diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2003-02-25 15:50:13 +0000 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2003-02-25 15:50:13 +0000 |
commit | 40efd97fe112e37ce064c0d13b8e04a0978fce9a (patch) | |
tree | ec867676139e4c0dc0a6e517209c05d7f92efa26 /asmcomp/i386/selection.ml | |
parent | c517632cb20ca21542ab307beb6a92ef42fd35eb (diff) | |
download | ocaml-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.ml | 23 |
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 *) |