mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 10:09:20 +02:00
Merged revision(s) 31681, 31706, 31712, 31728, 31730, 31755 from trunk (ARM PIC):
* Big fix for ARM GOT support to make it work: - Fixed access to symbols with offset. - Always use register R9 for GOT pointer to prevent bugs when free register limit is reached in a function. - GOT is not needed for function calls by name. ........ * Fixed instruction re-scheduler for ARM in case of PIC. ........ * ARM: Do not use R9 as a fixed GOT register. ........ * ARM: Fixed GOT init when optimization is off. ........ * ARM: I hope this is a final proper fix for GOT initialization. + Test. ........ * Removed a leftover of my code. It is not needed anymore. ........ git-svn-id: branches/fixes_3_0@33438 -
This commit is contained in:
parent
30c1bd9125
commit
463152d34b
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -10396,6 +10396,7 @@ tests/tbs/tb0608.pp svneol=native#text/pascal
|
|||||||
tests/tbs/tb0609.pp svneol=native#text/plain
|
tests/tbs/tb0609.pp svneol=native#text/plain
|
||||||
tests/tbs/tb205.pp svneol=native#text/plain
|
tests/tbs/tb205.pp svneol=native#text/plain
|
||||||
tests/tbs/tb610.pp svneol=native#text/pascal
|
tests/tbs/tb610.pp svneol=native#text/pascal
|
||||||
|
tests/tbs/tb613.pp svneol=native#text/plain
|
||||||
tests/tbs/tbs0594.pp svneol=native#text/pascal
|
tests/tbs/tbs0594.pp svneol=native#text/pascal
|
||||||
tests/tbs/ub0060.pp svneol=native#text/plain
|
tests/tbs/ub0060.pp svneol=native#text/plain
|
||||||
tests/tbs/ub0069.pp svneol=native#text/plain
|
tests/tbs/ub0069.pp svneol=native#text/plain
|
||||||
|
@ -953,6 +953,8 @@ implementation
|
|||||||
{$endif cpu64bitaddr}
|
{$endif cpu64bitaddr}
|
||||||
aitconst_got:
|
aitconst_got:
|
||||||
begin
|
begin
|
||||||
|
if tai_const(hp).symofs<>0 then
|
||||||
|
InternalError(2015091401); // No symbol offset is allowed for GOT.
|
||||||
AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
|
AsmWrite(#9'.word'#9+tai_const(hp).sym.name+'(GOT)');
|
||||||
Asmln;
|
Asmln;
|
||||||
end;
|
end;
|
||||||
|
@ -2500,13 +2500,16 @@ Implementation
|
|||||||
hp3:=tai(p.Previous);
|
hp3:=tai(p.Previous);
|
||||||
hp5:=tai(p.next);
|
hp5:=tai(p.next);
|
||||||
asml.Remove(p);
|
asml.Remove(p);
|
||||||
{ if there is a reg. dealloc instruction associated with p, move it together with p }
|
{ if there is a reg. dealloc instruction or address labels (e.g. for GOT-less PIC)
|
||||||
|
associated with p, move it together with p }
|
||||||
|
|
||||||
{ before the instruction? }
|
{ before the instruction? }
|
||||||
while assigned(hp3) and (hp3.typ<>ait_instruction) do
|
while assigned(hp3) and (hp3.typ<>ait_instruction) do
|
||||||
begin
|
begin
|
||||||
if (hp3.typ=ait_regalloc) and (tai_regalloc(hp3).ratype in [ra_dealloc]) and
|
if ( (hp3.typ=ait_regalloc) and (tai_regalloc(hp3).ratype in [ra_dealloc]) and
|
||||||
RegInInstruction(tai_regalloc(hp3).reg,p) then
|
RegInInstruction(tai_regalloc(hp3).reg,p) )
|
||||||
|
or ( (hp3.typ=ait_label) and (tai_label(hp3).labsym.typ=AT_ADDR) )
|
||||||
|
then
|
||||||
begin
|
begin
|
||||||
hp4:=hp3;
|
hp4:=hp3;
|
||||||
hp3:=tai(hp3.Previous);
|
hp3:=tai(hp3.Previous);
|
||||||
@ -2552,7 +2555,7 @@ Implementation
|
|||||||
{$endif DEBUG_PREREGSCHEDULER}
|
{$endif DEBUG_PREREGSCHEDULER}
|
||||||
asml.InsertBefore(hp1,insertpos);
|
asml.InsertBefore(hp1,insertpos);
|
||||||
asml.InsertListBefore(insertpos,list);
|
asml.InsertListBefore(insertpos,list);
|
||||||
p:=tai(p.next)
|
p:=tai(p.next);
|
||||||
end
|
end
|
||||||
else if p.typ=ait_instruction then
|
else if p.typ=ait_instruction then
|
||||||
p:=hp1
|
p:=hp1
|
||||||
|
@ -653,7 +653,6 @@ unit cgcpu;
|
|||||||
if (tf_pic_uses_got in target_info.flags) and
|
if (tf_pic_uses_got in target_info.flags) and
|
||||||
(cs_create_pic in current_settings.moduleswitches) then
|
(cs_create_pic in current_settings.moduleswitches) then
|
||||||
begin
|
begin
|
||||||
include(current_procinfo.flags,pi_needs_got);
|
|
||||||
r.refaddr:=addr_pic
|
r.refaddr:=addr_pic
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -2263,22 +2262,43 @@ unit cgcpu;
|
|||||||
var
|
var
|
||||||
ref : treference;
|
ref : treference;
|
||||||
l : TAsmLabel;
|
l : TAsmLabel;
|
||||||
|
regs : tcpuregisterset;
|
||||||
|
r: byte;
|
||||||
begin
|
begin
|
||||||
if (cs_create_pic in current_settings.moduleswitches) and
|
if (cs_create_pic in current_settings.moduleswitches) and
|
||||||
(pi_needs_got in current_procinfo.flags) and
|
(pi_needs_got in current_procinfo.flags) and
|
||||||
(tf_pic_uses_got in target_info.flags) then
|
(tf_pic_uses_got in target_info.flags) then
|
||||||
begin
|
begin
|
||||||
|
{ Procedure parametrs are not initialized at this stage.
|
||||||
|
Before GOT initialization code, allocate registers used for procedure parameters
|
||||||
|
to prevent usage of these registers for temp operations in later stages of code
|
||||||
|
generation. }
|
||||||
|
regs:=rg[R_INTREGISTER].used_in_proc;
|
||||||
|
for r:=RS_R0 to RS_R3 do
|
||||||
|
if r in regs then
|
||||||
|
a_reg_alloc(list, newreg(R_INTREGISTER,r,R_SUBWHOLE));
|
||||||
|
{ Allocate scratch register R12 and use it for GOT calculations directly.
|
||||||
|
Otherwise the init code can be distorted in later stages of code generation. }
|
||||||
|
a_reg_alloc(list,NR_R12);
|
||||||
|
|
||||||
reference_reset(ref,4);
|
reference_reset(ref,4);
|
||||||
current_asmdata.getdatalabel(l);
|
current_asmdata.getdatalabel(l);
|
||||||
cg.a_label(current_procinfo.aktlocaldata,l);
|
cg.a_label(current_procinfo.aktlocaldata,l);
|
||||||
ref.symbol:=l;
|
ref.symbol:=l;
|
||||||
ref.base:=NR_PC;
|
ref.base:=NR_PC;
|
||||||
ref.symboldata:=current_procinfo.aktlocaldata.last;
|
ref.symboldata:=current_procinfo.aktlocaldata.last;
|
||||||
list.concat(Taicpu.op_reg_ref(A_LDR,current_procinfo.got,ref));
|
list.concat(Taicpu.op_reg_ref(A_LDR,NR_R12,ref));
|
||||||
current_asmdata.getaddrlabel(l);
|
current_asmdata.getaddrlabel(l);
|
||||||
current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_32bit,l,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),-8));
|
current_procinfo.aktlocaldata.concat(tai_const.Create_rel_sym_offset(aitconst_32bit,l,current_asmdata.RefAsmSymbol('_GLOBAL_OFFSET_TABLE_'),-8));
|
||||||
cg.a_label(list,l);
|
cg.a_label(list,l);
|
||||||
list.concat(Taicpu.op_reg_reg_reg(A_ADD,current_procinfo.got,NR_PC,current_procinfo.got));
|
list.concat(Taicpu.op_reg_reg_reg(A_ADD,NR_R12,NR_PC,NR_R12));
|
||||||
|
list.concat(Taicpu.op_reg_reg(A_MOV,current_procinfo.got,NR_R12));
|
||||||
|
|
||||||
|
{ Deallocate registers }
|
||||||
|
a_reg_dealloc(list,NR_R12);
|
||||||
|
for r:=RS_R3 downto RS_R0 do
|
||||||
|
if r in regs then
|
||||||
|
a_reg_dealloc(list, newreg(R_INTREGISTER,r,R_SUBWHOLE));
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@ -2374,12 +2394,12 @@ unit cgcpu;
|
|||||||
begin
|
begin
|
||||||
tmpreg:=g_indirect_sym_load(list,ref.symbol.name,asmsym2indsymflags(ref.symbol));
|
tmpreg:=g_indirect_sym_load(list,ref.symbol.name,asmsym2indsymflags(ref.symbol));
|
||||||
if ref.offset<>0 then
|
if ref.offset<>0 then
|
||||||
a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
|
a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
|
||||||
indirection_done:=true;
|
indirection_done:=true;
|
||||||
end
|
end
|
||||||
else if (cs_create_pic in current_settings.moduleswitches) then
|
else if (cs_create_pic in current_settings.moduleswitches) then
|
||||||
if (tf_pic_uses_got in target_info.flags) then
|
if (tf_pic_uses_got in target_info.flags) then
|
||||||
current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym_offset(aitconst_got,ref.symbol,ref.offset))
|
current_procinfo.aktlocaldata.concat(tai_const.Create_type_sym(aitconst_got,ref.symbol))
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
{ ideally, we would want to generate
|
{ ideally, we would want to generate
|
||||||
@ -2403,7 +2423,7 @@ unit cgcpu;
|
|||||||
current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset))
|
current_procinfo.aktlocaldata.concat(tai_const.create_sym_offset(ref.symbol,ref.offset))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
|
current_procinfo.aktlocaldata.concat(tai_const.Create_32bit(ref.offset));
|
||||||
|
|
||||||
{ load consts entry }
|
{ load consts entry }
|
||||||
if not indirection_done then
|
if not indirection_done then
|
||||||
@ -2421,6 +2441,8 @@ unit cgcpu;
|
|||||||
tmpref.base:=current_procinfo.got;
|
tmpref.base:=current_procinfo.got;
|
||||||
tmpref.index:=tmpreg;
|
tmpref.index:=tmpreg;
|
||||||
list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
|
list.concat(taicpu.op_reg_ref(A_LDR,tmpreg,tmpref));
|
||||||
|
if ref.offset<>0 then
|
||||||
|
a_op_const_reg(list,OP_ADD,OS_ADDR,ref.offset,tmpreg);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
85
tests/tbs/tb613.pp
Normal file
85
tests/tbs/tb613.pp
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
{$mode objfpc}
|
||||||
|
{$PIC+}
|
||||||
|
|
||||||
|
{
|
||||||
|
Test for proper initialization of GOT register.
|
||||||
|
}
|
||||||
|
|
||||||
|
const
|
||||||
|
BufSize = 128*1024;
|
||||||
|
|
||||||
|
var
|
||||||
|
gvar: longint;
|
||||||
|
|
||||||
|
procedure check(c, e: longint);
|
||||||
|
begin
|
||||||
|
if c <> e then begin
|
||||||
|
writeln('ERROR. Result: ', c, ' Expected: ', e);
|
||||||
|
Halt(1);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function test101(p1, p2: longint): longint;
|
||||||
|
begin
|
||||||
|
result:=gvar+p1+p2;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function test102(p1, p2: longint): longint;
|
||||||
|
var
|
||||||
|
Buffer: array[0..BufSize] of byte;
|
||||||
|
begin
|
||||||
|
Buffer[0]:=0;
|
||||||
|
result:=gvar+p1+p2+Buffer[0];
|
||||||
|
end;
|
||||||
|
|
||||||
|
function test103(p1, p2: longint): longint;
|
||||||
|
var
|
||||||
|
a, j: longint;
|
||||||
|
begin
|
||||||
|
a:=0;
|
||||||
|
for j:=1 to 1 do begin
|
||||||
|
a:=a + j;
|
||||||
|
a:=a - j;
|
||||||
|
end;
|
||||||
|
result:=gvar+p1+p2+a;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function test111(p1, p2: longint): longint;
|
||||||
|
var
|
||||||
|
i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15: longint;
|
||||||
|
a, j: longint;
|
||||||
|
begin
|
||||||
|
i1:=1;i2:=2;i3:=3;i4:=4;i5:=5;i6:=6;i7:=7;i8:=8;i9:=9;i10:=10;i11:=11;i12:=12;i13:=13;i14:=14;i15:=15;
|
||||||
|
a:=0;
|
||||||
|
for j:=1 to 1 do begin
|
||||||
|
a:=a + (i1+i2+i3+i4+i5+i6+i7+i8+i9+i10+i11+i12+i13+i14+i15);
|
||||||
|
a:=a - (i1+i2+i3+i4+i5+i6+i7+i8+i9+i10+i11+i12+i13+i14+i15);
|
||||||
|
end;
|
||||||
|
result:=gvar+p1+p2+a;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function test112(p1, p2: longint): longint;
|
||||||
|
var
|
||||||
|
i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15: longint;
|
||||||
|
a, j: longint;
|
||||||
|
Buffer: array[0..BufSize] of byte;
|
||||||
|
begin
|
||||||
|
i1:=1;i2:=2;i3:=3;i4:=4;i5:=5;i6:=6;i7:=7;i8:=8;i9:=9;i10:=10;i11:=11;i12:=12;i13:=13;i14:=14;i15:=15;
|
||||||
|
a:=0;
|
||||||
|
Buffer[0]:=0;
|
||||||
|
for j:=1 to 1 do begin
|
||||||
|
a:=a + (i1+i2+i3+i4+i5+i6+i7+i8+i9+i10+i11+i12+i13+i14+i15);
|
||||||
|
a:=a - (i1+i2+i3+i4+i5+i6+i7+i8+i9+i10+i11+i12+i13+i14+i15);
|
||||||
|
a:=a + Buffer[0];
|
||||||
|
end;
|
||||||
|
result:=gvar+p1+p2+a;
|
||||||
|
end;
|
||||||
|
|
||||||
|
begin
|
||||||
|
gvar:=100;
|
||||||
|
check(test101(10, 20), 130);
|
||||||
|
check(test102(20, 30), 150);
|
||||||
|
check(test103(30, 40), 170);
|
||||||
|
check(test111(110, 20), 230);
|
||||||
|
check(test112(120, 30), 250);
|
||||||
|
end.
|
Loading…
Reference in New Issue
Block a user