Browse Source

* PowerPC compiles again, several routines implemented in cgcpu.pas
* added constant to cpubase of alpha and powerpc for maximum
number of operands

Jonas Maebe 26 years ago
parent
commit
ec34af8955

+ 8 - 1
compiler/new/alpha/cpubase.pas

@@ -129,6 +129,8 @@ Const
   c_countusableregsfpu = 31;
   c_countusableregsmm  = 0;
 
+  max_operands = 4;
+
   registers_saved_on_cdecl = [R_9..R_14,R_F2..R_F9];
   maxvarregs = 6;
 
@@ -253,7 +255,12 @@ end;
 end.
 {
   $Log$
-  Revision 1.12  1999-08-06 16:04:08  michael
+  Revision 1.13  1999-08-06 16:41:10  jonas
+    * PowerPC compiles again, several routines implemented in cgcpu.pas
+    * added constant to cpubase of alpha and powerpc for maximum
+      number of operands
+
+  Revision 1.12  1999/08/06 16:04:08  michael
   + introduced tainstruction
 
   Revision 1.11  1999/08/06 15:53:52  florian

+ 382 - 0
compiler/new/powerpc/cgcpu.pas

@@ -0,0 +1,382 @@
+{
+    $Id$
+    Copyright (c) 1993-98 by Florian Klaempfl
+
+    This unit implements the code generator for the PowerPC
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+ ****************************************************************************
+}
+unit cgcpu;
+
+  interface
+
+    uses
+       cgbase,cgobj,aasm,cpuasm,cpubase,cpuinfo;
+
+    type
+       pcgppc = ^tcgppc;
+
+       tcgppc = object(tcg)
+          procedure a_push_reg(list : paasmoutput;r : tregister);virtual;
+          procedure a_call_name(list : paasmoutput;const s : string;
+            offset : longint);virtual;
+
+          procedure a_op_reg_const(list : paasmoutput; Op: TOpCG; size: TCGSize; reg: TRegister; a: AWord); virtual;
+
+          { move instructions }
+          procedure a_load_const_reg(list : paasmoutput; size: tcgsize; a : aword;reg : tregister);virtual;
+          procedure a_load_reg_ref(list : paasmoutput; size: tcgsize; reg : tregister;const ref2 : treference);virtual;
+          procedure a_load_ref_reg(list : paasmoutput;size : tcgsize;const Ref2 : treference;reg : tregister);virtual;
+          procedure a_load_reg_reg(list : paasmoutput;size : tcgsize;reg1,reg2 : tregister);virtual;
+
+          {  comparison operations }
+          procedure a_cmp_reg_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
+            l : pasmlabel);virtual;
+          procedure a_cmp_reg_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : pasmlabel);
+ {         procedure a_cmp_reg_ref_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg : tregister;
+              const ref: treference; l : pasmlabel);
+          procedure a_cmp_ref_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;l : longint;reg : tregister;
+            l : pasmlabel);}
+
+          procedure a_loadaddress_ref_reg(list : paasmoutput;const ref2 : treference;r : tregister);virtual;
+          procedure g_stackframe_entry(list : paasmoutput;localsize : longint);virtual;
+          procedure g_restore_frame_pointer(list : paasmoutput);virtual;
+
+
+          private
+
+          procedure a_op_reg_reg_const32(list: PAasmOutPut; OpLo, OpHi: TAsmOp;
+                                          reg1, reg2: TRegister; a: AWord);
+          procedure fixref(var ref: treference);
+       end;
+
+const
+          TOpCG2AsmOpLo: Array[TOpCG] of TAsmOp = (A_ADDI,A_ANDI_,A_DIVWU,
+                              A_DIVW,A_MULLW, A_MULLW, A_NONE,A_NONE,A_ORI,
+                              A_SRAWI,A_SLWI,A_SRWI,A_SUBI,A_XORI);
+          TOpCG2AsmOpHi: Array[TOpCG] of TAsmOp = (A_ADDIS,A_ANDIS_,
+                              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 TAsmCond = (C_EQ,C_GT,C_LT,C_GE,
+                           C_LE,C_NE,C_LE,C_NG,C_GE,C_NL);
+
+
+  implementation
+
+    uses
+       globtype,globals,verbose;
+
+     procedure tcgppc.a_push_reg(list : paasmoutput;r : tregister);
+       begin
+ { no in-procedure register pushing on the PowerPC                          }
+         internalerror(68995);
+       end;
+
+    procedure tcgppc.a_call_name(list : paasmoutput;const s : string;
+      offset : longint);
+
+      begin
+ { save our RTOC register value. Only necessary when doing pointer based    }
+ { calls or cross TOC calls, but currently done always                      }
+         list^.concat(new(paippc,op_reg_ref(A_STW,R_RTOC,
+           new_reference(stack_pointer,LA_RTOC))));
+         list^.concat(new(paippc,op_sym(A_BL,newasmsymbol(s))));
+         list^.concat(new(paippc,op_reg_ref(A_LWZ,R_RTOC,
+           new_reference(stack_pointer,LA_RTOC))));
+      end;
+
+{********************** load instructions ********************}
+
+     procedure tcgppc.a_load_const_reg(list : paasmoutput; size: TCGSize; a : aword; reg : TRegister);
+
+       begin
+          If (a and $ffff) <> 0 Then
+            Begin
+              list^.concat(new(paippc,op_reg_const(A_LI,reg,a and $ffff)));
+              If (a shr 16) <> 0 Then
+                list^.concat(new(paippc,op_reg_const(A_ORIS,reg,a shr 16)))
+            End
+          Else
+            list^.concat(new(paippc,op_reg_const(A_LIS,reg,a shr 16)));
+       end;
+
+       procedure tcgppc.a_load_reg_ref(list : paasmoutput; size: TCGSize; reg : tregister;const ref2 : treference);
+
+       Var
+         op: TAsmOp;
+         ref: TReference;
+
+         begin
+           ref := ref2;
+           FixRef(ref);
+           Case size of
+             OS_8 : op := A_STB;
+             OS_16: op := A_STH;
+             OS_32: op := A_STW;
+             Else InternalError(68993)
+           End;
+           list^.concat(new(paippc,op_reg_ref(op,reg,newreference(ref))));
+         End;
+
+     procedure tcgppc.a_load_ref_reg(list : paasmoutput;size : tcgsize;const ref2: treference;reg : tregister);
+
+     Var
+       op: TAsmOp;
+       ref: TReference;
+
+       begin
+         ref := ref2;
+         FixRef(ref);
+         Case size of
+           OS_8 : op := A_LBZ;
+           OS_16: op := A_LHZ;
+           OS_32: op := A_LWZ
+           Else InternalError(68994)
+         End;
+         list^.concat(new(paippc,op_reg_ref(op,reg,newreference(ref))));
+       end;
+
+     procedure tcgppc.a_load_reg_reg(list : paasmoutput;size : tcgsize;reg1,reg2 : tregister);
+
+       begin
+         list^.concat(new(paippc,op_reg_reg(A_MR,reg2,reg1)));
+       end;
+
+     procedure tcgppc.a_op_reg_const(list : paasmoutput; Op: TOpCG; size: TCGSize; reg: TRegister; a: AWord);
+
+     var scratch_register: TRegister;
+
+       begin
+         Case Op of
+           OP_DIV, OP_IDIV, OP_IMUL, OP_MUL:
+             If (Op = OP_IMUL) And (longint(a) >= -32768) And
+                (longint(a) <= 32767) Then
+               list^.concat(new(paippc,op_reg_reg_const(A_MULLI,reg,reg,a)))
+             Else
+               Begin
+                 scratch_register := get_scratch_reg(list);
+                 a_load_const_reg(list, OS_32, a, scratch_register);
+                 list^.concat(new(paippc,op_reg_reg_reg(TOpCG2AsmOpLo[Op],
+                   reg,reg,scratch_register)));
+                 free_scratch_reg(list,scratch_register);
+               End;
+           OP_ADD, OP_AND, OP_OR, OP_SUB,OP_XOR:
+             a_op_reg_reg_const32(list,TOpCG2AsmOpLo[Op],
+               TOpCG2AsmOpHi[Op],reg,reg,a);
+           OP_SHL,OP_SHR,OP_SAR:
+             Begin
+               if (a and $ffff) <> 0 Then
+                 list^.concat(new(paippc,op_reg_reg_const(
+                   TOpCG2AsmOpLo[Op],reg,reg,a and $ffff)));
+               If (a shr 16) <> 0 Then
+                 InternalError(68991);
+             End
+           Else InternalError(68992);
+         end;
+       end;
+
+
+{*************** compare instructructions ****************}
+
+      procedure tcgppc.a_cmp_reg_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;a : aword;reg : tregister;
+        l : pasmlabel);
+
+      var AsmCond: TAsmCond;
+          scratch_register: TRegister;
+          signed: boolean;
+
+        begin
+          signed := cmp_op in [OC_GT,OC_LT,OC_GTE,OC_LTE];
+          If signed Then
+            If (longint(a) >= -32768) and (longint(a) <= 32767) Then
+              list^.concat(new(paippc,op_const_reg_const(A_CMPI,0,reg,a)))
+            else
+              begin
+                scratch_register := get_scratch_reg(list);
+                a_load_const_reg(list,OS_32,a,scratch_register);
+                list^.concat(new(paippc,op_const_reg_reg(A_CMP,0,reg,scratch_register)));
+                free_scratch_reg(list,scratch_register);
+             end
+           else
+             if (a <= $ffff) then
+              list^.concat(new(paippc,op_const_reg_const(A_CMPLI,0,reg,a)))
+            else
+              begin
+                scratch_register := get_scratch_reg(list);
+                a_load_const_reg(list,OS_32,a,scratch_register);
+                list^.concat(new(paippc,op_const_reg_reg(A_CMPL,0,reg,scratch_register)));
+                free_scratch_reg(list,scratch_register);
+             end;
+           AsmCond := TOpCmp2AsmCond[cmp_op];
+           list^.concat(new(paippc,op_const_const_sym(A_BC,AsmCond2BO[AsmCond],
+             AsmCond2BI[AsmCond],newasmsymbol(l^.name))));
+        end;
+
+
+      procedure tcgppc.a_cmp_reg_reg_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;
+        reg1,reg2 : tregister;l : pasmlabel);
+
+      var AsmCond: TAsmCond;
+
+      begin
+        list^.concat(new(paippc,op_const_reg_reg(A_CMPL,0,reg1,reg2)));
+        AsmCond := TOpCmp2AsmCond[cmp_op];
+        list^.concat(new(paippc,op_const_const_sym(A_BC,AsmCond2BO[AsmCond],
+          AsmCond2BI[AsmCond],newasmsymbol(l^.name))));
+      end;
+{
+      procedure tcgpp.a_cmp_reg_ref_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;reg : tregister;
+        const ref: treference; l : pasmlabel);
+
+      var scratch_register: TRegister;
+
+      begin
+        scratch_register := get_scratch_reg(list);
+        a_load_ref_reg(list,ref,scratch_register);
+        a_cmp_reg_reg_label(list,size,cmp_op,reg,scratch_register,l)
+        free_scratch_reg(list,scratch_register);
+     end;
+
+      procedure tcgpp.a_cmp_ref_const_label(list : paasmoutput;size : tcgsize;cmp_op : topcmp;l : longint;reg : tregister;
+        l : pasmlabel);
+
+      var sr: TRegister;
+
+        begin
+          sr := get_scratch_register(list);
+
+          a_cmp
+}
+
+     procedure tcgppc.a_loadaddress_ref_reg(list : paasmoutput;const ref2 : treference;r : tregister);
+
+     Var
+       ref: TReference;
+
+       begin
+         ref := ref2;
+         FixRef(ref);
+         If ref.offset <> 0 Then
+           If ref.base <> R_NO then
+             a_op_reg_reg_const32(list,A_ADDI,A_ADDIS,r,r,ref.offset)
+  { FixRef makes sure that "(ref.index <> R_NO) and (ref.offset <> 0)" never}
+  { occurs, so now only ref.offset has to be loaded                         }
+           else a_load_const_reg(list, OS_32, ref.offset, r)
+         else
+           if ref.index <> R_NO Then
+             list^.concat(new(paippc,op_reg_reg_reg(A_ADD,r,ref.base,ref.index)))
+           else list^.concat(new(paippc,op_reg_reg(A_MR,r,ref.base)))
+       end;
+
+{ *********** entry/exit code and address loading ************ }
+
+    procedure tcgppc.g_stackframe_entry(list : paasmoutput;localsize : longint);
+ { generated the entry code of a procedure/function. Note: localsize is the }
+ { sum of the size necessary for local variables and the maximum possible   }
+ { combined size of ALL the parameters of a procedure called by the current }
+ { one                                                                      }
+     var scratch_register: TRegister;
+
+      begin
+        if (localsize mod 8) <> 0 then internalerror(58991);
+ { CR and LR only have to be saved in case they are modified by the current }
+ { procedure, but currently this isn't checked, so save them always         }
+        scratch_register := get_scratch_reg(list);
+        list^.concat(new(paippc,op_reg(A_MFCR,scratch_register)));
+        list^.concat(new(paippc,op_reg_ref(A_STW,scratch_register,
+          new_reference(stack_pointer,LA_CR))));
+        free_scratch_reg(list,scratch_register);
+        scratch_register := get_scratch_reg(list);
+        list^.concat(new(paippc,op_reg_reg(A_MFSPR,scratch_register,
+          R_LR)));
+        list^.concat(new(paippc,op_reg_ref(A_STW,scratch_register,
+          new_reference(stack_pointer,LA_LR))));
+        free_scratch_reg(list,scratch_register);
+{ if the current procedure is a leaf procedure, we can use the Red Zone,    }
+{ but this is not yet implemented                                           }
+{        if (procinfo.flags and pi_do_call) <> 0 Then}
+           Begin
+             if localsize<>0 then
+               begin
+ { allocate space for the local variable, parameter and linkage area and   }
+ { save the stack pointer at the end of the linkage area                   }
+                 if localsize <= $ffff Then
+                   list^.concat(new(paippc,op_reg_ref
+                     (A_STWU,stack_pointer, new_reference(stack_pointer,localsize+
+                      LinkageAreaSize))))
+                 else
+                   Begin
+                     scratch_register := get_scratch_reg(list);
+                     a_load_const_reg(list,OS_32,localsize,scratch_register);
+                     list^.concat(new(paippc,op_reg_reg_reg(A_STWUX,stack_pointer,
+                       stack_pointer,scratch_register)));
+                     free_scratch_reg(list,scratch_register);
+                  End;
+               End
+           End;
+       end;
+
+    procedure tcgppc.g_restore_frame_pointer(list : paasmoutput);
+
+      begin
+ { no frame pointer on the PowerPC                                          }
+      end;
+
+
+{***************** This is private property, keep out! :) *****************}
+
+    procedure tcgppc.fixref(var ref: treference);
+
+ { Make sure ref is a valid reference for the PowerPC and sets the base to  }
+ { the value of the index if (base = R_NO). (Index <> R_NO) is not checked  }
+ { because the less conditional jumps, the better                           }
+
+       begin
+         If (ref.base <> R_NO) and (ref.index <> R_NO) and
+            (ref.offset <> 0) Then Internalerror(58992);
+         if (ref.base = R_NO) Then
+           begin
+             ref.base := ref.index;
+             ref.index := R_NO
+           end
+       end;
+
+    procedure tcgppc.a_op_reg_reg_const32(list: PAasmOutput; OpLo, OpHi:
+                       TAsmOp; reg1, reg2: TRegister; a: AWord);
+ { Generates                                                                }
+ {   OpLo reg1, reg2, (a and $ffff) and/or                                  }
+ {   OpHi reg1, reg2, (a shr 16)                                            }
+ { depending on the value of a                                              }
+
+     Begin
+       if (a and $ffff) <> 0 Then
+         list^.concat(new(paippc,op_reg_reg_const(OpLo,reg1,reg2,a and $ffff)));
+       If (a shr 16) <> 0 Then
+         list^.concat(new(paippc,op_reg_reg_const(OpHi,reg1,reg2,a shr 16)))
+     End;
+
+end.
+{
+  $Log$
+  Revision 1.1  1999-08-06 16:41:11  jonas
+    * PowerPC compiles again, several routines implemented in cgcpu.pas
+    * added constant to cpubase of alpha and powerpc for maximum
+      number of operands
+
+
+}

+ 133 - 143
compiler/new/powerpc/cpuasm.pas

@@ -27,24 +27,12 @@ interface
 uses
   cobjects,
   aasm,globals,verbose,
-  cpubase;
+  cpubase, tainst;
 
 type
-  pairegalloc = ^tairegalloc;
-  tairegalloc = object(tai)
-     allocation : boolean;
-     reg        : tregister;
-     constructor alloc(r : tregister);
-     constructor dealloc(r : tregister);
-  end;
 
-  pappc = ^tappc;
-  tappc = object(tai)
-     is_jmp    : boolean; { is this instruction a jump? (needed for optimizer) }
-     opcode    : tasmop;
-     ops       : longint;
-     condition : TasmCond;
-     oper      : array[0..4] of toper;
+  paippc = ^taippc;
+  taippc = object(tainstruction)
 
      constructor op_none(op : tasmop);
 
@@ -61,7 +49,7 @@ type
      constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
      constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
      constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: pasmsymbol;_op3ofs: longint);
-     constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+     constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: preference);
      constructor op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
      constructor op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
 
@@ -74,7 +62,7 @@ type
 
      { this is for Jmp instructions }
      constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : pasmsymbol);
-     constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint);
+     constructor op_const_const_sym(op : tasmop;_op1,_op2 : longint;_op3: pasmsymbol);
 
 
      constructor op_sym(op : tasmop;_op1 : pasmsymbol);
@@ -82,262 +70,264 @@ type
      constructor op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:pasmsymbol;_op2ofs : longint);
      constructor op_sym_ofs_ref(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
 
+     procedure loadbool(opidx:longint;_b:boolean);
+
      destructor done;virtual;
-     function  getcopy:plinkedlist_item;virtual;
   private
-     segprefix : tregister;
-     procedure init(op : tasmop); { this need to be called by all constructor }
   end;
 
 
 implementation
 
 {*****************************************************************************
-                                 TaiRegAlloc
+                                 taippc Constructors
 *****************************************************************************}
 
-    constructor tairegalloc.alloc(r : tregister);
+    procedure taippc.loadbool(opidx:longint;_b:boolean);
       begin
-        inherited init;
-        typ:=ait_regalloc;
-        allocation:=true;
-        reg:=r;
+        if opidx>=ops then
+         ops:=opidx+1;
+        with oper[opidx] do
+         begin
+           if typ=top_ref then
+            disposereference(ref);
+           b:=_b;
+           typ:=top_bool;
+         end;
       end;
 
 
-    constructor tairegalloc.dealloc(r : tregister);
-      begin
-        inherited init;
-        typ:=ait_regalloc;
-        allocation:=false;
-        reg:=r;
-      end;
-
-
-{*****************************************************************************
-                                 tappc Constructors
-*****************************************************************************}
-
-    procedure tappc.init(op : tasmop);
-      begin
-         typ:=ait_instruction;
-         is_jmp:=false;
-         segprefix:=R_NO;
-         opcode:=op;
-         ops:=0;
-         condition:=c_none;
-         fillchar(oper,sizeof(oper),0);
-      end;
-
-    constructor tappc.op_none(op : tasmop);
+    constructor taippc.op_none(op : tasmop);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
       end;
 
 
-    constructor tappc.op_reg(op : tasmop;_op1 : tregister);
+    constructor taippc.op_reg(op : tasmop;_op1 : tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=1;
+         loadreg(0,_op1);
       end;
 
 
-    constructor tappc.op_const(op : tasmop;_op1 : longint);
+    constructor taippc.op_const(op : tasmop;_op1 : longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=1;
+         loadconst(0,_op1);
       end;
 
 
-    constructor tappc.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+    constructor taippc.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
       end;
 
-    constructor tappc.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
+    constructor taippc.op_reg_const(op:tasmop; _op1: tregister; _op2: longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadreg(0,_op1);
+         loadconst(1,_op2);
       end;
 
-     constructor tappc.op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
+     constructor taippc.op_const_reg(op:tasmop; _op1: longint; _op2: tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadconst(0,_op1);
+         loadreg(1,_op2);
       end;
 
 
-    constructor tappc.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
+    constructor taippc.op_reg_ref(op : tasmop;_op1 : tregister;_op2 : preference);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadreg(0,_op1);
+         loadref(1,_op2);
       end;
 
 
-    constructor tappc.op_const_const(op : tasmop;_op1,_op2 : longint);
+    constructor taippc.op_const_const(op : tasmop;_op1,_op2 : longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadconst(0,_op1);
+         loadconst(1,_op2);
       end;
 
 
-    constructor tappc.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+    constructor taippc.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
       end;
 
-     constructor tappc.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+     constructor taippc.op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
        begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadconst(2,_op3);
       end;
 
-     constructor tappc.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: pasmsymbol;_op3ofs: longint);
+     constructor taippc.op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: pasmsymbol;_op3ofs: longint);
        begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadsymbol(0,_op3,_op3ofs);
       end;
 
-     constructor tappc.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; _op3: Longint);
+     constructor taippc.op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister;  _op3: preference);
        begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadref(2,_op3);
       end;
 
-    constructor tappc.op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
+    constructor taippc.op_const_reg_reg(op : tasmop;_op1 : longint;_op2, _op3 : tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadconst(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
       end;
 
-     constructor tappc.op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
+     constructor taippc.op_const_reg_const(op : tasmop;_op1 : longint;_op2 : tregister;_op3 : longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadconst(0,_op1);
+         loadreg(1,_op2);
+         loadconst(2,_op3);
       end;
 
 
-     constructor tappc.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
+     constructor taippc.op_reg_reg_reg_reg(op : tasmop;_op1,_op2,_op3,_op4 : tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=4;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+         loadreg(3,_op4);
       end;
 
-     constructor tappc.op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
+     constructor taippc.op_reg_bool_reg_reg(op : tasmop;_op1: tregister;_op2:boolean;_op3,_op4:tregister);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=4;
+         loadreg(0,_op1);
+         loadbool(1,_op2);
+         loadreg(2,_op3);
+         loadreg(3,_op4);
       end;
 
-     constructor tappc.op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
+     constructor taippc.op_reg_bool_reg_const(op : tasmop;_op1: tregister;_op2:boolean;_op3:tregister;_op4: longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=4;
+         loadreg(0,_op1);
+         loadbool(0,_op2);
+         loadreg(0,_op3);
+         loadconst(0,_op4);
       end;
 
-     constructor tappc.op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
+     constructor taippc.op_reg_reg_const_const_const(op : tasmop;_op1,_op2 : tregister;_op3,_op4,_op5 : Longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=5;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadconst(2,_op3);
+         loadconst(3,_op4);
+         loadconst(4,_op5);
       end;
 
-    constructor tappc.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : pasmsymbol);
+    constructor taippc.op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : pasmsymbol);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          condition:=cond;
          ops:=1;
+         loadsymbol(0,_op1,0);
       end;
 
-     constructor tappc.op_const_const_sym(op : tasmop;_op1,_op2 : longint);
+     constructor taippc.op_const_const_sym(op : tasmop;_op1,_op2 : longint; _op3: pasmsymbol);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=3;
+         loadconst(0,_op1);
+         loadconst(1,_op2);
+         loadsymbol(2,_op3,0);
       end;
 
 
-    constructor tappc.op_sym(op : tasmop;_op1 : pasmsymbol);
+    constructor taippc.op_sym(op : tasmop;_op1 : pasmsymbol);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=1;
+         loadsymbol(0,_op1,0);
       end;
 
 
-    constructor tappc.op_sym_ofs(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint);
+    constructor taippc.op_sym_ofs(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=1;
+         loadsymbol(0,_op1,_op1ofs);
       end;
 
 
-     constructor tappc.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:pasmsymbol;_op2ofs : longint);
+     constructor taippc.op_reg_sym_ofs(op : tasmop;_op1 : tregister;_op2:pasmsymbol;_op2ofs : longint);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadreg(0,_op1);
+         loadsymbol(1,_op2,_op2ofs);
       end;
 
 
-    constructor tappc.op_sym_ofs_ref(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
+    constructor taippc.op_sym_ofs_ref(op : tasmop;_op1 : pasmsymbol;_op1ofs:longint;_op2 : preference);
       begin
-         inherited init;
-         init(op);
+         inherited init(op);
          ops:=2;
+         loadsymbol(0,_op1,_op1ofs);
+         loadref(1,_op2);
       end;
 
-    destructor tappc.done;
+    destructor taippc.done;
       var
         i : longint;
       begin
-          for i:=1 to ops do
-            if (oper[i-1].typ=top_ref) then
-              dispose(oper[i-1].ref);
+          for i:=ops-1 downto 0 do
+            if (oper[i].typ=top_ref) then
+              dispose(oper[i].ref);
         inherited done;
       end;
 
-    function tappc.getcopy:plinkedlist_item;
-      var
-        i : longint;
-        p : plinkedlist_item;
-      begin
-        p:=inherited getcopy;
-        { make a copy of the references }
-        for i:=1 to ops do
-         if (pappc(p)^.oper[i-1].typ=top_ref) then
-          begin
-            new(pappc(p)^.oper[i-1].ref);
-            pappc(p)^.oper[i-1].ref^:=oper[i-1].ref^;
-          end;
-        getcopy:=p;
-      end;
-
 end.
 {
   $Log$
-  Revision 1.2  1999-08-04 12:59:24  jonas
+  Revision 1.3  1999-08-06 16:41:11  jonas
+    * PowerPC compiles again, several routines implemented in cgcpu.pas
+    * added constant to cpubase of alpha and powerpc for maximum
+      number of operands
+
+  Revision 1.2  1999/08/04 12:59:24  jonas
     * all tokes now start with an underscore
     * PowerPC compiles!!
 

+ 51 - 21
compiler/new/powerpc/cpubase.pas

@@ -27,7 +27,7 @@ interface
 {$endif}
 
 uses
-  strings,cobjects,aasm;
+  strings,cobjects,aasm,cpuinfo;
 
 const
 { Size of the instruction table converted by nasmconv.pas }
@@ -95,7 +95,7 @@ type
     a_mcrfs, a_lcrxe, a_mfcr, a_mffs, a_maffs_, a_mfmsr, a_mfspr, a_mfsr,
     a_mfsrin, a_mftb, a_mtfcrf, a_a_mtfd0, a_mtfsb1, a_mtfsf, a_mtfsf_,
     a_mtfsfi, a_mtfsfi_, a_mtmsr, a_mtspr, a_mtsr, a_mtsrin, a_mulhw,
-    a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullh, a_mullw_, a_mullwo,
+    a_mulhw_, a_mulhwu, a_mulhwu_, a_mulli, a_mullw, a_mullw_, a_mullwo,
     a_mullwo_, a_nand, a_nand_, a_neg, a_neg_, a_nego, a_nego_, a_nor, a_nor_,
     a_or, a_or_, a_orc, a_orc_, a_ori, a_oris, a_rfi, a_rlwimi, a_rlwimi_,
     a_rlwinm, a_tlwinm_, a_rlwnm, a_sc, a_slw, a_slw_, a_sraw, a_sraw_,
@@ -115,11 +115,14 @@ type
     a_srwi, a_srwi_, a_clrlwi, a_clrlwi_, a_clrrwi, a_clrrwi_, a_clrslwi,
     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},
-    nop, a_li, a_la, a_mr, a_not, a_mtcr);
+    nop, a_li, a_lis, a_la, a_mr, a_not, a_mtcr);
 
   op2strtable=array[tasmop] of string[8];
 
+
+
 const
+
   firstop = low(tasmop);
   lastop  = high(tasmop);
 
@@ -132,6 +135,13 @@ type
   TAsmCond=(C_None,
     C_LT,C_LE,C_EQ,C_GE,C_GT,C_NL,C_NE,C_NG,C_SO,C_NS,C_UN,C_NU
   );
+
+const
+  AsmCond2BO: Array[TAsmCond] of Byte =
+    (0,12,4,12,4,12,4,4,4,12,4,12,4);
+  AsmCond2BI: Array[TAsmCond] of Byte =
+    (0,0,1,2,0,1,0,2,1,3,3,3,3);
+
 (*
   TAsmCondBO = (B_T,B_F,B_DNZ,B_DNZT,B_DNZF,B_DZ,B_DZT,B_DZF);
   TasmCondSuffix = (SU_NO,SU_A,SU_LR,SU_CTR,SU_L,SU_LA,SU_LRL,SU_CTRL);
@@ -274,7 +284,7 @@ type
   preference = ^treference;
   treference = packed record
      is_immediate : boolean; { is this used as reference or immediate }
-     base: tregister;
+     base, index: tregister;
      offset      : longint;
      symbol      : pasmsymbol;
      offsetfixup : longint;
@@ -287,7 +297,7 @@ type
 *****************************************************************************}
 
 type
-  toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
+  toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_bool);
 
   toper=record
     ot  : longint;
@@ -295,8 +305,9 @@ type
      top_none   : ();
      top_reg    : (reg:tregister);
      top_ref    : (ref:preference);
-     top_const  : (val:longint);
+     top_const  : (val:aword);
      top_symbol : (sym:pasmsymbol;symofs:longint);
+     top_bool  :  (b: boolean);
   end;
 
 
@@ -323,19 +334,19 @@ type
   tlocation = packed record
      case loc : tloc of
         LOC_MEM,LOC_REFERENCE : (reference : treference);
-        LOC_FPUREGISTER, LOC_CFPUREGISTER : (register: tregister);
-        LOC_MMREGISTER, LOC_CMMREGISTER : (register: tregister);
+        LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
+          LOC_REGISTER,LOC_CREGISTER : (
+            case longint of
+              1 : (registerlow,registerhigh : tregister);
+              { overlay a registerlow }
+              2 : (register : tregister);
+            );
+
         LOC_JUMP : ();
         LOC_FLAGS : (resflags : tresflags);
         LOC_INVALID : ();
 
         { segment in reference at the same place as in loc_register }
-        LOC_REGISTER,LOC_CREGISTER : (
-        case longint of
-          1 : (register,registerhigh : tregister);
-          { overlay a registerlow }
-          2 : (registerlow : tregister);
-        );
   end;
 
 
@@ -343,9 +354,6 @@ type
                                  Constants
 *****************************************************************************}
 
-{type
-  tcpuflags = (cf_registers64);}
-
 const
   availabletempregsint = [R_11..R_30];
   availabletempregsfpu = [R_F14..R_F31];
@@ -355,6 +363,8 @@ const
   c_countusableregsfpu = 32;
   c_countusableregsmm  = 32;
 
+  max_operands = 5;
+
   maxvarregs = 18;
 
   varregs : Array [1..maxvarregs] of Tregister =
@@ -365,14 +375,19 @@ const
   fpuregs = [R_F0..R_F31];
   mmregs = [R_M0..R_M31];
 
-  registers_saved_on_cdecl = [R_11..R_30];
+  cpuflags = [];
+
+  registers_saved_on_cdecl = [R_13..R_29];
 
   { generic register names }
   stack_pointer = R_1;
-  frame_pointer = R_31;
+  R_RTOC          = R_2;
+  frame_pointer = R_NO;
   self_pointer  = R_9;
   accumulator   = R_3;
-  scratchregister = R_0;
+  vmt_offset_reg = R_0;
+  max_scratch_regs = 3;
+  scratch_regs: Array[1..max_scratch_regs] of TRegister = (R_0,R_30,R_31);
 
 (*  cpuflags : set of tcpuflags = []; *)
 
@@ -380,6 +395,16 @@ const
   pointersize   = 4;
   extended_size = 8;
 
+  LinkageAreaSize = 24;
+ { offset in the linkage area for the saved stack pointer }
+  LA_SP = 0;
+ { offset in the linkage area for the saved conditional register}
+  LA_CR = 4;
+ { offset in the linkage area for the saved link register}
+  LA_LR = 8;
+ { offset in the linkage area for the saved RTOC register}
+  LA_RTOC = 20;
+
 {*****************************************************************************
                                   Helpers
 *****************************************************************************}
@@ -464,7 +489,12 @@ end;
 end.
 {
   $Log$
-  Revision 1.3  1999-08-05 14:58:18  florian
+  Revision 1.4  1999-08-06 16:41:12  jonas
+    * PowerPC compiles again, several routines implemented in cgcpu.pas
+    * added constant to cpubase of alpha and powerpc for maximum
+      number of operands
+
+  Revision 1.3  1999/08/05 14:58:18  florian
     * some fixes for the floating point registers
     * more things for the new code generator