- 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:
Jonas Maebe 2007-02-03 19:32:44 +00:00
parent ccbee142bc
commit 359c19ee9e
8 changed files with 92 additions and 123 deletions

View File

@ -1169,10 +1169,12 @@ implementation
{$endif m68k} {$endif m68k}
{$ifdef powerpc} {$ifdef powerpc}
init_settings.cputype:=cpu_PPC604; init_settings.cputype:=cpu_PPC604;
init_settings.optimizecputype:=cpu_ppc7400;
init_settings.fputype:=fpu_standard; init_settings.fputype:=fpu_standard;
{$endif powerpc} {$endif powerpc}
{$ifdef POWERPC64} {$ifdef POWERPC64}
init_settings.cputype:=cpu_PPC970; init_settings.cputype:=cpu_PPC970;
init_settings.optimizecputype:=cpu_ppc970;
init_settings.fputype:=fpu_standard; init_settings.fputype:=fpu_standard;
{$endif POWERPC64} {$endif POWERPC64}
{$ifdef sparc} {$ifdef sparc}

View File

@ -93,7 +93,7 @@ const
a_clrslwi_, a_none, a_none, a_none, a_none, a_none, a_none, a_none, 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 {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_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; function TCpuAsmOptimizer.cmpi_mfcr_opt(p, next1, next2: taicpu): boolean;
var var
@ -448,7 +448,7 @@ const
a_clrslwi_, a_none, a_none, a_none, a_none, a_none, a_none, a_none, 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 {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_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; function changetomodifyflags(p: taicpu): boolean;
begin begin

View File

@ -85,13 +85,10 @@ unit cgcpu;
procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override; 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 } { 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 get_rlwi_const(a: aint; var l1, l2: longint): boolean; 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; procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
protected protected
@ -123,11 +120,6 @@ unit cgcpu;
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister; procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;
ref: treference); override; 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; function save_regs(list : TAsmList):longint;
procedure restore_regs(list : TAsmList); procedure restore_regs(list : TAsmList);
end; end;
@ -148,9 +140,6 @@ const
A_DIVWU,A_DIVW, A_MULLW,A_MULLW,A_NONE,A_NONE, A_DIVWU,A_DIVW, A_MULLW,A_MULLW,A_NONE,A_NONE,
A_ORIS,A_NONE, A_NONE,A_NONE,A_SUBIS,A_XORIS); 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 implementation
uses uses
@ -769,13 +758,6 @@ const
end; 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); procedure tcgppc.a_jmp_name(list : TAsmList;const s : string);
var var
p : taicpu; p : taicpu;
@ -1794,28 +1776,6 @@ const
end; 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 tcgppc.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);
procedure loadvmttor11; procedure loadvmttor11;
@ -2116,20 +2076,6 @@ const
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,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); procedure tcg64fppc.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
begin begin
a_op64_reg_reg_reg(list,op,size,regsrc,regdst,regdst); a_op64_reg_reg_reg(list,op,size,regsrc,regdst,regdst);

View File

@ -84,7 +84,7 @@ uses
a_clrslwi_, a_blr, a_bctr, a_blrl, a_bctrl, a_crset, a_crclr, a_crmove, 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_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_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 } {# This should define the array of instructions as string }
op2strtable=array[tasmop] of string[8]; op2strtable=array[tasmop] of string[8];

View File

@ -32,8 +32,10 @@ Type
{ possible supported processors for this target } { possible supported processors for this target }
tcputype = tcputype =
(cpu_none, (cpu_none,
cpu_ppc601, cpu_ppc604,
cpu_ppc604 cpu_ppc750,
cpu_ppc7400,
cpu_ppc970
); );
tfputype = tfputype =
@ -57,8 +59,10 @@ Const
]; ];
cputypestr : array[tcputype] of string[10] = ('', cputypestr : array[tcputype] of string[10] = ('',
'603', '604',
'604' '750',
'7400',
'970'
); );
fputypestr : array[tfputype] of string[8] = ('', fputypestr : array[tfputype] of string[8] = ('',

View File

@ -74,7 +74,7 @@ interface
'srwi', 'srwi.', 'clrlwi', 'clrlwi.', 'clrrwi', 'clrrwi.', 'clrslwi', 'srwi', 'srwi.', 'clrlwi', 'clrlwi.', 'clrrwi', 'clrrwi.', 'clrslwi',
'clrslwi.', 'blr', 'bctr', 'blrl', 'bctrl', 'crset', 'crclr', 'crmove', 'clrslwi.', 'blr', 'bctr', 'blrl', 'bctrl', 'crset', 'crclr', 'crmove',
'crnot', 'mt', 'mf','nop', 'li', 'lis', 'la', 'mr','mr.','not', 'not.', '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_regnum_search(const s:string):Tregister;
function gas_regname(r:Tregister):string; function gas_regname(r:Tregister):string;

View File

@ -99,10 +99,6 @@ type
procedure g_concatcopy(list: TAsmList; const source, dest: treference; procedure g_concatcopy(list: TAsmList; const source, dest: treference;
len: aint); override; 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 procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const
labelname: string; ioffset: longint); override; labelname: string; ioffset: longint); override;
private private
@ -129,11 +125,6 @@ type
procedure a_load_store(list: TAsmList; op: tasmop; reg: tregister; procedure a_load_store(list: TAsmList; op: tasmop; reg: tregister;
ref: treference); override; 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 { returns the lowest numbered FP register in use, and the number of used FP registers
for the current procedure } for the current procedure }
procedure calcFirstUsedFPR(out firstfpr : TSuperRegister; out fprcount : aint); 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) (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 implementation
uses uses
@ -1205,12 +1193,6 @@ begin
a_jmp(list, A_BC, TOpCmp2AsmCond[cmp_op], 0, l); a_jmp(list, A_BC, TOpCmp2AsmCond[cmp_op], 0, l);
end; 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); procedure tcgppc.a_jmp_name_direct(list : TAsmList; s : string; prependDot : boolean);
var var
p: taicpu; p: taicpu;
@ -1859,35 +1841,6 @@ begin
end; 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 procedure tcgppc.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const
labelname: string; ioffset: longint); labelname: string; ioffset: longint);
@ -2222,19 +2175,6 @@ begin
end; end;
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} function tcgppc.hasLargeOffset(const ref : TReference) : Boolean; {$ifdef ver2_0}inline;{$endif}
begin begin
{ this rather strange calculation is required because offsets of TReferences are unsigned } { this rather strange calculation is required because offsets of TReferences are unsigned }

View File

@ -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_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; 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 } { entry code }
procedure g_profilecode(list: TAsmList); override; procedure g_profilecode(list: TAsmList); override;
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
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; function fixref(list: TAsmList; var ref: treference): boolean; virtual; abstract;
procedure a_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference);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; 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 implementation
uses uses
@ -322,6 +337,45 @@ unit cgppc;
end; 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); procedure tcgppcgen.g_profilecode(list: TAsmList);
var var
paraloc1 : tcgpara; paraloc1 : tcgpara;
@ -341,5 +395,28 @@ unit cgppc;
end; end;
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. end.