summaryrefslogtreecommitdiff
path: root/asmcomp/i386/selection.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2003-02-25 15:50:13 +0000
committerXavier Leroy <xavier.leroy@inria.fr>2003-02-25 15:50:13 +0000
commit40efd97fe112e37ce064c0d13b8e04a0978fce9a (patch)
treeec867676139e4c0dc0a6e517209c05d7f92efa26 /asmcomp/i386/selection.ml
parentc517632cb20ca21542ab307beb6a92ef42fd35eb (diff)
downloadocaml-40efd97fe112e37ce064c0d13b8e04a0978fce9a.tar.gz
Amelioration des flottants x86: utiliser %st(0) comme registre quand c'est possible, evitant ainsi des couples fstp/fld; ajout option -ffast-math
git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@5404 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
Diffstat (limited to 'asmcomp/i386/selection.ml')
-rw-r--r--asmcomp/i386/selection.ml23
1 files changed, 21 insertions, 2 deletions
diff --git a/asmcomp/i386/selection.ml b/asmcomp/i386/selection.ml
index d6a5ef115a..f2f79ca5e7 100644
--- a/asmcomp/i386/selection.ml
+++ b/asmcomp/i386/selection.ml
@@ -73,14 +73,28 @@ let rec select_addr exp =
| arg ->
(Alinear arg, 0)
+(* C functions to be turned into Ifloatspecial instructions if -ffast-math *)
+
+let inline_float_ops =
+ ["atan"; "atan2"; "cos"; "log"; "log10"; "sin"; "sqrt"; "tan"]
+
(* Estimate number of float temporaries needed to evaluate expression
(Ershov's algorithm) *)
let rec float_needs = function
- Cop((Caddf | Csubf | Cmulf | Cdivf), [arg1; arg2]) ->
+ Cop((Cnegf | Cabsf), [arg]) ->
+ float_needs arg
+ | Cop((Caddf | Csubf | Cmulf | Cdivf), [arg1; arg2]) ->
let n1 = float_needs arg1 in
let n2 = float_needs arg2 in
if n1 = n2 then 1 + n1 else if n1 > n2 then n1 else n2
+ | Cop(Cextcall(fn, ty_res, alloc), args)
+ when !fast_math && List.mem fn inline_float_ops ->
+ begin match args with
+ [arg] -> float_needs arg
+ | [arg1; arg2] -> max (float_needs arg2 + 1) (float_needs arg1)
+ | _ -> assert false
+ end
| _ ->
1
@@ -119,7 +133,7 @@ let pseudoregs_for_operation op arg res =
the result is always left at the top of the floating-point stack *)
| Iconst_float _ | Inegf | Iabsf | Iaddf | Isubf | Imulf | Idivf
| Ifloatofint | Iload((Single | Double | Double_u), _)
- | Ispecific(Isubfrev | Idivfrev | Ifloatarithmem(_, _, _)) ->
+ | Ispecific(Isubfrev | Idivfrev | Ifloatarithmem(_, _, _) | Ifloatspecial _) ->
(arg, [| tos |], false) (* don't move it immediately *)
(* For storing a byte, the argument must be in eax...edx.
(But for a short, any reg will do!)
@@ -215,6 +229,11 @@ method select_operation op args =
| _ ->
super#select_operation op args
end
+ (* Recognize inlined floating point operations *)
+ | Cextcall(fn, ty_res, false)
+ when !fast_math && List.mem fn inline_float_ops ->
+ (Ispecific(Ifloatspecial fn), args)
+ (* Default *)
| _ -> super#select_operation op args
(* Recognize float arithmetic with mem *)