瀏覽代碼

- 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 -

Jonas Maebe 18 年之前
父節點
當前提交
359c19ee9e

+ 2 - 0
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}

+ 2 - 2
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

+ 1 - 55
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);

+ 1 - 1
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];

+ 8 - 4
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] = ('',

+ 1 - 1
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;

+ 0 - 60
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 }

+ 77 - 0
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.