mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-08 03:48:07 +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 }
|
||||
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 }
|
||||
{ instruction }
|
||||
function issimpleref(const ref: treference): boolean;
|
||||
@ -1656,69 +1648,6 @@ const
|
||||
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 }
|
||||
{ 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;
|
||||
|
@ -107,16 +107,6 @@ type
|
||||
|
||||
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 }
|
||||
{ instruction }
|
||||
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,
|
||||
or via the restore helper functions. The latter are selected by the -Og switch,
|
||||
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;
|
||||
if ((fprcount > 0) and (gprcount > 0)) then begin
|
||||
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 }
|
||||
needslinkreg :=
|
||||
not(nostackframe) and
|
||||
(((not (po_assembler in current_procinfo.procdef.procoptions)) and
|
||||
((pi_do_call in current_procinfo.flags) or (cs_profile in init_settings.moduleswitches))) or
|
||||
((cs_opt_size in current_settings.optimizerswitches) and ((fprcount > 0) or (gprcount > 0))) or
|
||||
([cs_lineinfo, cs_debuginfo] * current_settings.moduleswitches <> []));
|
||||
(save_lr_in_prologue or
|
||||
((cs_opt_size in current_settings.optimizerswitches) and
|
||||
((fprcount > 0) or
|
||||
(gprcount > 0))));
|
||||
|
||||
a_reg_alloc(list, NR_STACK_POINTER_REG);
|
||||
a_reg_alloc(list, NR_R0);
|
||||
@ -1944,93 +1935,6 @@ begin
|
||||
(ref.offset = 0)));
|
||||
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;
|
||||
ref: treference);
|
||||
|
||||
|
@ -28,7 +28,7 @@ unit cpupi;
|
||||
interface
|
||||
|
||||
uses
|
||||
cutils,
|
||||
cutils,aasmdata,
|
||||
procinfo, cpuinfo, psub;
|
||||
|
||||
type
|
||||
@ -43,6 +43,8 @@ type
|
||||
function calc_stackframe_size(numgpr, numfpr : longint): longint;
|
||||
|
||||
needs_frame_pointer : boolean;
|
||||
|
||||
procedure allocate_got_register(list: TAsmList); override;
|
||||
end;
|
||||
|
||||
implementation
|
||||
@ -50,8 +52,8 @@ implementation
|
||||
uses
|
||||
globtype, globals, systems,
|
||||
cpubase, cgbase,
|
||||
aasmtai,aasmdata,
|
||||
tgobj,
|
||||
aasmtai,
|
||||
tgobj,cgobj,
|
||||
symconst, symsym, paramgr, symutil, symtable,
|
||||
verbose;
|
||||
|
||||
@ -111,6 +113,16 @@ begin
|
||||
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
|
||||
cprocinfo := tppcprocinfo;
|
||||
end.
|
||||
|
@ -151,6 +151,8 @@ procedure tppcattreader.BuildReference(oper: tppcoperand);
|
||||
|
||||
var
|
||||
l: aint;
|
||||
relsym: string;
|
||||
asmsymtyp: tasmsymtype;
|
||||
|
||||
begin
|
||||
Consume(AS_LPAREN);
|
||||
@ -207,20 +209,50 @@ begin
|
||||
AS_ID:
|
||||
begin
|
||||
ReadSym(oper);
|
||||
{ add a constant expression? }
|
||||
if (actasmtoken = AS_PLUS) then
|
||||
begin
|
||||
l := BuildConstExpression(true, true);
|
||||
case oper.opr.typ of
|
||||
OPR_CONSTANT:
|
||||
inc(oper.opr.val, l);
|
||||
OPR_LOCAL:
|
||||
inc(oper.opr.localsymofs, l);
|
||||
OPR_REFERENCE:
|
||||
inc(oper.opr.ref.offset, l);
|
||||
else
|
||||
internalerror(200309202);
|
||||
end;
|
||||
case actasmtoken of
|
||||
AS_PLUS:
|
||||
begin
|
||||
{ add a constant expression? }
|
||||
l:=BuildConstExpression(true,true);
|
||||
case oper.opr.typ of
|
||||
OPR_CONSTANT :
|
||||
inc(oper.opr.val,l);
|
||||
OPR_LOCAL :
|
||||
inc(oper.opr.localsymofs,l);
|
||||
OPR_REFERENCE :
|
||||
inc(oper.opr.ref.offset,l);
|
||||
else
|
||||
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;
|
||||
Consume(AS_RPAREN);
|
||||
if actasmtoken = AS_AT then
|
||||
|
@ -66,7 +66,13 @@ unit cgppc;
|
||||
protected
|
||||
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;
|
||||
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 }
|
||||
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 save_lr_in_prologue: boolean;
|
||||
|
||||
function load_got_symbol(list : TAsmList; symbol : string) : tregister;
|
||||
end;
|
||||
|
||||
const
|
||||
@ -105,8 +113,10 @@ unit cgppc;
|
||||
function tcgppcgen.save_lr_in_prologue: boolean;
|
||||
begin
|
||||
result:=
|
||||
((pi_do_call in current_procinfo.flags) or
|
||||
([cs_lineinfo,cs_debuginfo,cs_profile] * current_settings.moduleswitches <> []));
|
||||
(not (po_assembler in current_procinfo.procdef.procoptions) and
|
||||
((pi_do_call in current_procinfo.flags) or
|
||||
(cs_profile in init_settings.moduleswitches))) or
|
||||
([cs_lineinfo,cs_debuginfo] * current_settings.moduleswitches <> []);
|
||||
end;
|
||||
|
||||
|
||||
@ -168,7 +178,8 @@ unit cgppc;
|
||||
if (cs_create_pic in current_settings.moduleswitches) and
|
||||
(pi_needs_got in current_procinfo.flags) then
|
||||
case target_info.system of
|
||||
system_powerpc_darwin:
|
||||
system_powerpc_darwin,
|
||||
system_powerpc64_darwin:
|
||||
begin
|
||||
savedlr:=save_lr_in_prologue;
|
||||
if not savedlr then
|
||||
@ -185,7 +196,7 @@ unit cgppc;
|
||||
list.concat(taicpu.op_reg_reg(A_MFSPR,current_procinfo.got,NR_LR));
|
||||
if not savedlr or
|
||||
{ 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) }
|
||||
not(pi_do_call in current_procinfo.flags) then
|
||||
list.concat(taicpu.op_reg_reg(A_MTSPR,NR_LR,NR_R0));
|
||||
@ -687,6 +698,125 @@ unit cgppc;
|
||||
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;
|
||||
ref: treference);
|
||||
|
||||
|
@ -99,11 +99,21 @@ asm
|
||||
ori r4, r4, longint_to_real_helper@highera
|
||||
sldi r4, r4, 32
|
||||
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)
|
||||
|
||||
{$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 r0,r3,0,32 // isolate low half
|
||||
std r4,temp1 // store dword both
|
||||
@ -114,4 +124,4 @@ asm
|
||||
fcfid f0,f0 // fpu int (no rnd)
|
||||
fmadd f0,f4,f2,f0 // (2**32)*high+low (only add can rnd)
|
||||
end;
|
||||
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
{ %NORUN }
|
||||
{ %SKIPTARGET=macos }
|
||||
|
||||
{$ifdef darwin}
|
||||
{$PIC+}
|
||||
{$endif darwin}
|
||||
|
||||
{$ifdef CPUX86_64}
|
||||
{$ifndef WINDOWS}
|
||||
{$PIC+}
|
||||
@ -32,7 +36,7 @@ const
|
||||
procedure Test;export;
|
||||
|
||||
begin
|
||||
// writeln('Hoi');
|
||||
writeln('Hoi');
|
||||
end;
|
||||
|
||||
exports
|
||||
|
@ -1,6 +1,10 @@
|
||||
{ %NORUN }
|
||||
{ %SKIPTARGET=macos, win64 }
|
||||
|
||||
{$ifdef darwin}
|
||||
{$PIC+}
|
||||
{$endif darwin}
|
||||
|
||||
{$ifdef CPUX86_64}
|
||||
{$ifndef WINDOWS}
|
||||
{$PIC+}
|
||||
|
@ -2,6 +2,11 @@
|
||||
{ %cpu=x86_64,i386,powerpc,sparc}
|
||||
{ %skiptarget = go32v2,macos }
|
||||
{ execute this test only on reasonable fast cpus }
|
||||
|
||||
{$ifdef darwin}
|
||||
{$PIC+}
|
||||
{$endif darwin}
|
||||
|
||||
library lib;
|
||||
const
|
||||
s =
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
{$ifdef fpc}{$mode delphi}{$endif}
|
||||
|
||||
{$ifdef darwin}
|
||||
{$PIC+}
|
||||
{$endif darwin}
|
||||
|
||||
resourcestring
|
||||
wurst = 'jo' deprecated;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user