Skip to content

Commit 90fc73d

Browse files
committed
Merge pull request #2276 from pguyot/w16/arm32-fixup
JIT arm32: assemble push and pop with single reg as gnu as These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents 34d2818 + f51f033 commit 90fc73d

2 files changed

Lines changed: 32 additions & 6 deletions

File tree

libs/jit/src/jit_arm32_asm.erl

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,16 @@ blx(Cond, Rm) ->
506506
%% PUSH {reglist} = STMDB SP!, {reglist}
507507
%% Encoding: cond[31:28] 100 1 0 0 1 0 1101 reglist[15:0]
508508
-spec push([arm_gpr_register()]) -> binary().
509+
push([sp]) ->
510+
%% GNU as uses STMDB for push {sp} (STR SP,[SP,#-4]! has undefined behavior)
511+
RegMask = 1 bsl 13,
512+
Instr = (14 bsl 28) bor (2#100100101101 bsl 16) bor RegMask,
513+
<<Instr:32/little>>;
514+
push([Reg]) ->
515+
%% STR Rd, [SP, #-4]!: single-register push (matches GNU as encoding)
516+
RegNum = reg_to_num(Reg),
517+
Instr = 16#E52D0004 bor (RegNum bsl 12),
518+
<<Instr:32/little>>;
509519
push(RegList) ->
510520
RegMask = reglist_to_mask(RegList),
511521
%% STMDB SP!: cond=AL 1001 0010 1101 reglist
@@ -515,6 +525,16 @@ push(RegList) ->
515525
%% POP {reglist} = LDMIA SP!, {reglist}
516526
%% Encoding: cond[31:28] 100 0 1 0 1 1 1101 reglist[15:0]
517527
-spec pop([arm_gpr_register()]) -> binary().
528+
pop([sp]) ->
529+
%% GNU as uses LDMIA for pop {sp} (LDR SP,[SP],#4 has undefined behavior)
530+
RegMask = 1 bsl 13,
531+
Instr = (14 bsl 28) bor (2#100010111101 bsl 16) bor RegMask,
532+
<<Instr:32/little>>;
533+
pop([Reg]) ->
534+
%% LDR Rd, [SP], #4: single-register pop (matches GNU as encoding)
535+
RegNum = reg_to_num(Reg),
536+
Instr = 16#E49D0004 bor (RegNum bsl 12),
537+
<<Instr:32/little>>;
518538
pop(RegList) ->
519539
RegMask = reglist_to_mask(RegList),
520540
%% LDMIA SP!: cond=AL 1000 1011 1101 reglist

tests/libs/jit/jit_arm32_asm_tests.erl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,12 +280,15 @@ blx_test_() ->
280280

281281
push_test_() ->
282282
[
283-
%% PUSH (STMDB SP!)
284-
?_assertAsmEqual(<<16#E92D0001:32/little>>, "push {r0}", jit_arm32_asm:push([r0])),
283+
%% single-register PUSH = STR Rd, [SP, #-4]!
284+
?_assertAsmEqual(<<16#E52D0004:32/little>>, "push {r0}", jit_arm32_asm:push([r0])),
285+
%% gcc as accepts to encode this, even if behavior is undefined
286+
?_assertAsmEqual(<<16#E92D2000:32/little>>, "push {sp}", jit_arm32_asm:push([sp])),
287+
%% multi-register PUSH = STMDB SP!
285288
?_assertAsmEqual(
286289
<<16#E92D0007:32/little>>, "push {r0, r1, r2}", jit_arm32_asm:push([r0, r1, r2])
287290
),
288-
?_assertAsmEqual(<<16#E92D4000:32/little>>, "push {lr}", jit_arm32_asm:push([lr])),
291+
?_assertAsmEqual(<<16#E52DE004:32/little>>, "push {lr}", jit_arm32_asm:push([lr])),
289292
?_assertAsmEqual(
290293
<<16#E92D4007:32/little>>, "push {r0, r1, r2, lr}", jit_arm32_asm:push([r0, r1, r2, lr])
291294
),
@@ -298,12 +301,15 @@ push_test_() ->
298301

299302
pop_test_() ->
300303
[
301-
%% POP (LDMIA SP!)
302-
?_assertAsmEqual(<<16#E8BD0001:32/little>>, "pop {r0}", jit_arm32_asm:pop([r0])),
304+
%% single-register POP = LDR Rd, [SP], #4
305+
?_assertAsmEqual(<<16#E49D0004:32/little>>, "pop {r0}", jit_arm32_asm:pop([r0])),
306+
%% gcc as accepts to encode this, even if behavior is undefined
307+
?_assertAsmEqual(<<16#E8BD2000:32/little>>, "pop {sp}", jit_arm32_asm:pop([sp])),
308+
%% multi-register POP = LDMIA SP!
303309
?_assertAsmEqual(
304310
<<16#E8BD0007:32/little>>, "pop {r0, r1, r2}", jit_arm32_asm:pop([r0, r1, r2])
305311
),
306-
?_assertAsmEqual(<<16#E8BD8000:32/little>>, "pop {pc}", jit_arm32_asm:pop([pc])),
312+
?_assertAsmEqual(<<16#E49DF004:32/little>>, "pop {pc}", jit_arm32_asm:pop([pc])),
307313
?_assertAsmEqual(
308314
<<16#E8BD8007:32/little>>, "pop {r0, r1, r2, pc}", jit_arm32_asm:pop([r0, r1, r2, pc])
309315
),

0 commit comments

Comments
 (0)