Skip to content

Commit 9587b12

Browse files
committed
arm64 float32 emit
1 parent c7ec27e commit 9587b12

File tree

1 file changed

+43
-45
lines changed

1 file changed

+43
-45
lines changed

backend/arm64/emit.mlp

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,11 @@ let is_immediate_float bits =
317317
let mant = Int64.logand bits 0xF_FFFF_FFFF_FFFFL in
318318
exp >= -3 && exp <= 4 && Int64.logand mant 0xF_0000_0000_0000L = mant
319319

320+
let is_immediate_float32 bits =
321+
let exp = (Int32.(to_int (shift_right_logical bits 23)) land 0x7F) - 63 in
322+
let mant = Int32.logand bits 0x7F_FFFFl in
323+
exp >= -3 && exp <= 4 && Int32.logand mant 0x78_0000l = mant
324+
320325
(* Adjust sp (up or down) by the given byte amount *)
321326

322327
let emit_stack_adjustment n =
@@ -704,9 +709,7 @@ module BR = Branch_relaxation.Make (struct
704709
| Lop (Move | Spill | Reload) -> 1
705710
| Lop (Const_int n) ->
706711
num_instructions_for_intconst n
707-
| Lop (Const_float32 _) ->
708-
(* CR mslater: (float32) arm64 *)
709-
Misc.fatal_error "float32 is not supported on this architecture"
712+
| Lop (Const_float32 _) -> 2
710713
| Lop (Const_float _) -> 2
711714
| Lop (Const_symbol _) -> 2
712715
| Lop (Const_vec128 _) ->
@@ -756,22 +759,19 @@ module BR = Branch_relaxation.Make (struct
756759
| Lop (Begin_region | End_region) -> 1
757760
| Lop (Intop (Icomp _)) -> 2
758761
| Lop (Floatop (Float64, Icompf _)) -> 2
759-
| Lop (Floatop (Float32, Icompf _)) ->
760-
(* CR mslater: (float32) arm64 *)
761-
Misc.fatal_error "float32 is not supported on this architecture"
762+
| Lop (Floatop (Float32, Icompf _)) -> 2
762763
| Lop (Intop_imm (Icomp _, _)) -> 2
763764
| Lop (Intop Imod) -> 2
764765
| Lop (Intop (Imulh _)) -> 1
765766
| Lop (Intop (Iclz _)) -> 1
766767
| Lop (Intop (Ictz _)) -> 2
767-
| Lop (Floatop (Float64, (Iabsf | Inegf)) | Specific Isqrtf) -> 1
768-
| Lop (Floatop (Float32, (Iabsf | Inegf))) ->
769-
(* CR mslater: (float32) arm64 *)
770-
Misc.fatal_error "float32 is not supported on this architecture"
771768
| Lop (Intop (Iadd|Isub|Imul|Idiv|Iand|Ior|Ixor|Ilsl|Ilsr|Iasr|Ipopcnt)) -> 1
772769
| Lop (Intop_imm
773770
((Iadd|Isub|Imul|Idiv|Imod|Imulh _|Iand|Ior|Ixor|Ilsl|Ilsr|Iasr
774771
| Iclz _ | Ictz _ |Ipopcnt),_)) -> 1
772+
| Lop (Floatop (Float64, (Iabsf | Inegf))) -> 1
773+
| Lop (Floatop (Float32, (Iabsf | Inegf))) -> 1
774+
| Lop (Specific Isqrtf) -> 1
775775
| Lop (Reinterpret_cast (Value_of_int | Int_of_value |
776776
Float_of_int64 | Int64_of_float)) -> 1
777777
| Lop (Reinterpret_cast (Float32_of_float | Float_of_float32 |
@@ -789,10 +789,9 @@ module BR = Branch_relaxation.Make (struct
789789
| Lop (Static_cast (V128_of_scalar _ | Scalar_of_v128 _)) ->
790790
(* CR mslater: (SIMD) arm64 *)
791791
Misc.fatal_error "SIMD is not supported on this architecture"
792-
| Lop (Floatop (Float64, (Iaddf | Isubf | Imulf | Idivf)) | Specific Inegmulf) -> 1
793-
| Lop (Floatop (Float32, (Iaddf | Isubf | Imulf | Idivf))) ->
794-
(* CR mslater: (float32) arm64 *)
795-
Misc.fatal_error "float32 is not supported on this architecture"
792+
| Lop (Floatop (Float64, (Iaddf | Isubf | Imulf | Idivf))) -> 1
793+
| Lop (Floatop (Float32, (Iaddf | Isubf | Imulf | Idivf))) -> 1
794+
| Lop (Specific Inegmulf) -> 1
796795
| Lop (Opaque) -> 0
797796
| Lop (Specific (Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf)) -> 1
798797
| Lop (Specific (Ishiftarith _)) -> 1
@@ -1031,7 +1030,7 @@ let emit_instr i =
10311030
move i.arg.(0) i.res.(0)
10321031
| Lop(Specific Imove32) ->
10331032
let src = i.arg.(0) and dst = i.res.(0) in
1034-
if src.loc <> dst.loc then begin
1033+
if not (Reg.same_loc src dst) then begin
10351034
match (src, dst) with
10361035
| {loc = Reg _}, {loc = Reg _} ->
10371036
` mov {emit_wreg dst}, {emit_wreg src}\n`
@@ -1046,9 +1045,17 @@ let emit_instr i =
10461045
end
10471046
| Lop(Const_int n) ->
10481047
emit_intconst i.res.(0) n
1049-
| Lop (Const_float32 _) ->
1050-
(* CR mslater: (float32) arm64 *)
1051-
Misc.fatal_error "float32 is not supported on this architecture"
1048+
| Lop (Const_float32 f) ->
1049+
DSL.check_reg Float32 i.res.(0);
1050+
if f = 0l then
1051+
` fmov {emit_reg i.res.(0)}, wzr\n`
1052+
else if is_immediate_float32 f then
1053+
` fmov {emit_reg i.res.(0)}, #{emit_printf "%.7f" (Int32.float_of_bits f)}\n`
1054+
else begin
1055+
(* float32 constants still take up 8 bytes; we load the lower half. *)
1056+
let lbl = float_literal (Int64.of_int32 f) in
1057+
emit_load_literal i.res.(0) lbl
1058+
end
10521059
| Lop(Const_float f) ->
10531060
if f = 0L then
10541061
` fmov {emit_reg i.res.(0)}, xzr\n`
@@ -1135,6 +1142,7 @@ let emit_instr i =
11351142
| Thirtytwo_signed ->
11361143
` ldrsw {emit_reg dst}, {emit_addressing addressing_mode base}\n`
11371144
| Single { reg = Float64 } ->
1145+
DSL.check_reg Float dst;
11381146
` ldr s7, {emit_addressing addressing_mode base}\n`;
11391147
` fcvt {emit_reg dst}, s7\n`
11401148
| Word_int | Word_val ->
@@ -1147,8 +1155,8 @@ let emit_instr i =
11471155
| Double ->
11481156
` ldr {emit_reg dst}, {emit_addressing addressing_mode base}\n`
11491157
| Single { reg = Float32 } ->
1150-
(* CR mslater: (float32) arm64 *)
1151-
fatal_error "arm64: got float32 memory chunk"
1158+
DSL.check_reg Float32 dst;
1159+
` ldr {emit_reg dst}, {emit_addressing addressing_mode base}\n`
11521160
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
11531161
(* CR mslater: (SIMD) arm64 *)
11541162
fatal_error "arm64: got 128 bit memory chunk"
@@ -1172,6 +1180,7 @@ let emit_instr i =
11721180
| Thirtytwo_unsigned | Thirtytwo_signed ->
11731181
` str {emit_wreg src}, {emit_addressing addr base}\n`
11741182
| Single { reg = Float64 } ->
1183+
DSL.check_reg Float src;
11751184
` fcvt s7, {emit_reg src}\n`;
11761185
` str s7, {emit_addressing addr base}\n`;
11771186
| Word_int | Word_val ->
@@ -1181,8 +1190,8 @@ let emit_instr i =
11811190
| Double ->
11821191
` str {emit_reg src}, {emit_addressing addr base}\n`
11831192
| Single { reg = Float32 } ->
1184-
(* CR mslater: (float32) arm64 *)
1185-
fatal_error "arm64: got float32 memory chunk"
1193+
DSL.check_reg Float32 src;
1194+
` str {emit_reg src}, {emit_addressing addr base}\n`
11861195
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
11871196
(* CR mslater: (SIMD) arm64 *)
11881197
fatal_error "arm64: got 128 bit memory chunk"
@@ -1214,9 +1223,10 @@ let emit_instr i =
12141223
let comp = name_for_float_comparison cmp in
12151224
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
12161225
` cset {emit_reg i.res.(0)}, {emit_string comp}\n`
1217-
| Lop(Floatop(Float32, Icompf _)) ->
1218-
(* CR mslater: (float32) arm64 *)
1219-
Misc.fatal_error "float32 is not supported on this architecture"
1226+
| Lop(Floatop(Float32, Icompf cmp)) ->
1227+
let comp = name_for_float_comparison cmp in
1228+
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
1229+
` cset {emit_reg i.res.(0)}, {emit_string comp}\n`
12201230
| Lop(Intop_imm(Icomp cmp, n)) ->
12211231
emit_cmpimm i.arg.(0) n;
12221232
` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n`
@@ -1241,25 +1251,19 @@ let emit_instr i =
12411251
| Lop(Intop_imm(op, n)) ->
12421252
let instr = name_for_int_operation op in
12431253
` {emit_string instr} {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, #{emit_int n}\n`
1244-
| Lop(Floatop (Float32, (Iabsf | Inegf))) ->
1245-
(* CR mslater: (float32) arm64 *)
1246-
Misc.fatal_error "float32 is not supported on this architecture"
1247-
| Lop(Floatop (Float32, (Iaddf | Isubf | Imulf | Idivf))) ->
1248-
(* CR mslater: (float32) arm64 *)
1249-
Misc.fatal_error "float32 is not supported on this architecture"
12501254
| Lop(Specific Isqrtf) ->
12511255
` fsqrt {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1252-
| Lop(Floatop ((Float64), Iabsf)) ->
1256+
| Lop(Floatop ((Float32 | Float64), Iabsf)) ->
12531257
` fabs {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1254-
| Lop(Floatop ((Float64), Inegf)) ->
1258+
| Lop(Floatop ((Float32 | Float64), Inegf)) ->
12551259
` fneg {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1256-
| Lop(Floatop ((Float64), Iaddf)) ->
1260+
| Lop(Floatop ((Float32 | Float64), Iaddf)) ->
12571261
` fadd {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
1258-
| Lop(Floatop ((Float64), Isubf)) ->
1262+
| Lop(Floatop ((Float32 | Float64), Isubf)) ->
12591263
` fsub {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
1260-
| Lop(Floatop ((Float64), Imulf)) ->
1264+
| Lop(Floatop ((Float32 | Float64), Imulf)) ->
12611265
` fmul {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
1262-
| Lop(Floatop ((Float64), Idivf)) ->
1266+
| Lop(Floatop ((Float32 | Float64), Idivf)) ->
12631267
` fdiv {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
12641268
| Lop(Specific Inegmulf) ->
12651269
` fnmul {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
@@ -1342,10 +1346,7 @@ let emit_instr i =
13421346
let comp = name_for_comparison cmp in
13431347
emit_cmpimm i.arg.(0) n;
13441348
` csel {emit_reg i.res.(0)}, {emit_reg i.arg.(1)}, {emit_reg i.arg.(2)}, {emit_string comp}\n`
1345-
| Ifloattest (Float32, _cmp) ->
1346-
(* CR mslater: (float32) arm64 *)
1347-
Misc.fatal_error "float32 is not supported on this architecture"
1348-
| Ifloattest (Float64, cmp) ->
1349+
| Ifloattest ((Float32 | Float64), cmp) ->
13491350
let comp = name_for_float_comparison cmp in
13501351
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
13511352
` csel {emit_reg i.res.(0)}, {emit_reg i.arg.(2)}, {emit_reg i.arg.(3)}, {emit_string comp}\n`
@@ -1378,10 +1379,7 @@ let emit_instr i =
13781379
emit_cmpimm i.arg.(0) n;
13791380
let comp = name_for_comparison cmp in
13801381
` b.{emit_string comp} {emit_label lbl}\n`
1381-
| Ifloattest (Float32, _cmp) ->
1382-
(* CR mslater: (float32) arm64 *)
1383-
Misc.fatal_error "float32 is not supported on this architecture"
1384-
| Ifloattest (Float64, cmp) ->
1382+
| Ifloattest ((Float32 | Float64), cmp) ->
13851383
let comp = name_for_float_comparison cmp in
13861384
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
13871385
` b.{emit_string comp} {emit_label lbl}\n`

0 commit comments

Comments
 (0)