Skip to content

Commit d9e5f33

Browse files
committed
Aarch64: add tests for better coverage
Signed-off-by: Paul Guyot <[email protected]>
1 parent 1237d66 commit d9e5f33

File tree

1 file changed

+333
-0
lines changed

1 file changed

+333
-0
lines changed

tests/libs/jit/jit_aarch64_tests.erl

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,51 @@ call_primitive_2_args_test() ->
8888
>>,
8989
?assertEqual(dump_to_bin(Dump), Stream).
9090

91+
call_primitive_5_args_test() ->
92+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
93+
State1 = ?BACKEND:call_primitive_last(State0, ?PRIM_ALLOCATE, [ctx, jit_state, 16, 32, 2]),
94+
Stream = ?BACKEND:stream(State1),
95+
Dump =
96+
<<
97+
" 0: f9401447 ldr x7, [x2, #40]\n"
98+
" 4: d2800202 mov x2, #0x10 // #16\n"
99+
" 8: d2800403 mov x3, #0x20 // #32\n"
100+
" c: d2800044 mov x4, #0x2 // #2\n"
101+
" 10: d61f00e0 br x7"
102+
>>,
103+
?assertEqual(dump_to_bin(Dump), Stream).
104+
105+
call_primitive_6_args_test() ->
106+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
107+
% Get bin_ptr from x_reg 0 (similar to get_list_test pattern)
108+
{State1, RegA} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
109+
State2 = ?BACKEND:and_(State1, RegA, ?TERM_PRIMARY_CLEAR_MASK),
110+
% Get another register for the last parameter to test {free, Reg} handling
111+
{State3, OtherReg} = ?BACKEND:move_to_native_register(State2, {x_reg, 1}),
112+
% Call PRIM_BITSTRING_EXTRACT_INTEGER with 6 arguments
113+
{State4, _ResultReg} = ?BACKEND:call_primitive(State3, ?PRIM_BITSTRING_EXTRACT_INTEGER, [
114+
ctx, jit_state, {free, RegA}, 64, 8, {free, OtherReg}
115+
]),
116+
Stream = ?BACKEND:stream(State4),
117+
Dump =
118+
<<
119+
" 0: f9401807 ldr x7, [x0, #48]\n"
120+
" 4: 927ef4e7 and x7, x7, #0xfffffffffffffffc\n"
121+
" 8: f9401c08 ldr x8, [x0, #56]\n"
122+
" c: f940b850 ldr x16, [x2, #368]\n"
123+
" 10: a9bf03fe stp x30, x0, [sp, #-16]!\n"
124+
" 14: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
125+
" 18: aa0703e2 mov x2, x7\n"
126+
" 1c: d2800803 mov x3, #0x40 // #64\n"
127+
" 20: d2800104 mov x4, #0x8 // #8\n"
128+
" 24: aa0803e5 mov x5, x8\n"
129+
" 28: d63f0200 blr x16\n"
130+
" 2c: aa0003e7 mov x7, x0\n"
131+
" 30: a8c10be1 ldp x1, x2, [sp], #16\n"
132+
" 34: a8c103fe ldp x30, x0, [sp], #16"
133+
>>,
134+
?assertEqual(dump_to_bin(Dump), Stream).
135+
91136
call_primitive_extended_regs_test() ->
92137
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
93138
{State1, RegA} = ?BACKEND:call_primitive(State0, ?PRIM_EXTENDED_REGISTER_PTR, [ctx, 19]),
@@ -146,6 +191,44 @@ call_primitive_extended_regs_test() ->
146191
>>,
147192
?assertEqual(dump_to_bin(Dump), Stream).
148193

194+
call_primitive_few_free_regs_test() ->
195+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
196+
{State1, Reg1} = ?BACKEND:move_to_native_register(State0, 1),
197+
{State2, Reg2} = ?BACKEND:move_to_native_register(State1, 2),
198+
{State3, Reg3} = ?BACKEND:move_to_native_register(State2, 3),
199+
{State4, Reg4} = ?BACKEND:move_to_native_register(State3, 4),
200+
{State5, Reg5} = ?BACKEND:move_to_native_register(State4, 5),
201+
{State6, ResultReg} = ?BACKEND:call_primitive(State5, ?PRIM_BITSTRING_INSERT_INTEGER, [
202+
Reg2, Reg1, {free, Reg4}, Reg3, {free, Reg5}
203+
]),
204+
State7 = ?BACKEND:free_native_registers(State6, [ResultReg, Reg2, Reg1, Reg3]),
205+
?BACKEND:assert_all_native_free(State7),
206+
Stream = ?BACKEND:stream(State7),
207+
Dump = <<
208+
" 0: d2800027 mov x7, #0x1 // #1\n"
209+
" 4: d2800048 mov x8, #0x2 // #2\n"
210+
" 8: d2800069 mov x9, #0x3 // #3\n"
211+
" c: d280008a mov x10, #0x4 // #4\n"
212+
" 10: d28000ab mov x11, #0x5 // #5\n"
213+
" 14: f940e450 ldr x16, [x2, #456]\n"
214+
" 18: a9bf03fe stp x30, x0, [sp, #-16]!\n"
215+
" 1c: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
216+
" 20: a9bf23e9 stp x9, x8, [sp, #-16]!\n"
217+
" 24: f81f0fe7 str x7, [sp, #-16]!\n"
218+
" 28: aa0803e0 mov x0, x8\n"
219+
" 2c: aa0703e1 mov x1, x7\n"
220+
" 30: aa0a03e2 mov x2, x10\n"
221+
" 34: aa0903e3 mov x3, x9\n"
222+
" 38: aa0b03e4 mov x4, x11\n"
223+
" 3c: d63f0200 blr x16\n"
224+
" 40: aa0003ea mov x10, x0\n"
225+
" 44: f84107e7 ldr x7, [sp], #16\n"
226+
" 48: a8c123e9 ldp x9, x8, [sp], #16\n"
227+
" 4c: a8c10be1 ldp x1, x2, [sp], #16\n"
228+
" 50: a8c103fe ldp x30, x0, [sp], #16"
229+
>>,
230+
?assertEqual(dump_to_bin(Dump), Stream).
231+
149232
call_ext_only_test() ->
150233
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
151234
State1 = ?BACKEND:decrement_reductions_and_maybe_schedule_next(State0),
@@ -168,6 +251,23 @@ call_ext_only_test() ->
168251
>>,
169252
?assertEqual(dump_to_bin(Dump), Stream).
170253

254+
call_primitive_last_5_args_test() ->
255+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
256+
{State1, RegA} = ?BACKEND:move_to_native_register(State0, {x_reg, 0}),
257+
State2 = ?BACKEND:call_primitive_last(State1, ?PRIM_RAISE_ERROR_TUPLE, [
258+
ctx, jit_state, offset, ?CASE_CLAUSE_ATOM, {free, RegA}
259+
]),
260+
Stream = ?BACKEND:stream(State2),
261+
Dump = <<
262+
" 0: f9401807 ldr x7, [x0, #48]\n"
263+
" 4: f9404c48 ldr x8, [x2, #152]\n"
264+
" 8: d2800102 mov x2, #0x8 // #8\n"
265+
" c: d2805963 mov x3, #0x2cb // #715\n"
266+
" 10: aa0703e4 mov x4, x7\n"
267+
" 14: d61f0100 br x8"
268+
>>,
269+
?assertEqual(dump_to_bin(Dump), Stream).
270+
171271
call_ext_last_test() ->
172272
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
173273
State1 = ?BACKEND:decrement_reductions_and_maybe_schedule_next(State0),
@@ -1038,6 +1138,179 @@ is_boolean_test() ->
10381138
>>,
10391139
?assertEqual(dump_to_bin(Dump), Stream).
10401140

1141+
%% Test OP_WAIT_TIMEOUT pattern
1142+
wait_timeout_test() ->
1143+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1144+
1145+
Label = 42,
1146+
{State1, OffsetRef0} = ?BACKEND:set_continuation_to_offset(State0),
1147+
{State2, TimeoutReg} = ?BACKEND:move_to_native_register(State1, 5000),
1148+
State3 = ?BACKEND:call_primitive_last(State2, ?PRIM_WAIT_TIMEOUT, [
1149+
ctx, jit_state, {free, TimeoutReg}, Label
1150+
]),
1151+
State4 = ?BACKEND:add_label(State3, OffsetRef0),
1152+
State5 = ?BACKEND:continuation_entry_point(State4),
1153+
{State6, ResultReg0} = ?BACKEND:call_primitive(State5, ?PRIM_PROCESS_SIGNAL_MESSAGES, [
1154+
ctx, jit_state
1155+
]),
1156+
State7 = ?BACKEND:return_if_not_equal_to_ctx(State6, {free, ResultReg0}),
1157+
% ?WAITING_TIMEOUT_EXPIRED
1158+
{State8, ResultReg1} = ?BACKEND:call_primitive(State7, ?PRIM_CONTEXT_GET_FLAGS, [ctx, 2]),
1159+
State9 = ?BACKEND:if_block(State8, {{free, ResultReg1}, '==', 0}, fun(BlockSt) ->
1160+
?BACKEND:call_primitive_last(BlockSt, ?PRIM_WAIT_TIMEOUT_TRAP_HANDLER, [
1161+
ctx, jit_state, Label
1162+
])
1163+
end),
1164+
State10 = ?BACKEND:update_branches(State9),
1165+
1166+
Stream = ?BACKEND:stream(State10),
1167+
Dump = <<
1168+
" 0: 100000e7 adr x7, 0x1c\n"
1169+
" 4: f9000427 str x7, [x1, #8]\n"
1170+
" 8: d2827107 mov x7, #0x1388 // #5000\n"
1171+
" c: f9407848 ldr x8, [x2, #240]\n"
1172+
" 10: aa0703e2 mov x2, x7\n"
1173+
" 14: d2800543 mov x3, #0x2a // #42\n"
1174+
" 18: d61f0100 br x8\n"
1175+
" 1c: f9405450 ldr x16, [x2, #168]\n"
1176+
" 20: a9bf03fe stp x30, x0, [sp, #-16]!\n"
1177+
" 24: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
1178+
" 28: d63f0200 blr x16\n"
1179+
" 2c: aa0003e7 mov x7, x0\n"
1180+
" 30: a8c10be1 ldp x1, x2, [sp], #16\n"
1181+
" 34: a8c103fe ldp x30, x0, [sp], #16\n"
1182+
" 38: eb0000ff cmp x7, x0\n"
1183+
" 3c: 54000060 b.eq 0x48 // b.none\n"
1184+
" 40: aa0703e0 mov x0, x7\n"
1185+
" 44: d65f03c0 ret\n"
1186+
" 48: f9408450 ldr x16, [x2, #264]\n"
1187+
" 4c: a9bf03fe stp x30, x0, [sp, #-16]!\n"
1188+
" 50: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
1189+
" 54: d2800041 mov x1, #0x2 // #2\n"
1190+
" 58: d63f0200 blr x16\n"
1191+
" 5c: aa0003e7 mov x7, x0\n"
1192+
" 60: a8c10be1 ldp x1, x2, [sp], #16\n"
1193+
" 64: a8c103fe ldp x30, x0, [sp], #16\n"
1194+
" 68: b5000087 cbnz x7, 0x78\n"
1195+
" 6c: f9407c47 ldr x7, [x2, #248]\n"
1196+
" 70: d2800542 mov x2, #0x2a // #42\n"
1197+
" 74: d61f00e0 br x7"
1198+
>>,
1199+
?assertEqual(dump_to_bin(Dump), Stream).
1200+
1201+
%% Test OP_WAIT pattern that uses set_continuation_to_label
1202+
wait_test() ->
1203+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1204+
1205+
State1 = ?BACKEND:jump_table(State0, 5),
1206+
State2 = ?BACKEND:add_label(State1, 1),
1207+
Label = 2,
1208+
State3 = ?BACKEND:set_continuation_to_label(State2, Label),
1209+
State4 = ?BACKEND:call_primitive_last(State3, ?PRIM_SCHEDULE_WAIT_CP, [ctx, jit_state]),
1210+
1211+
Stream = ?BACKEND:stream(State4),
1212+
Dump = <<
1213+
" 0: 14000000 b 0x0\n"
1214+
" 4: 14000000 b 0x4\n"
1215+
" 8: 14000000 b 0x8\n"
1216+
" c: 14000000 b 0xc\n"
1217+
" 10: 14000000 b 0x10\n"
1218+
" 14: 14000000 b 0x14\n"
1219+
" 18: 10000007 adr x7, 0x18\n"
1220+
" 1c: f9000427 str x7, [x1, #8]\n"
1221+
" 20: f9407447 ldr x7, [x2, #232]\n"
1222+
" 24: d61f00e0 br x7"
1223+
>>,
1224+
?assertEqual(dump_to_bin(Dump), Stream).
1225+
1226+
return_labels_and_lines_test() ->
1227+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1228+
1229+
% Test return_labels_and_lines with some sample labels and lines
1230+
State1 = ?BACKEND:add_label(State0, 2, 32),
1231+
State2 = ?BACKEND:add_label(State1, 1, 16),
1232+
1233+
% {Line, Offset} pairs
1234+
SortedLines = [{10, 16}, {20, 32}],
1235+
1236+
State3 = ?BACKEND:return_labels_and_lines(State2, SortedLines),
1237+
Stream = ?BACKEND:stream(State3),
1238+
1239+
% Should have generated adr + ret + labels table + lines table
1240+
% adr = 4 bytes, ret = 4 bytes, labels table = 6*2 = 12 bytes, lines table = 6*2 = 12 bytes
1241+
% Total minimum: 36 bytes
1242+
?assert(byte_size(Stream) >= 36),
1243+
1244+
% Expected: adr x0, #8 + ret + labels table + lines table
1245+
% The data tables start at offset 0x8, so we load PC + 8 into x0
1246+
Dump = <<
1247+
" 0: 10000040 adr x0, 0x8\n"
1248+
" 4: d65f03c0 ret\n"
1249+
" 8: 01000200 .word 0x01000200\n"
1250+
" c: 10000000 adr x0, 0xc\n"
1251+
" 10: 00000200 .word 0x00000200\n"
1252+
" 14: 02002000 .word 0x02002000\n"
1253+
" 18: 00000a00 .word 0x00000a00\n"
1254+
" 1c: 14001000 .word 0x14001000\n"
1255+
" 20: 20000000 .word 0x20000000"
1256+
>>,
1257+
?assertEqual(dump_to_bin(Dump), Stream).
1258+
1259+
%% Test call_primitive with {free, {x_reg, X}}
1260+
gc_bif2_test() ->
1261+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1262+
{State1, FuncPtr} = ?BACKEND:call_primitive(State0, ?PRIM_GET_IMPORTED_BIF, [jit_state, 42]),
1263+
{State2, _ResultReg} = ?BACKEND:call_func_ptr(State1, {free, FuncPtr}, [
1264+
ctx, 0, 3, {y_reg, 0}, {free, {x_reg, 0}}
1265+
]),
1266+
1267+
Stream = ?BACKEND:stream(State2),
1268+
Dump = <<
1269+
" 0: f9402050 ldr x16, [x2, #64]\n"
1270+
" 4: a9bf03fe stp x30, x0, [sp, #-16]!\n"
1271+
" 8: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
1272+
" c: aa0103e0 mov x0, x1\n"
1273+
" 10: d2800541 mov x1, #0x2a // #42\n"
1274+
" 14: d63f0200 blr x16\n"
1275+
" 18: aa0003e7 mov x7, x0\n"
1276+
" 1c: a8c10be1 ldp x1, x2, [sp], #16\n"
1277+
" 20: a8c103fe ldp x30, x0, [sp], #16\n"
1278+
" 24: a9bf03fe stp x30, x0, [sp, #-16]!\n"
1279+
" 28: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
1280+
" 2c: d2800001 mov x1, #0x0 // #0\n"
1281+
" 30: d2800062 mov x2, #0x3 // #3\n"
1282+
" 34: f9401403 ldr x3, [x0, #40]\n"
1283+
" 38: f9400063 ldr x3, [x3]\n"
1284+
" 3c: f9401804 ldr x4, [x0, #48]\n"
1285+
" 40: d63f00e0 blr x7\n"
1286+
" 44: aa0003e7 mov x7, x0\n"
1287+
" 48: a8c10be1 ldp x1, x2, [sp], #16\n"
1288+
" 4c: a8c103fe ldp x30, x0, [sp], #16"
1289+
>>,
1290+
?assertEqual(dump_to_bin(Dump), Stream).
1291+
1292+
%% Test case where parameter value is in r1
1293+
memory_ensure_free_with_roots_test() ->
1294+
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
1295+
{State1, _FuncPtr} = ?BACKEND:call_primitive(State0, ?PRIM_MEMORY_ENSURE_FREE_WITH_ROOTS, [
1296+
ctx, jit_state, {free, r1}, 4, 1
1297+
]),
1298+
1299+
Stream = ?BACKEND:stream(State1),
1300+
Dump = <<
1301+
" 0: f940b050 ldr x16, [x2, #352]\n"
1302+
" 4: a9bf03fe stp x30, x0, [sp, #-16]!\n"
1303+
" 8: a9bf0be1 stp x1, x2, [sp, #-16]!\n"
1304+
" c: aa0103e2 mov x2, x1\n"
1305+
" 10: d2800083 mov x3, #0x4 // #4\n"
1306+
" 14: d2800024 mov x4, #0x1 // #1\n"
1307+
" 18: d63f0200 blr x16\n"
1308+
" 1c: aa0003e7 mov x7, x0\n"
1309+
" 20: a8c10be1 ldp x1, x2, [sp], #16\n"
1310+
" 24: a8c103fe ldp x30, x0, [sp], #16"
1311+
>>,
1312+
?assertEqual(dump_to_bin(Dump), Stream).
1313+
10411314
call_ext_test() ->
10421315
State0 = ?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0)),
10431316
State1 = ?BACKEND:decrement_reductions_and_maybe_schedule_next(State0),
@@ -1662,6 +1935,66 @@ move_to_native_register_test_() ->
16621935
]
16631936
end}.
16641937

1938+
add_test0(State0, Reg, Imm, Dump) ->
1939+
State1 = ?BACKEND:add(State0, Reg, Imm),
1940+
Stream = ?BACKEND:stream(State1),
1941+
?assertEqual(dump_to_bin(Dump), Stream).
1942+
1943+
add_test_() ->
1944+
{setup,
1945+
fun() ->
1946+
?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0))
1947+
end,
1948+
fun(State0) ->
1949+
[
1950+
?_test(begin
1951+
add_test0(State0, r2, 2, <<
1952+
" 0: 91000842 add x2, x2, #0x2"
1953+
>>)
1954+
end),
1955+
?_test(begin
1956+
add_test0(State0, r2, 256, <<
1957+
" 0: 91040042 add x2, x2, #0x100"
1958+
>>)
1959+
end),
1960+
?_test(begin
1961+
add_test0(State0, r2, r3, <<
1962+
" 0: 8b030042 add x2, x2, x3"
1963+
>>)
1964+
end)
1965+
]
1966+
end}.
1967+
1968+
sub_test0(State0, Reg, Imm, Dump) ->
1969+
State1 = ?BACKEND:sub(State0, Reg, Imm),
1970+
Stream = ?BACKEND:stream(State1),
1971+
?assertEqual(dump_to_bin(Dump), Stream).
1972+
1973+
sub_test_() ->
1974+
{setup,
1975+
fun() ->
1976+
?BACKEND:new(?JIT_VARIANT_PIC, jit_stream_binary, jit_stream_binary:new(0))
1977+
end,
1978+
fun(State0) ->
1979+
[
1980+
?_test(begin
1981+
sub_test0(State0, r2, 2, <<
1982+
" 0: d1000842 sub x2, x2, #0x2"
1983+
>>)
1984+
end),
1985+
?_test(begin
1986+
sub_test0(State0, r2, 256, <<
1987+
" 0: d1040042 sub x2, x2, #0x100"
1988+
>>)
1989+
end),
1990+
?_test(begin
1991+
sub_test0(State0, r2, r3, <<
1992+
" 0: cb030042 sub x2, x2, x3"
1993+
>>)
1994+
end)
1995+
]
1996+
end}.
1997+
16651998
mul_test0(State0, Reg, Imm, Dump) ->
16661999
State1 = ?BACKEND:mul(State0, Reg, Imm),
16672000
Stream = ?BACKEND:stream(State1),

0 commit comments

Comments
 (0)