diff options
author | Jacques Garrigue <garrigue at math.nagoya-u.ac.jp> | 2004-01-31 01:11:32 +0000 |
---|---|---|
committer | Jacques Garrigue <garrigue at math.nagoya-u.ac.jp> | 2004-01-31 01:11:32 +0000 |
commit | 9a023928563f677c250cb69e441747f7d2fa0647 (patch) | |
tree | b69011b2b474f36373c76ac03d1d3ddecf84fcd7 | |
parent | a2af1981b184bf4b1f3d8f48e5d725ec4b2fc857 (diff) | |
download | ocaml-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.ml | 16 | ||||
-rw-r--r-- | asmcomp/i386/emit.mlp | 6 | ||||
-rw-r--r-- | asmcomp/i386/selection.ml | 26 | ||||
-rw-r--r-- | asmcomp/linearize.ml | 2 | ||||
-rw-r--r-- | asmcomp/mach.ml | 1 | ||||
-rw-r--r-- | asmcomp/mach.mli | 1 | ||||
-rw-r--r-- | asmcomp/printmach.ml | 2 |
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 |