mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-24 12:49:18 +02:00
+ PIC support for darwin/ppc64
* added {$PIC+} for darwin to all library tests git-svn-id: trunk@8868 -
This commit is contained in:
parent
c77267e01f
commit
45b7358d81
@ -100,14 +100,6 @@ unit cgcpu;
|
|||||||
{ the upper 24/16 bits of a register after an operation }
|
{ the upper 24/16 bits of a register after an operation }
|
||||||
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
||||||
|
|
||||||
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
|
||||||
{ base to the value of the index if (base = R_NO). }
|
|
||||||
{ Returns true if the reference contained a base, index and an }
|
|
||||||
{ offset or symbol, in which case the base will have been changed }
|
|
||||||
{ to a tempreg (which has to be freed by the caller) containing }
|
|
||||||
{ the sum of part of the original reference }
|
|
||||||
function fixref(list: TAsmList; var ref: treference): boolean; override;
|
|
||||||
|
|
||||||
{ returns whether a reference can be used immediately in a powerpc }
|
{ returns whether a reference can be used immediately in a powerpc }
|
||||||
{ instruction }
|
{ instruction }
|
||||||
function issimpleref(const ref: treference): boolean;
|
function issimpleref(const ref: treference): boolean;
|
||||||
@ -1656,69 +1648,6 @@ const
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function tcgppc.fixref(list: TAsmList; var ref: treference): boolean;
|
|
||||||
|
|
||||||
var
|
|
||||||
tmpreg: tregister;
|
|
||||||
begin
|
|
||||||
result := false;
|
|
||||||
|
|
||||||
if (target_info.system = system_powerpc_darwin) and
|
|
||||||
assigned(ref.symbol) and
|
|
||||||
not assigned(ref.relsymbol) and
|
|
||||||
((ref.symbol.bind = AB_EXTERNAL) or
|
|
||||||
(cs_create_pic in current_settings.moduleswitches))then
|
|
||||||
begin
|
|
||||||
if (ref.symbol.bind = AB_EXTERNAL) or
|
|
||||||
((cs_create_pic in current_settings.moduleswitches) and
|
|
||||||
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
|
||||||
begin
|
|
||||||
tmpreg := g_indirect_sym_load(list,ref.symbol.name);
|
|
||||||
ref.symbol:=nil;
|
|
||||||
end
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
include(current_procinfo.flags,pi_needs_got);
|
|
||||||
tmpreg := current_procinfo.got;
|
|
||||||
if assigned(ref.relsymbol) then
|
|
||||||
internalerror(2007093501);
|
|
||||||
ref.relsymbol := current_procinfo.CurrGOTLabel;
|
|
||||||
end;
|
|
||||||
if (ref.base = NR_NO) then
|
|
||||||
ref.base := tmpreg
|
|
||||||
else if (ref.index = NR_NO) then
|
|
||||||
ref.index := tmpreg
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.base,tmpreg));
|
|
||||||
ref.base := tmpreg;
|
|
||||||
end;
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (ref.base = NR_NO) then
|
|
||||||
begin
|
|
||||||
ref.base := ref.index;
|
|
||||||
ref.index := NR_NO;
|
|
||||||
end;
|
|
||||||
if (ref.base <> NR_NO) then
|
|
||||||
begin
|
|
||||||
if (ref.index <> NR_NO) and
|
|
||||||
((ref.offset <> 0) or assigned(ref.symbol)) then
|
|
||||||
begin
|
|
||||||
result := true;
|
|
||||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
|
||||||
list.concat(taicpu.op_reg_reg_reg(
|
|
||||||
A_ADD,tmpreg,ref.base,ref.index));
|
|
||||||
ref.index := NR_NO;
|
|
||||||
ref.base := tmpreg;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
if ref.index <> NR_NO then
|
|
||||||
internalerror(200208102);
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
{ find out whether a is of the form 11..00..11b or 00..11...00. If }
|
{ find out whether a is of the form 11..00..11b or 00..11...00. If }
|
||||||
{ that's the case, we can use rlwinm to do an AND operation }
|
{ that's the case, we can use rlwinm to do an AND operation }
|
||||||
function tcgppc.get_rlwi_const(a: aint; var l1, l2: longint): boolean;
|
function tcgppc.get_rlwi_const(a: aint; var l1, l2: longint): boolean;
|
||||||
|
@ -107,16 +107,6 @@ type
|
|||||||
|
|
||||||
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
procedure maybeadjustresult(list: TAsmList; op: TOpCg; size: tcgsize; dst: tregister);
|
||||||
|
|
||||||
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
|
||||||
{ base to the value of the index if (base = R_NO). }
|
|
||||||
{ Returns true if the reference contained a base, index and an }
|
|
||||||
{ offset or symbol, in which case the base will have been changed }
|
|
||||||
{ to a tempreg (which has to be freed by the caller) containing }
|
|
||||||
{ the sum of part of the original reference }
|
|
||||||
function fixref(list: TAsmList; var ref: treference): boolean; override;
|
|
||||||
|
|
||||||
function load_got_symbol(list : TAsmList; symbol : string) : tregister;
|
|
||||||
|
|
||||||
{ returns whether a reference can be used immediately in a powerpc }
|
{ returns whether a reference can be used immediately in a powerpc }
|
||||||
{ instruction }
|
{ instruction }
|
||||||
function issimpleref(const ref: treference): boolean;
|
function issimpleref(const ref: treference): boolean;
|
||||||
@ -1397,7 +1387,8 @@ var
|
|||||||
{ there are two ways to do this: manually, by generating a few "std" instructions,
|
{ there are two ways to do this: manually, by generating a few "std" instructions,
|
||||||
or via the restore helper functions. The latter are selected by the -Og switch,
|
or via the restore helper functions. The latter are selected by the -Og switch,
|
||||||
i.e. "optimize for size" }
|
i.e. "optimize for size" }
|
||||||
if (cs_opt_size in current_settings.optimizerswitches) then begin
|
if (cs_opt_size in current_settings.optimizerswitches) and
|
||||||
|
(target_info.system <> system_powerpc64_darwin) then begin
|
||||||
mayNeedLRStore := false;
|
mayNeedLRStore := false;
|
||||||
if ((fprcount > 0) and (gprcount > 0)) then begin
|
if ((fprcount > 0) and (gprcount > 0)) then begin
|
||||||
a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
|
a_op_const_reg_reg(list, OP_SUB, OS_INT, 8 * fprcount, NR_R1, NR_R12);
|
||||||
@ -1450,10 +1441,10 @@ begin
|
|||||||
{ determine whether we need to save the link register }
|
{ determine whether we need to save the link register }
|
||||||
needslinkreg :=
|
needslinkreg :=
|
||||||
not(nostackframe) and
|
not(nostackframe) and
|
||||||
(((not (po_assembler in current_procinfo.procdef.procoptions)) and
|
(save_lr_in_prologue or
|
||||||
((pi_do_call in current_procinfo.flags) or (cs_profile in init_settings.moduleswitches))) or
|
((cs_opt_size in current_settings.optimizerswitches) and
|
||||||
((cs_opt_size in current_settings.optimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
|
((fprcount > 0) or
|
||||||
([cs_lineinfo, cs_debuginfo] * current_settings.moduleswitches <> []));
|
(gprcount > 0))));
|
||||||
|
|
||||||
a_reg_alloc(list, NR_STACK_POINTER_REG);
|
a_reg_alloc(list, NR_STACK_POINTER_REG);
|
||||||
a_reg_alloc(list, NR_R0);
|
a_reg_alloc(list, NR_R0);
|
||||||
@ -1944,93 +1935,6 @@ begin
|
|||||||
(ref.offset = 0)));
|
(ref.offset = 0)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function tcgppc.load_got_symbol(list: TAsmList; symbol : string) : tregister;
|
|
||||||
var
|
|
||||||
l: tasmsymbol;
|
|
||||||
ref: treference;
|
|
||||||
symname : string;
|
|
||||||
begin
|
|
||||||
l:=current_asmdata.getasmsymbol(symbol);
|
|
||||||
reference_reset_symbol(ref,l,0);
|
|
||||||
ref.base := NR_R2;
|
|
||||||
ref.refaddr := addr_pic;
|
|
||||||
|
|
||||||
result := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
|
||||||
{$IFDEF EXTDEBUG}
|
|
||||||
list.concat(tai_comment.create(strpnew('loading got reference for ' + symbol)));
|
|
||||||
{$ENDIF EXTDEBUG}
|
|
||||||
// cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,result);
|
|
||||||
list.concat(taicpu.op_reg_ref(A_LD, result, ref));
|
|
||||||
end;
|
|
||||||
|
|
||||||
|
|
||||||
function tcgppc.fixref(list: TAsmList; var ref: treference): boolean;
|
|
||||||
var
|
|
||||||
tmpreg: tregister;
|
|
||||||
name : string;
|
|
||||||
begin
|
|
||||||
result := false;
|
|
||||||
{ Avoids recursion. }
|
|
||||||
if (ref.refaddr = addr_pic) then exit;
|
|
||||||
{$IFDEF EXTDEBUG}
|
|
||||||
list.concat(tai_comment.create(strpnew('fixref0 ' + ref2string(ref))));
|
|
||||||
{$ENDIF EXTDEBUG}
|
|
||||||
|
|
||||||
if (target_info.system = system_powerpc64_darwin) and
|
|
||||||
assigned(ref.symbol) and
|
|
||||||
(ref.symbol.bind = AB_EXTERNAL) then
|
|
||||||
begin
|
|
||||||
tmpreg := g_indirect_sym_load(list,ref.symbol.name);
|
|
||||||
if (ref.base = NR_NO) then
|
|
||||||
ref.base := tmpreg
|
|
||||||
else if (ref.index = NR_NO) then
|
|
||||||
ref.index := tmpreg
|
|
||||||
else
|
|
||||||
begin
|
|
||||||
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.base,tmpreg));
|
|
||||||
ref.base := tmpreg;
|
|
||||||
end;
|
|
||||||
ref.symbol := nil;
|
|
||||||
end;
|
|
||||||
|
|
||||||
{ if we have to create PIC, add the symbol to the TOC/GOT }
|
|
||||||
if (target_info.system <> system_powerpc64_darwin) and
|
|
||||||
(cs_create_pic in current_settings.moduleswitches) and
|
|
||||||
(assigned(ref.symbol)) then begin
|
|
||||||
tmpreg := load_got_symbol(list, ref.symbol.name);
|
|
||||||
if (ref.base = NR_NO) then
|
|
||||||
ref.base := tmpreg
|
|
||||||
else if (ref.index = NR_NO) then
|
|
||||||
ref.index := tmpreg
|
|
||||||
else begin
|
|
||||||
a_op_reg_reg_reg(list, OP_ADD, OS_ADDR, ref.base, tmpreg, tmpreg);
|
|
||||||
ref.base := tmpreg;
|
|
||||||
end;
|
|
||||||
ref.symbol := nil;
|
|
||||||
{$IFDEF EXTDEBUG}
|
|
||||||
list.concat(tai_comment.create(strpnew('fixref-pic ' + ref2string(ref))));
|
|
||||||
{$ENDIF EXTDEBUG}
|
|
||||||
end;
|
|
||||||
|
|
||||||
if (ref.base = NR_NO) then begin
|
|
||||||
ref.base := ref.index;
|
|
||||||
ref.index := NR_NO;
|
|
||||||
end;
|
|
||||||
if (ref.base <> NR_NO) and (ref.index <> NR_NO) and
|
|
||||||
((ref.offset <> 0) or assigned(ref.symbol)) then begin
|
|
||||||
result := true;
|
|
||||||
tmpreg := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
|
||||||
a_op_reg_reg_reg(list, OP_ADD, OS_ADDR, ref.base, ref.index, tmpreg);
|
|
||||||
ref.base := tmpreg;
|
|
||||||
ref.index := NR_NO;
|
|
||||||
end;
|
|
||||||
if (ref.index <> NR_NO) and (assigned(ref.symbol) or (ref.offset <> 0)) then
|
|
||||||
internalerror(2006010506);
|
|
||||||
{$IFDEF EXTDEBUG}
|
|
||||||
list.concat(tai_comment.create(strpnew('fixref1 ' + ref2string(ref))));
|
|
||||||
{$ENDIF EXTDEBUG}
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure tcgppc.a_load_store(list: TAsmList; op: tasmop; reg: tregister;
|
procedure tcgppc.a_load_store(list: TAsmList; op: tasmop; reg: tregister;
|
||||||
ref: treference);
|
ref: treference);
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ unit cpupi;
|
|||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
cutils,
|
cutils,aasmdata,
|
||||||
procinfo, cpuinfo, psub;
|
procinfo, cpuinfo, psub;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -43,6 +43,8 @@ type
|
|||||||
function calc_stackframe_size(numgpr, numfpr : longint): longint;
|
function calc_stackframe_size(numgpr, numfpr : longint): longint;
|
||||||
|
|
||||||
needs_frame_pointer : boolean;
|
needs_frame_pointer : boolean;
|
||||||
|
|
||||||
|
procedure allocate_got_register(list: TAsmList); override;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
@ -50,8 +52,8 @@ implementation
|
|||||||
uses
|
uses
|
||||||
globtype, globals, systems,
|
globtype, globals, systems,
|
||||||
cpubase, cgbase,
|
cpubase, cgbase,
|
||||||
aasmtai,aasmdata,
|
aasmtai,
|
||||||
tgobj,
|
tgobj,cgobj,
|
||||||
symconst, symsym, paramgr, symutil, symtable,
|
symconst, symsym, paramgr, symutil, symtable,
|
||||||
verbose;
|
verbose;
|
||||||
|
|
||||||
@ -111,6 +113,16 @@ begin
|
|||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure tppcprocinfo.allocate_got_register(list: TAsmList);
|
||||||
|
begin
|
||||||
|
if (target_info.system = system_powerpc64_darwin) and
|
||||||
|
(cs_create_pic in current_settings.moduleswitches) then
|
||||||
|
begin
|
||||||
|
got := cg.getaddressregister(list);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
cprocinfo := tppcprocinfo;
|
cprocinfo := tppcprocinfo;
|
||||||
end.
|
end.
|
||||||
|
@ -151,6 +151,8 @@ procedure tppcattreader.BuildReference(oper: tppcoperand);
|
|||||||
|
|
||||||
var
|
var
|
||||||
l: aint;
|
l: aint;
|
||||||
|
relsym: string;
|
||||||
|
asmsymtyp: tasmsymtype;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
Consume(AS_LPAREN);
|
Consume(AS_LPAREN);
|
||||||
@ -207,20 +209,50 @@ begin
|
|||||||
AS_ID:
|
AS_ID:
|
||||||
begin
|
begin
|
||||||
ReadSym(oper);
|
ReadSym(oper);
|
||||||
{ add a constant expression? }
|
case actasmtoken of
|
||||||
if (actasmtoken = AS_PLUS) then
|
AS_PLUS:
|
||||||
begin
|
begin
|
||||||
l := BuildConstExpression(true, true);
|
{ add a constant expression? }
|
||||||
case oper.opr.typ of
|
l:=BuildConstExpression(true,true);
|
||||||
OPR_CONSTANT:
|
case oper.opr.typ of
|
||||||
inc(oper.opr.val, l);
|
OPR_CONSTANT :
|
||||||
OPR_LOCAL:
|
inc(oper.opr.val,l);
|
||||||
inc(oper.opr.localsymofs, l);
|
OPR_LOCAL :
|
||||||
OPR_REFERENCE:
|
inc(oper.opr.localsymofs,l);
|
||||||
inc(oper.opr.ref.offset, l);
|
OPR_REFERENCE :
|
||||||
else
|
inc(oper.opr.ref.offset,l);
|
||||||
internalerror(200309202);
|
else
|
||||||
end;
|
internalerror(200309202);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
AS_MINUS:
|
||||||
|
begin
|
||||||
|
Consume(AS_MINUS);
|
||||||
|
BuildConstSymbolExpression(false,true,false,l,relsym,asmsymtyp);
|
||||||
|
if (relsym<>'') then
|
||||||
|
begin
|
||||||
|
if (oper.opr.typ = OPR_REFERENCE) then
|
||||||
|
oper.opr.ref.relsymbol:=current_asmdata.RefAsmSymbol(relsym)
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
Message(asmr_e_invalid_reference_syntax);
|
||||||
|
RecoverConsume(false);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
case oper.opr.typ of
|
||||||
|
OPR_CONSTANT :
|
||||||
|
dec(oper.opr.val,l);
|
||||||
|
OPR_LOCAL :
|
||||||
|
dec(oper.opr.localsymofs,l);
|
||||||
|
OPR_REFERENCE :
|
||||||
|
dec(oper.opr.ref.offset,l);
|
||||||
|
else
|
||||||
|
internalerror(2007092601);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
Consume(AS_RPAREN);
|
Consume(AS_RPAREN);
|
||||||
if actasmtoken = AS_AT then
|
if actasmtoken = AS_AT then
|
||||||
|
@ -66,7 +66,13 @@ unit cgppc;
|
|||||||
protected
|
protected
|
||||||
function get_darwin_call_stub(const s: string): tasmsymbol;
|
function get_darwin_call_stub(const s: string): tasmsymbol;
|
||||||
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
|
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
|
||||||
function fixref(list: TAsmList; var ref: treference): boolean; virtual; abstract;
|
{ Make sure ref is a valid reference for the PowerPC and sets the }
|
||||||
|
{ base to the value of the index if (base = R_NO). }
|
||||||
|
{ Returns true if the reference contained a base, index and an }
|
||||||
|
{ offset or symbol, in which case the base will have been changed }
|
||||||
|
{ to a tempreg (which has to be freed by the caller) containing }
|
||||||
|
{ the sum of part of the original reference }
|
||||||
|
function fixref(list: TAsmList; var ref: treference): boolean;
|
||||||
{ contains the common code of a_load_reg_ref and a_load_ref_reg }
|
{ contains the common code of a_load_reg_ref and a_load_ref_reg }
|
||||||
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference);virtual;
|
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference);virtual;
|
||||||
|
|
||||||
@ -81,6 +87,8 @@ unit cgppc;
|
|||||||
function hasLargeOffset(const ref : TReference) : Boolean; inline;
|
function hasLargeOffset(const ref : TReference) : Boolean; inline;
|
||||||
|
|
||||||
function save_lr_in_prologue: boolean;
|
function save_lr_in_prologue: boolean;
|
||||||
|
|
||||||
|
function load_got_symbol(list : TAsmList; symbol : string) : tregister;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
const
|
||||||
@ -105,8 +113,10 @@ unit cgppc;
|
|||||||
function tcgppcgen.save_lr_in_prologue: boolean;
|
function tcgppcgen.save_lr_in_prologue: boolean;
|
||||||
begin
|
begin
|
||||||
result:=
|
result:=
|
||||||
((pi_do_call in current_procinfo.flags) or
|
(not (po_assembler in current_procinfo.procdef.procoptions) and
|
||||||
([cs_lineinfo,cs_debuginfo,cs_profile] * current_settings.moduleswitches <> []));
|
((pi_do_call in current_procinfo.flags) or
|
||||||
|
(cs_profile in init_settings.moduleswitches))) or
|
||||||
|
([cs_lineinfo,cs_debuginfo] * current_settings.moduleswitches <> []);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -168,7 +178,8 @@ unit cgppc;
|
|||||||
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) then
|
(pi_needs_got in current_procinfo.flags) then
|
||||||
case target_info.system of
|
case target_info.system of
|
||||||
system_powerpc_darwin:
|
system_powerpc_darwin,
|
||||||
|
system_powerpc64_darwin:
|
||||||
begin
|
begin
|
||||||
savedlr:=save_lr_in_prologue;
|
savedlr:=save_lr_in_prologue;
|
||||||
if not savedlr then
|
if not savedlr then
|
||||||
@ -185,7 +196,7 @@ unit cgppc;
|
|||||||
list.concat(taicpu.op_reg_reg(A_MFSPR,current_procinfo.got,NR_LR));
|
list.concat(taicpu.op_reg_reg(A_MFSPR,current_procinfo.got,NR_LR));
|
||||||
if not savedlr or
|
if not savedlr or
|
||||||
{ in the following case lr is saved, but not restored }
|
{ in the following case lr is saved, but not restored }
|
||||||
{ (happens e.g. when generating debug info for leaf }
|
{ (happens e.g. when generating debug info for leaf }
|
||||||
{ procedures) }
|
{ procedures) }
|
||||||
not(pi_do_call in current_procinfo.flags) then
|
not(pi_do_call in current_procinfo.flags) then
|
||||||
list.concat(taicpu.op_reg_reg(A_MTSPR,NR_LR,NR_R0));
|
list.concat(taicpu.op_reg_reg(A_MTSPR,NR_LR,NR_R0));
|
||||||
@ -687,6 +698,125 @@ unit cgppc;
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgppcgen.load_got_symbol(list: TAsmList; symbol : string) : tregister;
|
||||||
|
var
|
||||||
|
l: tasmsymbol;
|
||||||
|
ref: treference;
|
||||||
|
begin
|
||||||
|
if (target_info.system <> system_powerpc64_linux) then
|
||||||
|
internalerror(2007102010);
|
||||||
|
l:=current_asmdata.getasmsymbol(symbol);
|
||||||
|
reference_reset_symbol(ref,l,0);
|
||||||
|
ref.base := NR_R2;
|
||||||
|
ref.refaddr := addr_pic;
|
||||||
|
|
||||||
|
result := rg[R_INTREGISTER].getregister(list, R_SUBWHOLE);
|
||||||
|
{$IFDEF EXTDEBUG}
|
||||||
|
list.concat(tai_comment.create(strpnew('loading got reference for ' + symbol)));
|
||||||
|
{$ENDIF EXTDEBUG}
|
||||||
|
// cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,result);
|
||||||
|
|
||||||
|
{$ifdef cpu64bit}
|
||||||
|
list.concat(taicpu.op_reg_ref(A_LD, result, ref));
|
||||||
|
{$else cpu64bit}
|
||||||
|
list.concat(taicpu.op_reg_ref(A_LWZ, result, ref));
|
||||||
|
{$endif cpu64bit}
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgppcgen.fixref(list: TAsmList; var ref: treference): boolean;
|
||||||
|
var
|
||||||
|
tmpreg: tregister;
|
||||||
|
begin
|
||||||
|
result := false;
|
||||||
|
|
||||||
|
{ Avoid recursion. }
|
||||||
|
if (ref.refaddr = addr_pic) then
|
||||||
|
exit;
|
||||||
|
|
||||||
|
{$IFDEF EXTDEBUG}
|
||||||
|
list.concat(tai_comment.create(strpnew('fixref0 ' + ref2string(ref))));
|
||||||
|
{$ENDIF EXTDEBUG}
|
||||||
|
if (target_info.system in [system_powerpc_darwin,system_powerpc64_darwin]) and
|
||||||
|
assigned(ref.symbol) and
|
||||||
|
not assigned(ref.relsymbol) and
|
||||||
|
((ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
(cs_create_pic in current_settings.moduleswitches))then
|
||||||
|
begin
|
||||||
|
if (ref.symbol.bind = AB_EXTERNAL) or
|
||||||
|
((cs_create_pic in current_settings.moduleswitches) and
|
||||||
|
(ref.symbol.bind in [AB_COMMON,AB_GLOBAL])) then
|
||||||
|
begin
|
||||||
|
tmpreg := g_indirect_sym_load(list,ref.symbol.name);
|
||||||
|
ref.symbol:=nil;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
include(current_procinfo.flags,pi_needs_got);
|
||||||
|
tmpreg := current_procinfo.got;
|
||||||
|
if assigned(ref.relsymbol) then
|
||||||
|
internalerror(2007093501);
|
||||||
|
ref.relsymbol := current_procinfo.CurrGOTLabel;
|
||||||
|
end;
|
||||||
|
if (ref.base = NR_NO) then
|
||||||
|
ref.base := tmpreg
|
||||||
|
else if (ref.index = NR_NO) then
|
||||||
|
ref.index := tmpreg
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(A_ADD,tmpreg,ref.base,tmpreg));
|
||||||
|
ref.base := tmpreg;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ if we have to create PIC, add the symbol to the TOC/GOT }
|
||||||
|
if (target_info.system = system_powerpc64_linux) and
|
||||||
|
(cs_create_pic in current_settings.moduleswitches) and
|
||||||
|
(assigned(ref.symbol)) then
|
||||||
|
begin
|
||||||
|
tmpreg := load_got_symbol(list, ref.symbol.name);
|
||||||
|
if (ref.base = NR_NO) then
|
||||||
|
ref.base := tmpreg
|
||||||
|
else if (ref.index = NR_NO) then
|
||||||
|
ref.index := tmpreg
|
||||||
|
else begin
|
||||||
|
a_op_reg_reg_reg(list, OP_ADD, OS_ADDR, ref.base, tmpreg, tmpreg);
|
||||||
|
ref.base := tmpreg;
|
||||||
|
end;
|
||||||
|
ref.symbol := nil;
|
||||||
|
{$IFDEF EXTDEBUG}
|
||||||
|
list.concat(tai_comment.create(strpnew('fixref-pic ' + ref2string(ref))));
|
||||||
|
{$ENDIF EXTDEBUG}
|
||||||
|
end;
|
||||||
|
|
||||||
|
if (ref.base = NR_NO) then
|
||||||
|
begin
|
||||||
|
ref.base := ref.index;
|
||||||
|
ref.index := NR_NO;
|
||||||
|
end;
|
||||||
|
if (ref.base <> NR_NO) then
|
||||||
|
begin
|
||||||
|
if (ref.index <> NR_NO) and
|
||||||
|
((ref.offset <> 0) or assigned(ref.symbol)) then
|
||||||
|
begin
|
||||||
|
result := true;
|
||||||
|
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||||
|
list.concat(taicpu.op_reg_reg_reg(
|
||||||
|
A_ADD,tmpreg,ref.base,ref.index));
|
||||||
|
ref.index := NR_NO;
|
||||||
|
ref.base := tmpreg;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
if (ref.index <> NR_NO) and
|
||||||
|
(assigned(ref.symbol) or
|
||||||
|
(ref.offset <> 0)) then
|
||||||
|
internalerror(200208102);
|
||||||
|
{$IFDEF EXTDEBUG}
|
||||||
|
list.concat(tai_comment.create(strpnew('fixref1 ' + ref2string(ref))));
|
||||||
|
{$ENDIF EXTDEBUG}
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgppcgen.a_load_store(list:TAsmList;op: tasmop;reg:tregister;
|
procedure tcgppcgen.a_load_store(list:TAsmList;op: tasmop;reg:tregister;
|
||||||
ref: treference);
|
ref: treference);
|
||||||
|
|
||||||
|
@ -99,11 +99,21 @@ asm
|
|||||||
ori r4, r4, longint_to_real_helper@highera
|
ori r4, r4, longint_to_real_helper@highera
|
||||||
sldi r4, r4, 32
|
sldi r4, r4, 32
|
||||||
oris r4, r4, longint_to_real_helper@ha
|
oris r4, r4, longint_to_real_helper@ha
|
||||||
{$else darwin}
|
|
||||||
lis r4, longint_to_real_helper@ha
|
|
||||||
{$endif darwin}
|
|
||||||
lfd f4, longint_to_real_helper@l(r4)
|
lfd f4, longint_to_real_helper@l(r4)
|
||||||
|
{$else not darwin}
|
||||||
|
{$ifdef FPC_PIC}
|
||||||
|
mflr r0
|
||||||
|
bcl 20,31,.Lpiclab
|
||||||
|
.Lpiclab:
|
||||||
|
mflr r5
|
||||||
|
mtlr r0
|
||||||
|
addis r4,r5,(longint_to_real_helper-.Lpiclab)@ha
|
||||||
|
lfd f2,(longint_to_real_helper-.Lpiclab)@l(r4)
|
||||||
|
{$else FPC_PIC}
|
||||||
|
lis r4, longint_to_real_helper@ha
|
||||||
|
lfd f4, longint_to_real_helper@l(r4)
|
||||||
|
{$endif FPC_PIC}
|
||||||
|
{$endif not darwin}
|
||||||
rldicl r4,r3,32,32 // isolate high half
|
rldicl r4,r3,32,32 // isolate high half
|
||||||
rldicl r0,r3,0,32 // isolate low half
|
rldicl r0,r3,0,32 // isolate low half
|
||||||
std r4,temp1 // store dword both
|
std r4,temp1 // store dword both
|
||||||
@ -114,4 +124,4 @@ asm
|
|||||||
fcfid f0,f0 // fpu int (no rnd)
|
fcfid f0,f0 // fpu int (no rnd)
|
||||||
fmadd f0,f4,f2,f0 // (2**32)*high+low (only add can rnd)
|
fmadd f0,f4,f2,f0 // (2**32)*high+low (only add can rnd)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
{ %NORUN }
|
{ %NORUN }
|
||||||
{ %SKIPTARGET=macos }
|
{ %SKIPTARGET=macos }
|
||||||
|
|
||||||
|
{$ifdef darwin}
|
||||||
|
{$PIC+}
|
||||||
|
{$endif darwin}
|
||||||
|
|
||||||
{$ifdef CPUX86_64}
|
{$ifdef CPUX86_64}
|
||||||
{$ifndef WINDOWS}
|
{$ifndef WINDOWS}
|
||||||
{$PIC+}
|
{$PIC+}
|
||||||
@ -32,7 +36,7 @@ const
|
|||||||
procedure Test;export;
|
procedure Test;export;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
// writeln('Hoi');
|
writeln('Hoi');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
exports
|
exports
|
||||||
|
@ -1,6 +1,10 @@
|
|||||||
{ %NORUN }
|
{ %NORUN }
|
||||||
{ %SKIPTARGET=macos, win64 }
|
{ %SKIPTARGET=macos, win64 }
|
||||||
|
|
||||||
|
{$ifdef darwin}
|
||||||
|
{$PIC+}
|
||||||
|
{$endif darwin}
|
||||||
|
|
||||||
{$ifdef CPUX86_64}
|
{$ifdef CPUX86_64}
|
||||||
{$ifndef WINDOWS}
|
{$ifndef WINDOWS}
|
||||||
{$PIC+}
|
{$PIC+}
|
||||||
|
@ -2,6 +2,11 @@
|
|||||||
{ %cpu=x86_64,i386,powerpc,sparc}
|
{ %cpu=x86_64,i386,powerpc,sparc}
|
||||||
{ %skiptarget = go32v2,macos }
|
{ %skiptarget = go32v2,macos }
|
||||||
{ execute this test only on reasonable fast cpus }
|
{ execute this test only on reasonable fast cpus }
|
||||||
|
|
||||||
|
{$ifdef darwin}
|
||||||
|
{$PIC+}
|
||||||
|
{$endif darwin}
|
||||||
|
|
||||||
library lib;
|
library lib;
|
||||||
const
|
const
|
||||||
s =
|
s =
|
||||||
|
@ -4,6 +4,10 @@
|
|||||||
|
|
||||||
{$ifdef fpc}{$mode delphi}{$endif}
|
{$ifdef fpc}{$mode delphi}{$endif}
|
||||||
|
|
||||||
|
{$ifdef darwin}
|
||||||
|
{$PIC+}
|
||||||
|
{$endif darwin}
|
||||||
|
|
||||||
resourcestring
|
resourcestring
|
||||||
wurst = 'jo' deprecated;
|
wurst = 'jo' deprecated;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user