Skip to content

Commit dae94d0

Browse files
committed
AArch64: fix assembler for some instructions and tests
Signed-off-by: Paul Guyot <[email protected]>
1 parent 2f7279c commit dae94d0

File tree

2 files changed

+74
-28
lines changed

2 files changed

+74
-28
lines changed

libs/jit/src/jit_aarch64_asm.erl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,8 +235,9 @@ mov(Rd, Rm) when is_atom(Rd), is_atom(Rm) ->
235235
mov_immediate(Dst, Imm) when Imm >= 0, Imm =< 16#FFFF ->
236236
%% Simple 16-bit positive immediate
237237
movz(Dst, Imm, 0);
238-
mov_immediate(Dst, Imm) when Imm < 0, Imm >= -16#FFFF ->
238+
mov_immediate(Dst, Imm) when Imm < 0, (-Imm - 1) =< 16#FFFF ->
239239
%% Simple 16-bit negative immediate using MOVN
240+
%% MOVN encodes ~immediate, so we can use it when ~Imm fits in 16 bits
240241
DstNum = reg_to_num(Dst),
241242
<<(16#92800000 bor (((-Imm - 1) band 16#FFFF) bsl 5) bor DstNum):32/little>>;
242243
mov_immediate(Dst, Imm) when Imm >= 0 ->
@@ -372,7 +373,7 @@ orr_immediate(Dst, N, Immr, Imms) when
372373
% 64-bit operation
373374
Sf = 1,
374375
<<
375-
((Sf bsl 31) bor (16#32000000) bor (N bsl 22) bor (Immr bsl 16) bor (Imms bsl 10) bor
376+
((Sf bsl 31) bor (16#B2000000) bor (N bsl 22) bor (Immr bsl 16) bor (Imms bsl 10) bor
376377
(31 bsl 5) bor DstNum):32/little
377378
>>.
378379

@@ -796,7 +797,7 @@ cmp(Rn, Imm) when is_atom(Rn), is_integer(Imm) ->
796797
%% For large immediates, load into a temporary register and compare
797798
%% Use r16 as temporary register (caller-saved)
798799
TempReg = r16,
799-
LoadInstr = build_positive_immediate(TempReg, <<Imm:64>>),
800+
LoadInstr = mov_immediate(TempReg, Imm),
800801
CmpInstr = cmp(Rn, TempReg),
801802
<<LoadInstr/binary, CmpInstr/binary>>.
802803

tests/libs/jit/jit_aarch64_asm_tests.erl

Lines changed: 70 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,29 @@
2424
-include_lib("eunit/include/eunit.hrl").
2525
-endif.
2626

27+
-export([
28+
list_to_integer/1,
29+
list_to_integer/2
30+
]).
31+
32+
list_to_integer(X) -> erlang:list_to_integer(X).
33+
list_to_integer(X, B) -> erlang:list_to_integer(X, B).
34+
2735
-define(_assertAsmEqual(Bin, Str, Value),
2836
?_assertEqual(jit_tests_common:asm(aarch64, Bin, Str), Value)
2937
).
38+
-define(_assertAsmEqualLargeInt(Bin, Str, Value),
39+
?_test(begin
40+
case erlang:system_info(machine) of
41+
"BEAM" ->
42+
?assertEqual(jit_tests_common:asm(aarch64, Bin, Str), Value);
43+
"ATOM" ->
44+
% AtomVM doesn't handle large integers yet.
45+
% Skip the test
46+
ok
47+
end
48+
end)
49+
).
3050

3151
add_test_() ->
3252
[
@@ -236,14 +256,14 @@ mov_test_() ->
236256
),
237257

238258
% mov immediate - very large value requiring multiple instructions
239-
?_assertAsmEqual(
259+
?_assertAsmEqualLargeInt(
240260
<<16#D29579A1:32/little, 16#F2B7C041:32/little, 16#F2DFD741:32/little,
241261
16#F2EFF941:32/little>>,
242262
"mov x1, #0xabcd\n"
243263
"movk x1, #0xbe02, lsl #16\n"
244264
"movk x1, #0xfeba, lsl #32\n"
245265
"movk x1, #0x7fca, lsl #48",
246-
jit_aarch64_asm:mov(r1, 9208452466117618637)
266+
jit_aarch64_asm:mov(r1, ?MODULE:list_to_integer("9208452466117618637"))
247267
),
248268

249269
% mov register
@@ -256,20 +276,28 @@ mov_test_() ->
256276
),
257277

258278
%% Test 4-bit pattern encoding
259-
?_test(begin
260-
Result = jit_aarch64_asm:mov(r0, 16#FFFFFFFFFFFF0000),
261-
?assert(is_binary(Result))
262-
end),
279+
?_assertAsmEqual(
280+
<<16#929fffe0:32/little>>,
281+
"mov x0, #-65536",
282+
jit_aarch64_asm:mov(r0, -65536)
283+
),
263284
%% Test complex immediate that will use fallback sequence
264-
?_test(begin
265-
% This should be a complex immediate that can't be encoded as bitmask
266-
% and needs fallback to build_immediate_sequence
267-
Result = jit_aarch64_asm:mov(r0, 16#123456789ABCDEF0),
268-
?assert(is_binary(Result))
269-
end),
285+
?_assertAsmEqualLargeInt(
286+
<<
287+
16#d29bde00:32/little,
288+
16#f2b35780:32/little,
289+
16#f2cacf00:32/little,
290+
16#f2e24680:32/little
291+
>>,
292+
"mov x0, #0xdef0\n"
293+
"movk x0, #0x9abc, lsl #16\n"
294+
"movk x0, #0x5678, lsl #32\n"
295+
"movk x0, #0x1234, lsl #48",
296+
jit_aarch64_asm:mov(r0, ?MODULE:list_to_integer("123456789ABCDEF0", 16))
297+
),
270298

271299
%% Test negative immediate that uses build_negative_immediate fallback
272-
?_assertAsmEqual(
300+
?_assertAsmEqualLargeInt(
273301
<<
274302
16#d2842200:32/little,
275303
16#f2aca860:32/little,
@@ -280,27 +308,27 @@ mov_test_() ->
280308
"movk x0, #0x6543, lsl #16\n"
281309
"movk x0, #0xa987, lsl #32\n"
282310
"movk x0, #0xedcb, lsl #48",
283-
jit_aarch64_asm:mov(r0, -16#123456789ABCDEF0)
311+
jit_aarch64_asm:mov(r0, ?MODULE:list_to_integer("-123456789ABCDEF0", 16))
284312
),
285313

286314
%% Test bitmask patterns with different sizes
287315
%% Size 16 pattern: repeats every 16 bits
288-
?_assertAsmEqual(
316+
?_assertAsmEqualLargeInt(
289317
<<16#b20083e0:32/little>>,
290318
"mov x0, #0x0001000100010001",
291-
jit_aarch64_asm:mov(r0, 16#0001000100010001)
319+
jit_aarch64_asm:mov(r0, ?MODULE:list_to_integer("0001000100010001", 16))
292320
),
293321
%% Size 4 pattern: repeats every 4 bits
294-
?_assertAsmEqual(
322+
?_assertAsmEqualLargeInt(
295323
<<16#b200e7e0:32/little>>,
296324
"mov x0, #0x3333333333333333",
297-
jit_aarch64_asm:mov(r0, 16#3333333333333333)
325+
jit_aarch64_asm:mov(r0, ?MODULE:list_to_integer("3333333333333333", 16))
298326
),
299327
%% Size 2 pattern: repeats every 2 bits
300-
?_assertAsmEqual(
328+
?_assertAsmEqualLargeInt(
301329
<<16#b200f3e0:32/little>>,
302330
"mov x0, #0x5555555555555555",
303-
jit_aarch64_asm:mov(r0, 16#5555555555555555)
331+
jit_aarch64_asm:mov(r0, ?MODULE:list_to_integer("5555555555555555", 16))
304332
)
305333
].
306334

@@ -380,11 +408,28 @@ cmp_test_() ->
380408
?_assertAsmEqual(<<16#F103001F:32/little>>, "cmp x0, #192", jit_aarch64_asm:cmp(r0, 192)),
381409

382410
%% Test large immediate compare (uses temporary register)
383-
?_test(begin
384-
Result = jit_aarch64_asm:cmp(r0, 16#12345678),
385-
?assert(is_binary(Result)),
386-
?assert(byte_size(Result) > 4)
387-
end)
411+
?_assertAsmEqual(
412+
<<
413+
16#d28acf10:32/little,
414+
16#f2a24690:32/little,
415+
16#eb10001f:32/little
416+
>>,
417+
"mov x16, #0x5678\n"
418+
"movk x16, #0x1234, lsl #16\n"
419+
"cmp x0, x16",
420+
jit_aarch64_asm:cmp(r0, 16#12345678)
421+
),
422+
423+
%% Test negative immediate compare (uses MOVN)
424+
?_assertAsmEqual(
425+
<<
426+
16#92800010:32/little,
427+
16#eb1000ff:32/little
428+
>>,
429+
"movn x16, #0\n"
430+
"cmp x7, x16",
431+
jit_aarch64_asm:cmp(r7, -1)
432+
)
388433
].
389434

390435
cmp_w_test_() ->

0 commit comments

Comments
 (0)