@@ -317,6 +317,11 @@ let is_immediate_float bits =
317
317
let mant = Int64.logand bits 0xF_FFFF_FFFF_FFFFL in
318
318
exp >= -3 && exp <= 4 && Int64.logand mant 0xF_0000_0000_0000L = mant
319
319
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
+
320
325
(* Adjust sp (up or down) by the given byte amount *)
321
326
322
327
let emit_stack_adjustment n =
@@ -704,9 +709,7 @@ module BR = Branch_relaxation.Make (struct
704
709
| Lop (Move | Spill | Reload) -> 1
705
710
| Lop (Const_int n) ->
706
711
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
710
713
| Lop (Const_float _) -> 2
711
714
| Lop (Const_symbol _) -> 2
712
715
| Lop (Const_vec128 _) ->
@@ -756,22 +759,19 @@ module BR = Branch_relaxation.Make (struct
756
759
| Lop (Begin_region | End_region) -> 1
757
760
| Lop (Intop (Icomp _)) -> 2
758
761
| 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
762
763
| Lop (Intop_imm (Icomp _, _)) -> 2
763
764
| Lop (Intop Imod) -> 2
764
765
| Lop (Intop (Imulh _)) -> 1
765
766
| Lop (Intop (Iclz _)) -> 1
766
767
| 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"
771
768
| Lop (Intop (Iadd|Isub|Imul|Idiv|Iand|Ior|Ixor|Ilsl|Ilsr|Iasr|Ipopcnt)) -> 1
772
769
| Lop (Intop_imm
773
770
((Iadd|Isub|Imul|Idiv|Imod|Imulh _|Iand|Ior|Ixor|Ilsl|Ilsr|Iasr
774
771
| Iclz _ | Ictz _ |Ipopcnt),_)) -> 1
772
+ | Lop (Floatop (Float64, (Iabsf | Inegf))) -> 1
773
+ | Lop (Floatop (Float32, (Iabsf | Inegf))) -> 1
774
+ | Lop (Specific Isqrtf) -> 1
775
775
| Lop (Reinterpret_cast (Value_of_int | Int_of_value |
776
776
Float_of_int64 | Int64_of_float)) -> 1
777
777
| Lop (Reinterpret_cast (Float32_of_float | Float_of_float32 |
@@ -789,10 +789,9 @@ module BR = Branch_relaxation.Make (struct
789
789
| Lop (Static_cast (V128_of_scalar _ | Scalar_of_v128 _)) ->
790
790
(* CR mslater: (SIMD) arm64 *)
791
791
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
796
795
| Lop (Opaque) -> 0
797
796
| Lop (Specific (Imuladdf | Inegmuladdf | Imulsubf | Inegmulsubf)) -> 1
798
797
| Lop (Specific (Ishiftarith _)) -> 1
@@ -1031,7 +1030,7 @@ let emit_instr i =
1031
1030
move i.arg.(0) i.res.(0)
1032
1031
| Lop(Specific Imove32) ->
1033
1032
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
1035
1034
match (src, dst) with
1036
1035
| {loc = Reg _}, {loc = Reg _} ->
1037
1036
` mov {emit_wreg dst}, {emit_wreg src}\n`
@@ -1046,9 +1045,17 @@ let emit_instr i =
1046
1045
end
1047
1046
| Lop(Const_int n) ->
1048
1047
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
1052
1059
| Lop(Const_float f) ->
1053
1060
if f = 0L then
1054
1061
` fmov {emit_reg i.res.(0)}, xzr\n`
@@ -1135,6 +1142,7 @@ let emit_instr i =
1135
1142
| Thirtytwo_signed ->
1136
1143
` ldrsw {emit_reg dst}, {emit_addressing addressing_mode base}\n`
1137
1144
| Single { reg = Float64 } ->
1145
+ DSL.check_reg Float dst;
1138
1146
` ldr s7, {emit_addressing addressing_mode base}\n`;
1139
1147
` fcvt {emit_reg dst}, s7\n`
1140
1148
| Word_int | Word_val ->
@@ -1147,8 +1155,8 @@ let emit_instr i =
1147
1155
| Double ->
1148
1156
` ldr {emit_reg dst}, {emit_addressing addressing_mode base}\n`
1149
1157
| 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`
1152
1160
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
1153
1161
(* CR mslater: (SIMD) arm64 *)
1154
1162
fatal_error "arm64: got 128 bit memory chunk"
@@ -1172,6 +1180,7 @@ let emit_instr i =
1172
1180
| Thirtytwo_unsigned | Thirtytwo_signed ->
1173
1181
` str {emit_wreg src}, {emit_addressing addr base}\n`
1174
1182
| Single { reg = Float64 } ->
1183
+ DSL.check_reg Float src;
1175
1184
` fcvt s7, {emit_reg src}\n`;
1176
1185
` str s7, {emit_addressing addr base}\n`;
1177
1186
| Word_int | Word_val ->
@@ -1181,8 +1190,8 @@ let emit_instr i =
1181
1190
| Double ->
1182
1191
` str {emit_reg src}, {emit_addressing addr base}\n`
1183
1192
| 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`
1186
1195
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
1187
1196
(* CR mslater: (SIMD) arm64 *)
1188
1197
fatal_error "arm64: got 128 bit memory chunk"
@@ -1214,9 +1223,10 @@ let emit_instr i =
1214
1223
let comp = name_for_float_comparison cmp in
1215
1224
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
1216
1225
` 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`
1220
1230
| Lop(Intop_imm(Icomp cmp, n)) ->
1221
1231
emit_cmpimm i.arg.(0) n;
1222
1232
` cset {emit_reg i.res.(0)}, {emit_string (name_for_comparison cmp)}\n`
@@ -1241,25 +1251,19 @@ let emit_instr i =
1241
1251
| Lop(Intop_imm(op, n)) ->
1242
1252
let instr = name_for_int_operation op in
1243
1253
` {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"
1250
1254
| Lop(Specific Isqrtf) ->
1251
1255
` fsqrt {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1252
- | Lop(Floatop ((Float64), Iabsf)) ->
1256
+ | Lop(Floatop ((Float32 | Float64), Iabsf)) ->
1253
1257
` fabs {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1254
- | Lop(Floatop ((Float64), Inegf)) ->
1258
+ | Lop(Floatop ((Float32 | Float64), Inegf)) ->
1255
1259
` fneg {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}\n`
1256
- | Lop(Floatop ((Float64), Iaddf)) ->
1260
+ | Lop(Floatop ((Float32 | Float64), Iaddf)) ->
1257
1261
` 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)) ->
1259
1263
` 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)) ->
1261
1265
` 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)) ->
1263
1267
` fdiv {emit_reg i.res.(0)}, {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`
1264
1268
| Lop(Specific Inegmulf) ->
1265
1269
` 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 =
1342
1346
let comp = name_for_comparison cmp in
1343
1347
emit_cmpimm i.arg.(0) n;
1344
1348
` 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) ->
1349
1350
let comp = name_for_float_comparison cmp in
1350
1351
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
1351
1352
` 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 =
1378
1379
emit_cmpimm i.arg.(0) n;
1379
1380
let comp = name_for_comparison cmp in
1380
1381
` 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) ->
1385
1383
let comp = name_for_float_comparison cmp in
1386
1384
` fcmp {emit_reg i.arg.(0)}, {emit_reg i.arg.(1)}\n`;
1387
1385
` b.{emit_string comp} {emit_label lbl}\n`
0 commit comments