mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 17:49:25 +02:00
- removed ppc601 as ppc32 cpu target
+ added ppc740 (g3), ppc7400 (G4) and ppc970 (G5) as ppc32 cpu targets * initialise optimizecputype by default to ppc7400 for ppc32 and to ppc970 for ppc64 * merged ppc32/ppc64 overflow checking code and use the ppc64 one in case cputype or optimizecputype >= ppc970, because one of the instructions used in the ppc32 version no longer exists on the ppc970 (although it's emulated in the kernel on at least Mac OS X) * moved some other support routines and constants to ppcgen which were needed for the overflow checking (were identical for ppc32 and ppc64) git-svn-id: trunk@6323 -
This commit is contained in:
parent
ccbee142bc
commit
359c19ee9e
@ -1169,10 +1169,12 @@ implementation
|
||||
{$endif m68k}
|
||||
{$ifdef powerpc}
|
||||
init_settings.cputype:=cpu_PPC604;
|
||||
init_settings.optimizecputype:=cpu_ppc7400;
|
||||
init_settings.fputype:=fpu_standard;
|
||||
{$endif powerpc}
|
||||
{$ifdef POWERPC64}
|
||||
init_settings.cputype:=cpu_PPC970;
|
||||
init_settings.optimizecputype:=cpu_ppc970;
|
||||
init_settings.fputype:=fpu_standard;
|
||||
{$endif POWERPC64}
|
||||
{$ifdef sparc}
|
||||
|
@ -93,7 +93,7 @@ const
|
||||
a_clrslwi_, a_none, a_none, a_none, a_none, a_none, a_none, a_none,
|
||||
a_none, a_none {move to special prupose reg}, a_none {move from special purpose reg},
|
||||
a_none, a_none, a_none, a_none, a_none, a_none, a_not, a_not_, a_none, a_none, a_none,
|
||||
a_none, a_none, a_none);
|
||||
a_none, a_none, a_none, a_none);
|
||||
|
||||
function TCpuAsmOptimizer.cmpi_mfcr_opt(p, next1, next2: taicpu): boolean;
|
||||
var
|
||||
@ -448,7 +448,7 @@ const
|
||||
a_clrslwi_, a_none, a_none, a_none, a_none, a_none, a_none, a_none,
|
||||
a_none, a_none {move to special prupose reg}, a_none {move from special purpose reg},
|
||||
a_none, a_none, a_none, a_none, a_mr_, a_mr_, a_not_, a_not_, a_none, a_none, a_none,
|
||||
a_none, a_none, a_none);
|
||||
a_none, a_none, a_none, a_none);
|
||||
|
||||
function changetomodifyflags(p: taicpu): boolean;
|
||||
begin
|
||||
|
@ -63,7 +63,7 @@ unit cgcpu;
|
||||
|
||||
procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
|
||||
tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
|
||||
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
|
||||
procedure a_load_subsetreg_subsetreg(list: TAsmlist; fromsubsetsize, tosubsetsize: tcgsize; const fromsreg, tosreg: tsubsetregister); override;
|
||||
|
||||
{ comparison operations }
|
||||
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
|
||||
@ -85,13 +85,10 @@ unit cgcpu;
|
||||
|
||||
procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
|
||||
|
||||
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
|
||||
{ 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 get_rlwi_const(a: aint; var l1, l2: longint): boolean;
|
||||
|
||||
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
|
||||
|
||||
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
|
||||
|
||||
protected
|
||||
@ -123,11 +120,6 @@ unit cgcpu;
|
||||
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;
|
||||
ref: treference); override;
|
||||
|
||||
{ creates the correct branch instruction for a given combination }
|
||||
{ of asmcondflags and destination addressing mode }
|
||||
procedure a_jmp(list: TAsmList; op: tasmop;
|
||||
c: tasmcondflag; crval: longint; l: tasmlabel);
|
||||
|
||||
function save_regs(list : TAsmList):longint;
|
||||
procedure restore_regs(list : TAsmList);
|
||||
end;
|
||||
@ -148,9 +140,6 @@ const
|
||||
A_DIVWU,A_DIVW, A_MULLW,A_MULLW,A_NONE,A_NONE,
|
||||
A_ORIS,A_NONE, A_NONE,A_NONE,A_SUBIS,A_XORIS);
|
||||
|
||||
TOpCmp2AsmCond: Array[topcmp] of TAsmCondFlag = (C_NONE,C_EQ,C_GT,
|
||||
C_LT,C_GE,C_LE,C_NE,C_LE,C_LT,C_GE,C_GT);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -769,13 +758,6 @@ const
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
|
||||
|
||||
begin
|
||||
a_jmp(list,A_BC,TOpCmp2AsmCond[cond],0,l);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.a_jmp_name(list : TAsmList;const s : string);
|
||||
var
|
||||
p : taicpu;
|
||||
@ -1794,28 +1776,6 @@ const
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef);
|
||||
var
|
||||
hl : tasmlabel;
|
||||
begin
|
||||
if not(cs_check_overflow in current_settings.localswitches) then
|
||||
exit;
|
||||
current_asmdata.getjumplabel(hl);
|
||||
if not ((def.typ=pointerdef) or
|
||||
((def.typ=orddef) and
|
||||
(torddef(def).ordtype in [u64bit,u16bit,u32bit,u8bit,uchar,
|
||||
bool8bit,bool16bit,bool32bit,bool64bit]))) then
|
||||
begin
|
||||
list.concat(taicpu.op_reg(A_MCRXR,NR_CR7));
|
||||
a_jmp(list,A_BC,C_NO,7,hl)
|
||||
end
|
||||
else
|
||||
a_jmp_cond(list,OC_AE,hl);
|
||||
a_call_name(list,'FPC_OVERFLOW');
|
||||
a_label(list,hl);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);
|
||||
|
||||
procedure loadvmttor11;
|
||||
@ -2116,20 +2076,6 @@ const
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.a_jmp(list: TAsmList; op: tasmop; c: tasmcondflag;
|
||||
crval: longint; l: tasmlabel);
|
||||
var
|
||||
p: taicpu;
|
||||
|
||||
begin
|
||||
p := taicpu.op_sym(op,l);
|
||||
if op <> A_B then
|
||||
create_cond_norm(c,crval,p.condition);
|
||||
p.is_jmp := true;
|
||||
list.concat(p)
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg64fppc.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
|
||||
begin
|
||||
a_op64_reg_reg_reg(list,op,size,regsrc,regdst,regdst);
|
||||
|
@ -84,7 +84,7 @@ uses
|
||||
a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove,
|
||||
a_crnot, a_mt {move to special prupose reg}, a_mf {move from special purpose reg},
|
||||
a_nop, a_li, a_lis, a_la, a_mr, a_mr_, a_not, a_not_, a_mtcr, a_mtlr, a_mflr,
|
||||
a_mtctr, a_mfctr, a_mftbu);
|
||||
a_mtctr, a_mfctr, a_mftbu, a_mfxer);
|
||||
|
||||
{# This should define the array of instructions as string }
|
||||
op2strtable=array[tasmop] of string[8];
|
||||
|
@ -32,8 +32,10 @@ Type
|
||||
{ possible supported processors for this target }
|
||||
tcputype =
|
||||
(cpu_none,
|
||||
cpu_ppc601,
|
||||
cpu_ppc604
|
||||
cpu_ppc604,
|
||||
cpu_ppc750,
|
||||
cpu_ppc7400,
|
||||
cpu_ppc970
|
||||
);
|
||||
|
||||
tfputype =
|
||||
@ -57,8 +59,10 @@ Const
|
||||
];
|
||||
|
||||
cputypestr : array[tcputype] of string[10] = ('',
|
||||
'603',
|
||||
'604'
|
||||
'604',
|
||||
'750',
|
||||
'7400',
|
||||
'970'
|
||||
);
|
||||
|
||||
fputypestr : array[tfputype] of string[8] = ('',
|
||||
|
@ -74,7 +74,7 @@ interface
|
||||
'srwi', 'srwi.', 'clrlwi', 'clrlwi.', 'clrrwi', 'clrrwi.', 'clrslwi',
|
||||
'clrslwi.', 'blr', 'bctr', 'blrl', 'bctrl', 'crset', 'crclr', 'crmove',
|
||||
'crnot', 'mt', 'mf','nop', 'li', 'lis', 'la', 'mr','mr.','not', 'not.',
|
||||
'mtcr', 'mtlr', 'mflr','mtctr', 'mfctr', 'mftbu');
|
||||
'mtcr', 'mtlr', 'mflr','mtctr', 'mfctr', 'mftbu', 'mfxer');
|
||||
|
||||
function gas_regnum_search(const s:string):Tregister;
|
||||
function gas_regname(r:Tregister):string;
|
||||
|
@ -99,10 +99,6 @@ type
|
||||
procedure g_concatcopy(list: TAsmList; const source, dest: treference;
|
||||
len: aint); override;
|
||||
|
||||
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef);
|
||||
override;
|
||||
procedure a_jmp_cond(list: TAsmList; cond: TOpCmp; l: tasmlabel);
|
||||
|
||||
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const
|
||||
labelname: string; ioffset: longint); override;
|
||||
private
|
||||
@ -129,11 +125,6 @@ type
|
||||
procedure a_load_store(list: TAsmList; op: tasmop; reg: tregister;
|
||||
ref: treference); override;
|
||||
|
||||
{ creates the correct branch instruction for a given combination }
|
||||
{ of asmcondflags and destination addressing mode }
|
||||
procedure a_jmp(list: TAsmList; op: tasmop;
|
||||
c: tasmcondflag; crval: longint; l: tasmlabel);
|
||||
|
||||
{ returns the lowest numbered FP register in use, and the number of used FP registers
|
||||
for the current procedure }
|
||||
procedure calcFirstUsedFPR(out firstfpr : TSuperRegister; out fprcount : aint);
|
||||
@ -169,9 +160,6 @@ const
|
||||
(A_SRAWI, A_SLWI, A_SRWI), (A_SRADI, A_SLDI, A_SRDI)
|
||||
);
|
||||
|
||||
TOpCmp2AsmCond: array[topcmp] of TAsmCondFlag = (C_NONE, C_EQ, C_GT,
|
||||
C_LT, C_GE, C_LE, C_NE, C_LE, C_LT, C_GE, C_GT);
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -1205,12 +1193,6 @@ begin
|
||||
a_jmp(list, A_BC, TOpCmp2AsmCond[cmp_op], 0, l);
|
||||
end;
|
||||
|
||||
procedure tcgppc.a_jmp_cond(list: TAsmList; cond: TOpCmp; l: tasmlabel);
|
||||
|
||||
begin
|
||||
a_jmp(list, A_BC, TOpCmp2AsmCond[cond], 0, l);
|
||||
end;
|
||||
|
||||
procedure tcgppc.a_jmp_name_direct(list : TAsmList; s : string; prependDot : boolean);
|
||||
var
|
||||
p: taicpu;
|
||||
@ -1859,35 +1841,6 @@ begin
|
||||
|
||||
end;
|
||||
|
||||
procedure tcgppc.g_overflowcheck(list: TAsmList; const l: tlocation; def:
|
||||
tdef);
|
||||
var
|
||||
hl: tasmlabel;
|
||||
flags : TResFlags;
|
||||
begin
|
||||
if not (cs_check_overflow in current_settings.localswitches) then
|
||||
exit;
|
||||
current_asmdata.getjumplabel(hl);
|
||||
if not ((def.typ = pointerdef) or
|
||||
((def.typ = orddef) and
|
||||
(torddef(def).ordtype in [u64bit, u16bit, u32bit, u8bit, uchar,
|
||||
bool8bit, bool16bit, bool32bit]))) then
|
||||
begin
|
||||
{ ... instructions setting overflow flag ...
|
||||
mfxerf R0
|
||||
mtcrf 128, R0
|
||||
ble cr0, label }
|
||||
list.concat(taicpu.op_reg(A_MFXER, NR_R0));
|
||||
list.concat(taicpu.op_const_reg(A_MTCRF, 128, NR_R0));
|
||||
flags.cr := RS_CR0;
|
||||
flags.flag := F_LE;
|
||||
a_jmp_flags(list, flags, hl);
|
||||
end else
|
||||
a_jmp_cond(list, OC_AE, hl);
|
||||
a_call_name(list, 'FPC_OVERFLOW');
|
||||
a_label(list, hl);
|
||||
end;
|
||||
|
||||
procedure tcgppc.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const
|
||||
labelname: string; ioffset: longint);
|
||||
|
||||
@ -2222,19 +2175,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tcgppc.a_jmp(list: TAsmList; op: tasmop; c: tasmcondflag;
|
||||
crval: longint; l: tasmlabel);
|
||||
var
|
||||
p: taicpu;
|
||||
|
||||
begin
|
||||
p := taicpu.op_sym(op, current_asmdata.RefAsmSymbol(l.name));
|
||||
if op <> A_B then
|
||||
create_cond_norm(c, crval, p.condition);
|
||||
p.is_jmp := true;
|
||||
list.concat(p)
|
||||
end;
|
||||
|
||||
function tcgppc.hasLargeOffset(const ref : TReference) : Boolean; {$ifdef ver2_0}inline;{$endif}
|
||||
begin
|
||||
{ this rather strange calculation is required because offsets of TReferences are unsigned }
|
||||
|
@ -50,15 +50,30 @@ unit cgppc;
|
||||
procedure a_loadfpu_ref_reg(list: TAsmList; fromsize, tosize: tcgsize; const ref: treference; reg: tregister); override;
|
||||
procedure a_loadfpu_reg_ref(list: TAsmList; fromsize, tosize: tcgsize; reg: tregister; const ref: treference); override;
|
||||
|
||||
{ overflow checking }
|
||||
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef);override;
|
||||
|
||||
{ entry code }
|
||||
procedure g_profilecode(list: TAsmList); override;
|
||||
|
||||
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
|
||||
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;
|
||||
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference);virtual;abstract;
|
||||
|
||||
{ creates the correct branch instruction for a given combination }
|
||||
{ of asmcondflags and destination addressing mode }
|
||||
procedure a_jmp(list: TAsmList; op: tasmop;
|
||||
c: tasmcondflag; crval: longint; l: tasmlabel);
|
||||
end;
|
||||
|
||||
const
|
||||
TOpCmp2AsmCond: Array[topcmp] of TAsmCondFlag = (C_NONE,C_EQ,C_GT,
|
||||
C_LT,C_GE,C_LE,C_NE,C_LE,C_LT,C_GE,C_GT);
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
@ -322,6 +337,45 @@ unit cgppc;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppcgen.g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef);
|
||||
var
|
||||
hl : tasmlabel;
|
||||
flags : TResFlags;
|
||||
begin
|
||||
if not(cs_check_overflow in current_settings.localswitches) then
|
||||
exit;
|
||||
current_asmdata.getjumplabel(hl);
|
||||
if not ((def.typ=pointerdef) or
|
||||
((def.typ=orddef) and
|
||||
(torddef(def).ordtype in [u64bit,u16bit,u32bit,u8bit,uchar,
|
||||
bool8bit,bool16bit,bool32bit,bool64bit]))) then
|
||||
begin
|
||||
if (current_settings.optimizecputype >= cpu_ppc970) or
|
||||
(current_settings.cputype >= cpu_ppc970) then
|
||||
begin
|
||||
{ ... instructions setting overflow flag ...
|
||||
mfxerf R0
|
||||
mtcrf 128, R0
|
||||
ble cr0, label }
|
||||
list.concat(taicpu.op_reg(A_MFXER, NR_R0));
|
||||
list.concat(taicpu.op_const_reg(A_MTCRF, 128, NR_R0));
|
||||
flags.cr := RS_CR0;
|
||||
flags.flag := F_LE;
|
||||
a_jmp_flags(list, flags, hl);
|
||||
end
|
||||
else
|
||||
begin
|
||||
list.concat(taicpu.op_reg(A_MCRXR,NR_CR7));
|
||||
a_jmp(list,A_BC,C_NO,7,hl)
|
||||
end;
|
||||
end
|
||||
else
|
||||
a_jmp_cond(list,OC_AE,hl);
|
||||
a_call_name(list,'FPC_OVERFLOW');
|
||||
a_label(list,hl);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppcgen.g_profilecode(list: TAsmList);
|
||||
var
|
||||
paraloc1 : tcgpara;
|
||||
@ -341,5 +395,28 @@ unit cgppc;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppcgen.a_jmp_cond(list : TAsmList;cond : TOpCmp; l: tasmlabel);
|
||||
begin
|
||||
a_jmp(list,A_BC,TOpCmp2AsmCond[cond],0,l);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppcgen.a_jmp(list: TAsmList; op: tasmop; c: tasmcondflag;
|
||||
crval: longint; l: tasmlabel);
|
||||
var
|
||||
p: taicpu;
|
||||
|
||||
begin
|
||||
p := taicpu.op_sym(op,l);
|
||||
if op <> A_B then
|
||||
create_cond_norm(c,crval,p.condition);
|
||||
p.is_jmp := true;
|
||||
list.concat(p)
|
||||
end;
|
||||
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user