summaryrefslogtreecommitdiff
path: root/ocaml-binary-annot/asmcomp/i386/reload.ml
diff options
context:
space:
mode:
Diffstat (limited to 'ocaml-binary-annot/asmcomp/i386/reload.ml')
-rw-r--r--ocaml-binary-annot/asmcomp/i386/reload.ml83
1 files changed, 83 insertions, 0 deletions
diff --git a/ocaml-binary-annot/asmcomp/i386/reload.ml b/ocaml-binary-annot/asmcomp/i386/reload.ml
new file mode 100644
index 0000000000..539d45daea
--- /dev/null
+++ b/ocaml-binary-annot/asmcomp/i386/reload.ml
@@ -0,0 +1,83 @@
+(***********************************************************************)
+(* *)
+(* Objective Caml *)
+(* *)
+(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
+(* *)
+(* Copyright 1996 Institut National de Recherche en Informatique et *)
+(* en Automatique. All rights reserved. This file is distributed *)
+(* under the terms of the Q Public License version 1.0. *)
+(* *)
+(***********************************************************************)
+
+(* $Id$ *)
+
+open Cmm
+open Arch
+open Reg
+open Mach
+
+(* Reloading for the Intel x86 *)
+
+let stackp r =
+ match r.loc with
+ Stack _ -> true
+ | _ -> false
+
+class reload = object (self)
+
+inherit Reloadgen.reload_generic as super
+
+method! makereg r =
+ match r.typ with
+ Float -> r
+ | _ -> super#makereg r
+
+(* By overriding makereg, we make sure that pseudoregs of type float
+ will never be reloaded. Hence there is no need to make special cases for
+ floating-point operations. *)
+
+method! reload_operation op arg res =
+ match op with
+ Iintop(Iadd|Isub|Iand|Ior|Ixor|Icomp _|Icheckbound) ->
+ (* One of the two arguments can reside in the stack *)
+ if stackp arg.(0) && stackp arg.(1)
+ then ([|arg.(0); self#makereg arg.(1)|], res)
+ else (arg, res)
+ | Iintop(Imul) ->
+ (* First argument (and destination) must be in register,
+ second arg can reside in stack *)
+ if stackp arg.(0)
+ then let r = self#makereg arg.(0) in ([|r; arg.(1)|], [|r|])
+ else (arg, res)
+ | Iintop_imm(Iadd, _) when arg.(0).loc <> res.(0).loc ->
+ (* This add will be turned into a lea; args and results must be
+ in registers *)
+ super#reload_operation op arg res
+ | Iintop_imm(Imul, _) ->
+ (* First argument and destination must be in register *)
+ if stackp arg.(0)
+ then let r = self#makereg arg.(0) in ([|r|], [|r|])
+ else (arg, res)
+ | Iintop(Ilsl|Ilsr|Iasr) | Iintop_imm(_, _) | Ifloatofint | Iintoffloat |
+ Ispecific(Ipush) ->
+ (* The argument(s) can be either in register or on stack *)
+ (arg, res)
+ | _ -> (* Other operations: all args and results in registers *)
+ super#reload_operation op arg res
+
+method! reload_test tst arg =
+ match tst with
+ Iinttest cmp ->
+ (* One of the two arguments can reside on stack *)
+ if stackp arg.(0) && stackp arg.(1)
+ then [| self#makereg arg.(0); arg.(1) |]
+ else arg
+ | _ ->
+ (* The argument(s) can be either in register or on stack *)
+ arg
+
+end
+
+let fundecl f =
+ (new reload)#fundecl f