aboutsummaryrefslogtreecommitdiffstats
path: root/riscV/ExpansionOracle.ml
diff options
context:
space:
mode:
authorLéo Gourdin <leo.gourdin@univ-grenoble-alpes.fr>2021-07-21 13:35:49 +0200
committerLéo Gourdin <leo.gourdin@univ-grenoble-alpes.fr>2021-07-21 13:35:49 +0200
commit0481f8e4c6aa3dd19219a8b196b36fcfaeb5408d (patch)
treeb97ac9dc5a0ea95808522ab32f0fddaa322ea1ce /riscV/ExpansionOracle.ml
parent9ce1b23f6361d8070490df1269a7bc53aa215efb (diff)
downloadcompcert-kvx-0481f8e4c6aa3dd19219a8b196b36fcfaeb5408d.tar.gz
compcert-kvx-0481f8e4c6aa3dd19219a8b196b36fcfaeb5408d.zip
new expansions
Diffstat (limited to 'riscV/ExpansionOracle.ml')
-rw-r--r--riscV/ExpansionOracle.ml198
1 files changed, 197 insertions, 1 deletions
diff --git a/riscV/ExpansionOracle.ml b/riscV/ExpansionOracle.ml
index c1cf5c9c..2a21b7a4 100644
--- a/riscV/ExpansionOracle.ml
+++ b/riscV/ExpansionOracle.ml
@@ -514,7 +514,6 @@ let expanse_cond_fp vn cnot fn_cond cmp f1 f2 dest =
let r', l = extract_arg insn in
addinst vn (OExoriw Int.one) [ r' ] dest :: l
-
(** Return olds args if the CSE numbering is empty *)
let get_arguments vn vals args =
@@ -607,6 +606,203 @@ let expanse_list li =
exp := extract_final vn !exp dest;
was_exp := true
| _ -> ());
+ (if !Clflags.option_fexpanse_others && not !was_exp then
+ match i with
+ | Bop (Ofloatconst f, nil, dest, iinfo) -> (
+ match make_immed64 (Floats.Float.to_bits f) with
+ | Imm64_single _ | Imm64_large _ -> ()
+ | Imm64_pair (hi, lo) ->
+ debug "Bop/Ofloatconst\n";
+ let r = r2pi () in
+ let l = load_hilo64 vn r hi lo in
+ let r', l' = extract_arg l in
+ exp := addinst vn Ofloat_of_bits [ r' ] dest :: l';
+ exp := extract_final vn !exp dest;
+ was_exp := true)
+ | Bop (Osingleconst f, nil, dest, iinfo) -> (
+ match make_immed32 (Floats.Float32.to_bits f) with
+ | Imm32_single imm -> ()
+ | Imm32_pair (hi, lo) ->
+ debug "Bop/Osingleconst\n";
+ let r = r2pi () in
+ let l = load_hilo32 vn r hi lo in
+ let r', l' = extract_arg l in
+ exp := addinst vn Osingle_of_bits [ r' ] dest :: l';
+ exp := extract_final vn !exp dest;
+ was_exp := true)
+ | Bop (Ointconst n, nil, dest, iinfo) ->
+ debug "Bop/Ointconst\n";
+ exp := loadimm32 vn dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Olongconst n, nil, dest, iinfo) ->
+ debug "Bop/Olongconst\n";
+ exp := loadimm64 vn dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oaddimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oaddimm\n";
+ exp := addimm32 vn a1 dest n None;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oaddlimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oaddlimm\n";
+ exp := addimm64 vn a1 dest n None;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oandimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oandimm\n";
+ exp := andimm32 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oandlimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oandlimm\n";
+ exp := andimm64 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oorimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oorimm\n";
+ exp := orimm32 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oorlimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oorlimm\n";
+ exp := orimm64 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oxorimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oxorimm\n";
+ exp := xorimm32 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oxorlimm n, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Oxorlimm\n";
+ exp := xorimm64 vn a1 dest n;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Ocast8signed, a1 :: nil, dest, iinfo) ->
+ debug "Bop/cast8signed\n";
+ let op = Oshlimm (Int.repr (Z.of_sint 24)) in
+ let r = r2pi () in
+ let i1 = addinst vn op [ a1 ] r in
+ let r', l = extract_arg [ i1 ] in
+ exp :=
+ addinst vn (Oshrimm (Int.repr (Z.of_sint 24))) [ r' ] dest :: l;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Ocast16signed, a1 :: nil, dest, iinfo) ->
+ debug "Bop/cast16signed\n";
+ let op = Oshlimm (Int.repr (Z.of_sint 16)) in
+ let r = r2pi () in
+ let i1 = addinst vn op [ a1 ] r in
+ let r', l = extract_arg [ i1 ] in
+ exp :=
+ addinst vn (Oshrimm (Int.repr (Z.of_sint 16))) [ r' ] dest :: l;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Ocast32unsigned, a1 :: nil, dest, iinfo) ->
+ debug "Bop/Ocast32unsigned\n";
+ let r1 = r2pi () in
+ let r2 = r2pi () in
+ let op1 = Ocast32signed in
+ let i1 = addinst vn op1 [ a1 ] r1 in
+ let r1', l1 = extract_arg [ i1 ] in
+
+ let op2 = Oshllimm (Int.repr (Z.of_sint 32)) in
+ let i2 = addinst vn op2 [ r1' ] r2 in
+ let r2', l2 = extract_arg (i2 :: l1) in
+
+ let op3 = Oshrluimm (Int.repr (Z.of_sint 32)) in
+ exp := addinst vn op3 [ r2' ] dest :: l2;
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oshrximm n, a1 :: nil, dest, iinfo) ->
+ if Int.eq n Int.zero then (
+ debug "Bop/Oshrximm1\n";
+ exp := [ addinst vn (OEmayundef (MUshrx n)) [ a1; a1 ] dest ])
+ else if Int.eq n Int.one then (
+ debug "Bop/Oshrximm2\n";
+ let r1 = r2pi () in
+ let r2 = r2pi () in
+ let op1 = Oshruimm (Int.repr (Z.of_sint 31)) in
+ let i1 = addinst vn op1 [ a1 ] r1 in
+ let r1', l1 = extract_arg [ i1 ] in
+
+ let op2 = Oadd in
+ let i2 = addinst vn op2 [ a1; r1' ] r2 in
+ let r2', l2 = extract_arg (i2 :: l1) in
+
+ let op3 = Oshrimm Int.one in
+ let i3 = addinst vn op3 [ r2' ] dest in
+ let r3, l3 = extract_arg (i3 :: l2) in
+ exp := addinst vn (OEmayundef (MUshrx n)) [ r3; r3 ] dest :: l3)
+ else (
+ debug "Bop/Oshrximm3\n";
+ let r1 = r2pi () in
+ let r2 = r2pi () in
+ let r3 = r2pi () in
+ let op1 = Oshrimm (Int.repr (Z.of_sint 31)) in
+ let i1 = addinst vn op1 [ a1 ] r1 in
+ let r1', l1 = extract_arg [ i1 ] in
+
+ let op2 = Oshruimm (Int.sub Int.iwordsize n) in
+ let i2 = addinst vn op2 [ r1' ] r2 in
+ let r2', l2 = extract_arg (i2 :: l1) in
+
+ let op3 = Oadd in
+ let i3 = addinst vn op3 [ a1; r2' ] r3 in
+ let r3', l3 = extract_arg (i3 :: l2) in
+
+ let op4 = Oshrimm n in
+ let i4 = addinst vn op4 [ r3' ] dest in
+ let r4, l4 = extract_arg (i4 :: l3) in
+ exp := addinst vn (OEmayundef (MUshrx n)) [ r4; r4 ] dest :: l4);
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | Bop (Oshrxlimm n, a1 :: nil, dest, iinfo) ->
+ if Int.eq n Int.zero then (
+ debug "Bop/Oshrxlimm1\n";
+ exp := [ addinst vn (OEmayundef (MUshrxl n)) [ a1; a1 ] dest ])
+ else if Int.eq n Int.one then (
+ debug "Bop/Oshrxlimm2\n";
+ let r1 = r2pi () in
+ let r2 = r2pi () in
+ let op1 = Oshrluimm (Int.repr (Z.of_sint 63)) in
+ let i1 = addinst vn op1 [ a1 ] r1 in
+ let r1', l1 = extract_arg [ i1 ] in
+
+ let op2 = Oaddl in
+ let i2 = addinst vn op2 [ a1; r1' ] r2 in
+ let r2', l2 = extract_arg (i2 :: l1) in
+
+ let op3 = Oshrlimm Int.one in
+ let i3 = addinst vn op3 [ r2' ] dest in
+ let r3, l3 = extract_arg (i3 :: l2) in
+ exp := addinst vn (OEmayundef (MUshrxl n)) [ r3; r3 ] dest :: l3)
+ else (
+ debug "Bop/Oshrxlimm3\n";
+ let r1 = r2pi () in
+ let r2 = r2pi () in
+ let r3 = r2pi () in
+ let op1 = Oshrlimm (Int.repr (Z.of_sint 63)) in
+ let i1 = addinst vn op1 [ a1 ] r1 in
+ let r1', l1 = extract_arg [ i1 ] in
+
+ let op2 = Oshrluimm (Int.sub Int64.iwordsize' n) in
+ let i2 = addinst vn op2 [ r1' ] r2 in
+ let r2', l2 = extract_arg (i2 :: l1) in
+
+ let op3 = Oaddl in
+ let i3 = addinst vn op3 [ a1; r2' ] r3 in
+ let r3', l3 = extract_arg (i3 :: l2) in
+
+ let op4 = Oshrlimm n in
+ let i4 = addinst vn op4 [ r3' ] dest in
+ let r4, l4 = extract_arg (i4 :: l3) in
+ exp := addinst vn (OEmayundef (MUshrxl n)) [ r4; r4 ] dest :: l4);
+ exp := extract_final vn !exp dest;
+ was_exp := true
+ | _ -> ());
if not !was_exp then (
(match i with
| Bop (op, args, dest, iinfo) ->