From 359c19ee9ed10f8c4476e1fe64d10bee55c05c09 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sat, 3 Feb 2007 19:32:44 +0000 Subject: [PATCH] - 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 - --- compiler/globals.pas | 2 + compiler/powerpc/aoptcpu.pas | 4 +- compiler/powerpc/cgcpu.pas | 56 +------------------------ compiler/powerpc/cpubase.pas | 2 +- compiler/powerpc/cpuinfo.pas | 12 ++++-- compiler/powerpc/itcpugas.pas | 2 +- compiler/powerpc64/cgcpu.pas | 60 --------------------------- compiler/ppcgen/cgppc.pas | 77 +++++++++++++++++++++++++++++++++++ 8 files changed, 92 insertions(+), 123 deletions(-) diff --git a/compiler/globals.pas b/compiler/globals.pas index 5628c247eb..f3c706158b 100644 --- a/compiler/globals.pas +++ b/compiler/globals.pas @@ -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} diff --git a/compiler/powerpc/aoptcpu.pas b/compiler/powerpc/aoptcpu.pas index 7c118bb695..37aee7c047 100644 --- a/compiler/powerpc/aoptcpu.pas +++ b/compiler/powerpc/aoptcpu.pas @@ -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 diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index 6aaba68258..05a0bb08fb 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/compiler/powerpc/cgcpu.pas @@ -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); diff --git a/compiler/powerpc/cpubase.pas b/compiler/powerpc/cpubase.pas index 204c1c354c..6e18c909bd 100644 --- a/compiler/powerpc/cpubase.pas +++ b/compiler/powerpc/cpubase.pas @@ -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]; diff --git a/compiler/powerpc/cpuinfo.pas b/compiler/powerpc/cpuinfo.pas index 87ebb24f66..188812cabd 100644 --- a/compiler/powerpc/cpuinfo.pas +++ b/compiler/powerpc/cpuinfo.pas @@ -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] = ('', diff --git a/compiler/powerpc/itcpugas.pas b/compiler/powerpc/itcpugas.pas index 282c5ce1aa..48f487f7a9 100644 --- a/compiler/powerpc/itcpugas.pas +++ b/compiler/powerpc/itcpugas.pas @@ -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; diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas index 9bb7034cea..5ec515fcc3 100644 --- a/compiler/powerpc64/cgcpu.pas +++ b/compiler/powerpc64/cgcpu.pas @@ -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 } diff --git a/compiler/ppcgen/cgppc.pas b/compiler/ppcgen/cgppc.pas index f998531d44..9de0ed2151 100644 --- a/compiler/ppcgen/cgppc.pas +++ b/compiler/ppcgen/cgppc.pas @@ -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.