Xtensa [patch] Error in calculating base and offset in tcgcpu.a_op_const_reg_reg
Original Reporter info from Mantis: ccrause @ccrause
-
Reporter name: Christo Crause
Original Reporter info from Mantis: ccrause @ccrause
- Reporter name: Christo Crause
Description:
Current calculation of base and offset for constants in tcgcpu.a_op_const_reg_reg using the addmi + addi pair of instructions are sometimes incorrect. The current behaviour is to truncate the upper byte of parameter "a" to a multiple of 256. In some cases the offset can exceed the valid range for addi (-128 to 127). Consider:
a := 480 then
Smallint(a and $ff00) = 256
and
Shortint(a and $ff) = -32
Obviously 256 - 32 <> 480
Also if a := -280 then
Smallint(a and $ff00) = -512
and
Shortint(a and $ff) = -24
Again -512 - 24 <> -280
The issue can be fixed by adding 128 to the first calculation, turning the truncation into a round to nearest:
a := 480
Smallint((a+128) and $ff00) = 512
and
Shortint(a and $ff) = -32
512 - 32 = 480
Similarly
a := -280
Smallint((a+128) and $ff00) = -256
and
Shortint(a and $ff) = -24
-256 - 24 = -280
This behaviour was noticed when using references to local variables, see steps to reproduce.
Steps to reproduce:
program testbug;
procedure testproc;
var
LongArray: array[0..479] of byte;
i: integer;
ptr: uint32;
begin
ptr := uint32(@i);
writeln('@i = ', HexStr(ptr, 4));
end;
begin
testproc;
end.
Additional information:
The code generated to store @i into ptr generated with trunk compiler:
# Var LongArray located at a1+0, size=OS_NO # Var i located at a1+480, size=OS_S32 # Var ptr located at a1+484, size=OS_32 # [11] ptr := uint32(@i); addmi a2,a1,256 // incorrect base calculated addi a2,a2,-32 s32i a2,a1,484
The same code after the patching trunk:
# Var LongArray located at a1+0, size=OS_NO # Var i located at a1+480, size=OS_S32 # Var ptr located at a1+484, size=OS_32 # [11] ptr := uint32(@i); addmi a2,a1,512 // correct base to put offset within range addi a2,a2,-32
s32i a2,a1,484
Mantis conversion info:
- Mantis ID: 37015
- Build: 45251
- Version: 3.3.1
- Fixed in revision: 45258 (#724676db)