Xtensa incorrect stack based parameter passing
Original Reporter info from Mantis: ccrause @ccrause
-
Reporter name: Christo Crause
Original Reporter info from Mantis: ccrause @ccrause
- Reporter name: Christo Crause
Description:
Calling a procedure with more than 6 parameters (thus forcing parameter passing via stack) results in errors for both windowed and call0 ABIs. The reason appears to be that the caller stores the stack parameters starting at the caller SP (which is correct according to the ISA). The callee loads the stack based parameter relative to the start of its stack/frame pointer. In steps to reproduce please find a simple test program. The disassembled code from this test program is shown in additional information.
Note the following:
In main the address of variable gg is stored at the current (caller) SP: # [13] test(aa, bb, cc, dd, ee, ff, gg); l32r a2,.Lj5 s32i a2,a1,0
On the callee side parameter f is loaded relative the callee SP:
# Var g located at a15+24, size=OS_32
addi a2,a15,24
l32i a3,a15,0
s32i a3,a2,0
The ISA has the following to say: "If there are more than six words of arguments, the additional arguments are stored on
the stack beginning at the caller’s stack pointer and at increasingly positive offsets from
the stack pointer. That is, the caller stores the seventh argument word (after the first six
words in registers) at [sp + 0], the eighth word at [sp + 4], and so on. The callee can ac-
cess these arguments in memory beginning at [sp + FRAMESIZE], where FRAMESIZE
is the size of the callee’s stack frame."
From the generated assembler it is clear that the FRAMESIZE offset is missing, hence the stack based parameters are loaded from the wrong memory locations.
Steps to reproduce:
program testparams;
procedure test(var a, b, c, d, e, f, g: uint32);
begin
g := 13;
end;
var
aa, bb, cc, dd, ee, ff, gg: uint32;
begin
gg := 0;
test(aa, bb, cc, dd, ee, ff, gg);
if gg = 13 then
halt(0)
else
halt(13);
end.
Additional information:
.section .text.n_p$testparams_$$_test$longword$longword$longword$longword$longword$longword$longword,"ax" .balign 4 .globl P$TESTPARAMS_$$_TEST$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD P$TESTPARAMS_$$_TEST$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD: .Ll1: # [testparams.pp] # [4] begin addi a1,a1,-32 s32i a15,a1,28 mov a15,a1 # Var a located at a15+0, size=OS_32 # Var b located at a15+4, size=OS_32 # Var c located at a15+8, size=OS_32 # Var d located at a15+12, size=OS_32 # Var e located at a15+16, size=OS_32 # Var f located at a15+20, size=OS_32 # Var g located at a15+24, size=OS_32 s32i a2,a15,0 s32i a3,a15,4 s32i a4,a15,8 s32i a5,a15,12 s32i a6,a15,16 s32i a7,a15,20 addi a2,a15,24 l32i a3,a15,0 s32i a3,a2,0 .Ll2: # [5] g := 13; l32i a2,a15,24 movi a3,13 s32i a3,a2,0 .Ll3: # [6] end; l32i a15,a1,28 addi a1,a1,32 ret .Lt2: .Le0: .size P$TESTPARAMS_$$_TEST$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD, .Le0 - P$TESTPARAMS_$$_TEST$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD .Ll4:
.section .text.n_main,"ax" .balign 4 .Lj5: .long U_$P$TESTPARAMS_$$_GG .Lj6: .long U_$P$TESTPARAMS_$$_FF .Lj7: .long U_$P$TESTPARAMS_$$_EE .Lj8: .long U_$P$TESTPARAMS_$$_DD .Lj9: .long U_$P$TESTPARAMS_$$_CC .Lj10: .long U_$P$TESTPARAMS_$$_BB .Lj11: .long U_$P$TESTPARAMS_$$_AA .balign 4 .globl main main: .globl PASCALMAIN PASCALMAIN: .Ll5: # [11] begin addi a1,a1,-48 s32i a15,a1,44 mov a15,a1 s32i a0,a1,40 call0 FPC_INIT_FUNC_TABLE .Ll6: # [12] gg := 0; movi a2,0 l32r a3,.Lj5 s32i a2,a3,0 .Ll7: # [13] test(aa, bb, cc, dd, ee, ff, gg); l32r a2,.Lj5 s32i a2,a1,0 l32r a7,.Lj6 l32r a6,.Lj7 l32r a5,.Lj8 l32r a4,.Lj9 l32r a3,.Lj10 l32r a2,.Lj11 call0 P$TESTPARAMS_$$_TEST$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD$LONGWORD .Ll8: # [14] if gg = 13 then l32r a2,.Lj5 l32i a2,a2,0 movi a3,13 beq a2,a3,.Lj12 j .Lj13 .Lj12: .Ll9: # [15] halt(0) movi a2,0 call0 SYSTEM_$$_HALT$LONGINT j .Lj14 .Lj13: .Ll10: # [17] halt(1); movi a2,1 call0 SYSTEM_$$_HALT$LONGINT .Lj14: .Ll11: # [18] end. call0 fpc_do_exit l32i a15,a1,44 l32i a0,a1,40 addi a1,a1,48
ret
Mantis conversion info:
- Mantis ID: 37708
- Build: 46770
- Version: 3.3.1
- Fixed in version: 3.3.1