Skip to content

Commit 71a81e6

Browse files
committed
vec128 emit
1 parent 48fb7fc commit 71a81e6

File tree

1 file changed

+45
-25
lines changed

1 file changed

+45
-25
lines changed

backend/arm64/emit.mlp

Lines changed: 45 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -383,29 +383,42 @@ let function_name = ref ""
383383
let tailrec_entry_point = ref None
384384
(* Pending floating-point literals *)
385385
let float_literals = ref ([] : (int64 * label) list)
386+
let vec128_literals = ref ([] : (Cmm.vec128_bits * label) list)
386387

387388
(* Label a floating-point literal *)
388-
let float_literal f =
389+
let add_literal p f =
389390
try
390-
List.assoc f !float_literals
391+
List.assoc f !p
391392
with Not_found ->
392393
let lbl = Cmm.new_label() in
393-
float_literals := (f, lbl) :: !float_literals;
394+
p := (f, lbl) :: !p;
394395
lbl
395396

397+
let float_literal f = add_literal float_literals f
398+
let vec128_literal f = add_literal vec128_literals f
399+
396400
(* Emit all pending literals *)
397-
let emit_literals() =
398-
if !float_literals <> [] then begin
401+
let emit_literals p align emit_literal =
402+
if !p <> [] then begin
399403
if macosx then
400-
` .section __TEXT,__literal8,8byte_literals\n`;
401-
` .align 3\n`;
402-
List.iter
403-
(fun (f, lbl) ->
404-
`{emit_label lbl}:`; emit_float64_directive ".quad" f)
405-
!float_literals;
406-
float_literals := []
404+
` .section __TEXT,__literal8,8byte_literals\n`;
405+
` .balign {emit_int align}\n`;
406+
List.iter emit_literal !p;
407+
p := []
407408
end
408409

410+
let emit_float_literal (f, lbl) =
411+
`{emit_label lbl}:`; emit_float64_directive ".quad" f
412+
413+
let emit_vec128_literal (({ high; low; } : Cmm.vec128_bits), lbl) =
414+
`{emit_label lbl}:\n`;
415+
emit_float64_directive ".quad" low;
416+
emit_float64_directive ".quad" high
417+
418+
let emit_literals () =
419+
emit_literals float_literals size_float emit_float_literal;
420+
emit_literals vec128_literals size_vec128 emit_vec128_literal
421+
409422
(* Emit code to load the address of a symbol *)
410423

411424
let emit_load_symbol_addr dst s =
@@ -711,10 +724,8 @@ module BR = Branch_relaxation.Make (struct
711724
num_instructions_for_intconst n
712725
| Lop (Const_float32 _) -> 2
713726
| Lop (Const_float _) -> 2
727+
| Lop (Const_vec128 _) -> 2
714728
| Lop (Const_symbol _) -> 2
715-
| Lop (Const_vec128 _) ->
716-
(* CR mslater: (SIMD) arm64 *)
717-
Misc.fatal_error "SIMD is not supported on this architecture"
718729
| Lop (Intop_atomic _) ->
719730
(* Never generated; builtins are not yet translated to atomics *)
720731
assert false
@@ -1065,9 +1076,16 @@ let emit_instr i =
10651076
let lbl = float_literal f in
10661077
emit_load_literal i.res.(0) lbl
10671078
end
1068-
| Lop(Const_vec128 _) ->
1069-
(* CR mslater: (SIMD) arm64 *)
1070-
Misc.fatal_error "SIMD is not supported on this architecture"
1079+
| Lop(Const_vec128 ({high; low} as l)) ->
1080+
DSL.check_reg Vec128 i.res.(0);
1081+
begin match (high, low) with
1082+
| 0x0000_0000_0000_0000L, 0x0000_0000_0000_0000L ->
1083+
let dst = DSL.emit_reg_v2d i.res.(0) in
1084+
DSL.ins I.MOVI [| dst; DSL.imm 0 |]
1085+
| _ ->
1086+
let lbl = vec128_literal l in
1087+
emit_load_literal i.res.(0) lbl
1088+
end
10711089
| Lop(Const_symbol s) ->
10721090
emit_load_symbol_addr i.res.(0) s.sym_name
10731091
| Lcall_op(Lcall_ind) ->
@@ -1158,8 +1176,9 @@ let emit_instr i =
11581176
DSL.check_reg Float32 dst;
11591177
` ldr {emit_reg dst}, {emit_addressing addressing_mode base}\n`
11601178
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
1161-
(* CR mslater: (SIMD) arm64 *)
1162-
fatal_error "arm64: got 128 bit memory chunk"
1179+
(* CR gyorsh: check alignment *)
1180+
DSL.check_reg Vec128 dst;
1181+
` ldr {emit_reg dst}, {emit_addressing addressing_mode base}\n`
11631182
end
11641183
| Lop(Store(size, addr, assignment)) ->
11651184
(* NB: assignments other than Word_int and Word_val do not follow the
@@ -1193,8 +1212,9 @@ let emit_instr i =
11931212
DSL.check_reg Float32 src;
11941213
` str {emit_reg src}, {emit_addressing addr base}\n`
11951214
| Onetwentyeight_aligned | Onetwentyeight_unaligned ->
1196-
(* CR mslater: (SIMD) arm64 *)
1197-
fatal_error "arm64: got 128 bit memory chunk"
1215+
(* CR gyorsh: check alignment *)
1216+
DSL.check_reg Vec128 src;
1217+
` str {emit_reg src}, {emit_addressing addr base}\n`
11981218
end
11991219
| Lop(Alloc { bytes = n; dbginfo; mode = Heap }) ->
12001220
assembly_code_for_allocation i ~n ~local:false ~far:false ~dbginfo
@@ -1549,9 +1569,9 @@ let emit_item (d : Cmm.data_item) =
15491569
| Cint n -> ` .quad {emit_nativeint n}\n`
15501570
| Csingle f -> emit_float32_directive ".long" (Int32.bits_of_float f)
15511571
| Cdouble f -> emit_float64_directive ".quad" (Int64.bits_of_float f)
1552-
| Cvec128 _ ->
1553-
(* CR mslater: (SIMD) arm64 *)
1554-
Misc.fatal_error "SIMD is not supported on this architecture"
1572+
| Cvec128 { high; low; } ->
1573+
emit_float64_directive ".quad" low;
1574+
emit_float64_directive ".quad" high;
15551575
| Csymbol_address s -> ` .quad {emit_symbol s.sym_name}\n`
15561576
| Csymbol_offset (s, o) -> ` .quad {emit_symbol s.sym_name}+{emit_int o}\n`
15571577
| Cstring s -> emit_string_directive " .ascii " s

0 commit comments

Comments
 (0)