Browse Source

- 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 years ago
parent
commit
359c19ee9e

+ 2 - 0
compiler/globals.pas

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

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

+ 1 - 55
compiler/powerpc/cgcpu.pas

@@ -63,7 +63,7 @@ unit cgcpu;
 
 
         procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
         procedure a_load_subsetreg_reg(list : TAsmList; subsetsize: tcgsize;
           tosize: tcgsize; const sreg: tsubsetregister; destreg: tregister); override;
           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 }
         {  comparison operations }
         procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
         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_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);

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

+ 8 - 4
compiler/powerpc/cpuinfo.pas

@@ -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] = ('',

+ 1 - 1
compiler/powerpc/itcpugas.pas

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

+ 0 - 60
compiler/powerpc64/cgcpu.pas

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

+ 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_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.