* get rid of addr_load_indirect again by having tcgx86 provide an internal implementation of both make_simple_ref() and a_load_ref_reg() so that make_direct_ref() can call the latter (and the latter the former) without fear of inifinite recursive calls due to the symbol; a_load_ref_reg() is additionally declared as "final" as a_load_ref_reg_internal() needs to be overloaded instead (which is the case for tcg8086)

git-svn-id: trunk@34579 -
This commit is contained in:
svenbarth 2016-09-30 14:01:02 +00:00
parent d4f0634908
commit c8202061dc
3 changed files with 30 additions and 13 deletions

View File

@ -69,8 +69,7 @@ interface
addr_no,
addr_full,
addr_pic,
addr_pic_no_got,
addr_load_indirect // only load symbol address via indirect symbol, not actual symbol data
addr_pic_no_got
{$IF defined(POWERPC) or defined(POWERPC64) or defined(SPARC) or defined(MIPS)}
,
addr_low, // bits 48-63

View File

@ -68,7 +68,8 @@ unit cgcpu;
procedure a_load_const_reg(list : TAsmList; tosize: tcgsize; a : tcgint;reg : tregister);override;
procedure a_load_const_ref(list : TAsmList; tosize: tcgsize; a : tcgint;const ref : treference);override;
procedure a_load_reg_ref(list : TAsmList;fromsize,tosize: tcgsize; reg : tregister;const ref : treference);override;
procedure a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override;
{ use a_load_ref_reg_internal() instead }
//procedure a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override;
procedure a_load_reg_reg(list : TAsmList;fromsize,tosize: tcgsize;reg1,reg2 : tregister);override;
{ comparison operations }
@ -96,6 +97,8 @@ unit cgcpu;
procedure get_32bit_ops(op: TOpCG; out op1,op2: TAsmOp);
procedure add_move_instruction(instr:Taicpu);override;
protected
procedure a_load_ref_reg_internal(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister;isdirect:boolean);override;
end;
tcg64f8086 = class(tcg64f32)
@ -1249,7 +1252,7 @@ unit cgcpu;
end;
procedure tcg8086.a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);
procedure tcg8086.a_load_ref_reg_internal(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister;isdirect:boolean);
procedure add_mov(instr: Taicpu);
begin
@ -1264,7 +1267,7 @@ unit cgcpu;
tmpref : treference;
begin
tmpref:=ref;
make_simple_ref(list,tmpref);
make_simple_ref(list,tmpref,isdirect);
check_register_size(tosize,reg);
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then

View File

@ -77,7 +77,8 @@ unit cgx86;
procedure a_load_const_reg(list : TAsmList; tosize: tcgsize; a : tcgint;reg : tregister);override;
procedure a_load_const_ref(list : TAsmList; tosize: tcgsize; a : tcgint;const ref : treference);override;
procedure a_load_reg_ref(list : TAsmList;fromsize,tosize: tcgsize; reg : tregister;const ref : treference);override;
procedure a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override;
{ final as a_load_ref_reg_internal() should be overridden instead }
procedure a_load_ref_reg(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister);override;final;
procedure a_load_reg_reg(list : TAsmList;fromsize,tosize: tcgsize;reg1,reg2 : tregister);override;
procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
@ -125,13 +126,15 @@ unit cgx86;
procedure g_overflowcheck(list: TAsmList; const l:tlocation;def:tdef);override;
procedure make_simple_ref(list:TAsmList;var ref: treference);
procedure make_simple_ref(list:TAsmList;var ref: treference);inline;
procedure make_direct_ref(list:TAsmList;var ref: treference);
function get_darwin_call_stub(const s: string; weak: boolean): tasmsymbol;
procedure generate_leave(list : TAsmList);
protected
procedure a_load_ref_reg_internal(list : TAsmList;fromsize,tosize: tcgsize;const ref : treference;reg : tregister;isdirect:boolean);virtual;
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
procedure check_register_size(size:tcgsize;reg:tregister);
@ -146,6 +149,8 @@ unit cgx86;
procedure floatstoreops(t : tcgsize;var op : tasmop;var s : topsize);
procedure internal_restore_regs(list: TAsmList; use_pop: boolean);
procedure make_simple_ref(list:TAsmList;var ref: treference;isdirect:boolean);
end;
const
@ -412,6 +417,12 @@ unit cgx86;
procedure tcgx86.make_simple_ref(list:TAsmList;var ref: treference);
begin
make_simple_ref(list,ref,false);
end;
procedure tcgx86.make_simple_ref(list:TAsmList;var ref: treference;isdirect:boolean);
var
hreg : tregister;
href : treference;
@ -426,7 +437,7 @@ unit cgx86;
exit;
{ handle indirect symbols first }
if ref.refaddr<>addr_load_indirect then
if not isdirect then
make_direct_ref(list,ref);
{$if defined(x86_64)}
@ -655,8 +666,7 @@ unit cgx86;
reference_reset_symbol(href,ref.symbol,0,sizeof(pint));
{ tell make_simple_ref that we are loading the symbol address via an indirect
symbol and that hence it should not call make_direct_ref() again }
href.refaddr:=addr_load_indirect;
a_op_ref_reg(list,OP_MOVE,OS_ADDR,href,hreg);
a_load_ref_reg_internal(list,OS_ADDR,OS_ADDR,href,hreg,true);
if ref.base<>NR_NO then
begin
{ fold symbol register into base register }
@ -973,13 +983,19 @@ unit cgx86;
procedure tcgx86.a_load_ref_reg(list : TAsmList;fromsize,tosize : tcgsize;const ref: treference;reg : tregister);
begin
a_load_ref_reg_internal(list,fromsize,tosize,ref,reg,false);
end;
procedure tcgx86.a_load_ref_reg_internal(list : TAsmList;fromsize,tosize : tcgsize;const ref: treference;reg : tregister;isdirect:boolean);
var
op: tasmop;
s: topsize;
tmpref : treference;
begin
tmpref:=ref;
make_simple_ref(list,tmpref);
make_simple_ref(list,tmpref,isdirect);
check_register_size(tosize,reg);
sizes2load(fromsize,tosize,op,s);
{$ifdef x86_64}
@ -1042,8 +1058,7 @@ unit cgx86;
{ this could probably done in a more optimized way, but for now this
is sufficent }
if dirref.refaddr<>addr_load_indirect then
make_direct_ref(list,dirref);
make_direct_ref(list,dirref);
with dirref do
begin