Only, that is not what is happening. Somewhere (either in this thread or the other thread( it was explained.
I honestly have no idea what you're talking about now. That was a discussion about implicit disabling of range checking for an array pointer. It is not related.
Well, I replied to your part about using an 32bit register, as a signed 64bit without sign extending.
This may not be the original topic, and you may not have introduced it, but you did entertain it. And I replied to the statement that you made about it.
So my reply is very related to the statement you made.
The error I describe here occurs even if I declare the array type as having a range of [-100..100] or whatever. It doesn't matter.
For example:
type
type
PAByte = ^TAByte;
TAByte = packed array [-100..100] of byte;
Unfortunately your code sample does not compile... So I can't do my own tests on it.
I took the code from your original post, and modified it accordingly
program Project1;
{$mode objfpc}{$R-}
type
PAInt = ^TAint;
// TAInt = array[0..255] of integer;
TAInt = array[-10..255] of integer;
var
a, b: PAint;
v: integer;
begin
GetMem(a, 200 * SizeOf(integer));
b := @a[100];
v := b^[-1];
v := b^[-2];
v := b^[-20];
end.
I need the "^" operator since it's not mode Delphi.
Now, different fpc versions used with different settings may produce different results.
My tests were done with
FPC 3.3.1 (from earlier this month)
-O-
In the original 0..255 array, accessing b^[-1] produced this asm
mov rax,[rip+$00014990]
mov eax,[rax+$0003FFFC]
mov [rip+$00014994],eax
The importance here is $3FFFC
And that is indeed strange, but appears somehow $40000 - 1 * sizeof(integer).
I don't know the compiler source code, but I would assume
# the compiler treated this as an unsigned value*
# Calculated cardinal(0) - sizeof(integer) = $FFFFFFFC
# For unknown reason masked that value to 20 bits.
And yes: b^[-2] produces mov eax,[rax+$0003FFF8]
So the value goes down in steps of sizeof(integer).
Then if the array is declare
[-10..255]I get
# [15] v := b^[-1];
movq U_$P$PROJECT1_$$_B(%rip),%rax
movl 36(%rax),%eax
movl %eax,U_$P$PROJECT1_$$_V(%rip)
# [16] v := b^[-2];
movq U_$P$PROJECT1_$$_B(%rip),%rax
movl 32(%rax),%eax
movl %eax,U_$P$PROJECT1_$$_V(%rip)
# [17] v := b^[-20];
movq U_$P$PROJECT1_$$_B(%rip),%rax
movl -40(%rax),%eax
movl %eax,U_$P$PROJECT1_$$_V(%rip)
The index -1 is 9 above the starting point of -10 => So the offset in memory is 36
The index -20 is 10 below -10 so the offset is -40
That looks correct to me.
Mind however, that it is not guaranteed for -20 (or other out of range values) to work.
If the compiler decided to use a signed-byte to do the calculations, then -300 would fail.
As I said, I couldn't check your latest example. It is not complete code.
But if I do (in above example / with "j:integer")
for j:= -1 to 1 do
v := b^[j];
then I get
# [15] for j:= -1 to 1 do
movl $-1,U_$P$PROJECT1_$$_J(%rip)
.p2align 4,,10
.p2align 3
.Lj3:
.Ll5:
# [16] v := b^[j];
movq U_$P$PROJECT1_$$_B(%rip),%rax
movslq U_$P$PROJECT1_$$_J(%rip),%rdx
movl 40(%rax,%rdx,4),%eax
movl %eax,U_$P$PROJECT1_$$_V(%rip)
.Ll6:
movl U_$P$PROJECT1_$$_J(%rip),%eax
addl $1,%eax
movl %eax,U_$P$PROJECT1_$$_J(%rip)
cmpl $1,U_$P$PROJECT1_$$_J(%rip)
jg .Lj5
jmp .Lj3
.Lj5:
.Ll7:
movslq is sign extended.
FPC 3.2.2 at -O- produces a bit different asm, but also use movslq.
Please indicate how you got the assemble code?
If you used the debugger to disassemble, maybe there is an issue there (you can compile with -al to get an assemble file).
Also compare the result you get at different optimization settings. Maybe there is a bug in the optimizer.