summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2004-01-31 01:11:32 +0000
committerJacques Garrigue <garrigue at math.nagoya-u.ac.jp>2004-01-31 01:11:32 +0000
commit9a023928563f677c250cb69e441747f7d2fa0647 (patch)
treeb69011b2b474f36373c76ac03d1d3ddecf84fcd7
parenta2af1981b184bf4b1f3d8f48e5d725ec4b2fc857 (diff)
downloadocaml-9a023928563f677c250cb69e441747f7d2fa0647.tar.gz
direct addressing in comparison
git-svn-id: http://caml.inria.fr/svn/ocaml/branches/newoolab@6098 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02
-rw-r--r--asmcomp/i386/arch.ml16
-rw-r--r--asmcomp/i386/emit.mlp6
-rw-r--r--asmcomp/i386/selection.ml26
-rw-r--r--asmcomp/linearize.ml2
-rw-r--r--asmcomp/mach.ml1
-rw-r--r--asmcomp/mach.mli1
-rw-r--r--asmcomp/printmach.ml2
7 files changed, 54 insertions, 0 deletions
diff --git a/asmcomp/i386/arch.ml b/asmcomp/i386/arch.ml
index bcbfb5f3f7..802d74ca28 100644
--- a/asmcomp/i386/arch.ml
+++ b/asmcomp/i386/arch.ml
@@ -48,6 +48,9 @@ type specific_operation =
(* bool: true=64 bits, false=32 *)
| Ifloatspecial of string
+and 'a specific_test =
+ Iinttests of 'a * bool * addressing_mode
+
and float_operation =
Ifloatadd | Ifloatsub | Ifloatsubrev | Ifloatmul | Ifloatdiv | Ifloatdivrev
@@ -78,6 +81,10 @@ let num_args_addressing = function
| Iscaled(scale, n) -> 1
| Iindexed2scaled(scale, n) -> 2
+let invert_specific_test negate = function
+ Iinttests (cmp, sgn, addr) ->
+ Iinttests (negate cmp, sgn, addr)
+
(* Printing operations and addressing modes *)
let print_addressing printreg addr ppf arg =
@@ -145,3 +152,12 @@ let print_specific_operation printreg op ppf arg =
printreg ppf arg.(i)
done
+let print_specific_test printreg printcmp tst ppf arg =
+ match tst with
+ Iinttests (cmp, sgn, addr) ->
+ fprintf ppf "%a %s%c %a"
+ printreg (arg.(0))
+ (printcmp cmp)
+ (if sgn then 'c' else 'u')
+ (print_addressing printreg addr)
+ (Array.sub arg 1 (Array.length arg - 1))
diff --git a/asmcomp/i386/emit.mlp b/asmcomp/i386/emit.mlp
index 17c0362f3e..0bdd992970 100644
--- a/asmcomp/i386/emit.mlp
+++ b/asmcomp/i386/emit.mlp
@@ -695,6 +695,12 @@ let emit_instr fallthrough i =
` cmpl {emit_reg i.arg.(1)}, {emit_reg i.arg.(0)}\n`;
let b = name_for_cond_branch cmp in
` j{emit_string b} {emit_label lbl}\n`
+ | Ispectest (Iinttests (cmp, sgn, addr)) ->
+ ` cmpl {emit_addressing addr i.arg 1}, {emit_reg i.arg.(0)}\n`;
+ let cmp = if sgn then Isigned cmp else Iunsigned cmp in
+ let b = name_for_cond_branch cmp in
+ ` j{emit_string b} {emit_label lbl}\n`
+
| Iinttest_imm((Isigned Ceq | Isigned Cne |
Iunsigned Ceq | Iunsigned Cne) as cmp, 0) ->
output_test_zero i.arg.(0);
diff --git a/asmcomp/i386/selection.ml b/asmcomp/i386/selection.ml
index 621cb8de38..03c2c45ea4 100644
--- a/asmcomp/i386/selection.ml
+++ b/asmcomp/i386/selection.ml
@@ -260,6 +260,32 @@ method select_floatarith regular_op reversed_op mem_op mem_rev_op args =
| _ ->
fatal_error "Proc_i386: select_floatarith"
+(* Recognize direct addressing in comparisons *)
+method select_condition = function
+ Cop ((Ccmpi cmp | Ccmpa cmp as op), [arg1; arg2]) as exp ->
+ (* Format.printf "%a@." Printcmm.expression exp; *)
+ let sgn = (op = Ccmpi cmp) in
+ let make_test cmp addr arg arg1 =
+ match arg1 with
+ Cconst_int _ | Cconst_pointer _ -> super#select_condition exp
+ | _ -> (Ispectest(Iinttests(cmp, sgn, addr)), Ctuple [arg1; arg])
+ in
+ let get_addressing = function
+ Cop (Cload Word, [arg]) -> self#select_addressing arg
+ | _ -> (Iindexed 0, Ctuple[])
+ in
+ begin match get_addressing arg1 with
+ (Iindexed 0, _) ->
+ begin match get_addressing arg2 with
+ (Iindexed 0, _) -> super#select_condition exp
+ | (addr, arg) -> make_test cmp addr arg arg1
+ end
+ | (addr, arg) ->
+ make_test (Cmm.swap_comparison cmp) addr arg arg2
+ end
+ | exp ->
+ super#select_condition exp
+
(* Deal with register constraints *)
method insert_op op rs rd =
diff --git a/asmcomp/linearize.ml b/asmcomp/linearize.ml
index 506f5a11c3..dbc7344280 100644
--- a/asmcomp/linearize.ml
+++ b/asmcomp/linearize.ml
@@ -69,6 +69,8 @@ let invert_test = function
| Ifloattest(cmp, neg) -> Ifloattest(cmp, not neg)
| Ieventest -> Ioddtest
| Ioddtest -> Ieventest
+ | Ispectest tst ->
+ Ispectest (Arch.invert_specific_test Cmm.negate_comparison tst)
(* The "end" instruction *)
diff --git a/asmcomp/mach.ml b/asmcomp/mach.ml
index 6417b5c40e..3458bcde58 100644
--- a/asmcomp/mach.ml
+++ b/asmcomp/mach.ml
@@ -32,6 +32,7 @@ type test =
| Ifloattest of Cmm.comparison * bool
| Ioddtest
| Ieventest
+ | Ispectest of Cmm.comparison Arch.specific_test
type operation =
Imove
diff --git a/asmcomp/mach.mli b/asmcomp/mach.mli
index ec10ffb814..4804096cfe 100644
--- a/asmcomp/mach.mli
+++ b/asmcomp/mach.mli
@@ -32,6 +32,7 @@ type test =
| Ifloattest of Cmm.comparison * bool
| Ioddtest
| Ieventest
+ | Ispectest of Cmm.comparison Arch.specific_test
type operation =
Imove
diff --git a/asmcomp/printmach.ml b/asmcomp/printmach.ml
index 17cf675b98..ba23b51a50 100644
--- a/asmcomp/printmach.ml
+++ b/asmcomp/printmach.ml
@@ -95,6 +95,8 @@ let test tst ppf arg =
reg arg.(0) (floatcomp cmp) reg arg.(1)
| Ieventest -> fprintf ppf "%a & 1 == 0" reg arg.(0)
| Ioddtest -> fprintf ppf "%a & 1 == 1" reg arg.(0)
+ | Ispectest tst ->
+ Arch.print_specific_test reg Printcmm.comparison tst ppf arg
let print_live = ref false