Explorar o código

* SPARC calling mechanism almost OK (as in GCC./mppcsparc )

mazen %!s(int64=23) %!d(string=hai) anos
pai
achega
f97aa452bd

+ 4 - 3
compiler/ncgutil.pas

@@ -1315,7 +1315,6 @@ implementation
              { move register parameters which aren't regable into memory                                          }
              { we do this after init_paras because it saves some code in init_paras if parameters are in register }
              { instead in memory                                                                                  }
-{$IFNDEF SPARC}
              hp:=tparaitem(procinfo.procdef.para.first);
              while assigned(hp) do
                begin
@@ -1353,7 +1352,6 @@ implementation
                     end;
                   hp:=tparaitem(hp.next);
                end;
-{$ENDIF SPARC}
           end;
 
         if (not inlined) then
@@ -1848,7 +1846,10 @@ implementation
 end.
 {
   $Log$
-  Revision 1.57  2002-11-03 20:22:40  mazen
+  Revision 1.58  2002-11-10 19:07:45  mazen
+  * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+  Revision 1.57  2002/11/03 20:22:40  mazen
   * parameter handling updated
 
   Revision 1.56  2002/10/16 19:01:43  peter

+ 34 - 56
compiler/sparc/aasmcpu.pas

@@ -31,7 +31,6 @@ uses
 const
   MaxPrefixes=4;
 type
-  TOperandOrder=(op_intel,op_att);
   { alignment for operator }
   tai_align=class(tai_align_abstract)
  reg:tregister;
@@ -46,15 +45,13 @@ type
     constructor op_const(op:tasmop;_op1:aword);
     constructor op_ref(op:tasmop;const _op1:treference);
     constructor op_reg_reg(op:tasmop;_op1,_op2:tregister);
-    constructor op_reg_ref(op:tasmop;_op1:tregister;const _op2:treference);
+    constructor op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
     constructor op_reg_const(op:tasmop;_op1:tregister;_op2:aword);
     constructor op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
-    constructor op_ref_reg(op:tasmop;const _op1:treference;_op2:tregister);
- { this is only allowed if _op1 is an int value (_op1^.isintvalue=true) }
- constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
- constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
- constructor op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:tregister);
- constructor op_reg_ref_reg(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference;_op3:TRegister);
+    constructor op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
+    constructor op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
+    constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
+    constructor op_reg_const_reg(Op:TAsmOp;SrcReg:TRegister;value:aWord;DstReg:TRegister);
  constructor op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
  constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
 
@@ -72,7 +69,6 @@ type
   procedure loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
   procedure loadraddr(opidx:longint;rg1,rg2:TRegister);
   private
- FOperandOrder:TOperandOrder;
  procedure init(_size:topsize);{this need to be called by all constructor}
  public
      { the next will reset all instructions that can change in pass 2 }
@@ -80,7 +76,6 @@ type
      procedure ResetPass2;
      function  CheckIfValid:boolean;
      function  Pass1(offset:longint):longint;virtual;
-     procedure SetOperandOrder(order:TOperandOrder);
   private
      { next fields are filled in pass1, so pass2 is faster }
      insentry  : PInsEntry;
@@ -153,10 +148,7 @@ procedure taicpu.changeopsize(siz:topsize);
   end;
 procedure taicpu.init(_size:topsize);
   begin
-     { default order is att }
-     FOperandOrder:=op_att;
-     {segprefix:=R_NONE;}{This may be only for I386 architecture!}
-     opsize:=_size;
+    opsize:=_size;
   end;
 constructor taicpu.op_none(op:tasmop);
   begin
@@ -200,13 +192,16 @@ constructor taicpu.op_reg_const(op:tasmop;_op1:tregister; _op2:aword);
      loadreg(0,_op1);
      loadconst(1,_op2);
   end;
-constructor taicpu.op_reg_ref(op:tasmop;_op1:tregister;const _op2:treference);
+constructor taicpu.op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
   begin
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadreg(0,_op1);
-     loadref(1,_op2);
+    if not(Op in [A_STB..A_STDFQ])
+    then
+      fail;
+    inherited Create(Op);
+    init(_size);
+    ops:=2;
+    LoadReg(0,Reg);
+    LoadRef(1,Ref);
   end;
 constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
   begin
@@ -216,13 +211,16 @@ constructor taicpu.op_const_reg(op:tasmop;_op1:aword;_op2:tregister);
      loadconst(0,_op1);
      loadreg(1,_op2);
   end;
-constructor taicpu.op_ref_reg(op:tasmop;const _op1:treference;_op2:tregister);
+constructor TAiCpu.op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
 	begin
-		inherited create(op);
-		init(S_SW);
-		ops:=2;
-		loadref(0,_op1);
-		loadreg(1,_op2);
+    if not(Op in [A_JMPL,A_FLUSH,A_LDSB..A_LDDC,A_RETT,A_SWAP])
+    then
+      fail;
+		inherited Create(Op);
+		Init(S_SW);
+		Ops:=2;
+		LoadRef(0,Ref);
+		LoadReg(1,Reg);
 	end;
 constructor taicpu.op_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
   begin
@@ -241,23 +239,14 @@ constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
      loadreg(1,_op2);
      loadreg(2,_op3);
   end;
-CONSTRUCTOR taicpu.op_reg_const_reg(op:tasmop;_size:topsize;_op1:TRegister;_op2:aWord;_op3:TRegister);
-  BEGIN
-INHERITED create(op);
-init(_size);
-ops:=3;
-LoadReg(0,_op1);
-LoadConst(1,_op2);
-LoadReg(2,_op3);
-  END;
-constructor taicpu.op_reg_ref_reg(op:tasmop;_size:topsize;_op1:tregister;const _op2:treference;_op3:tregister);
+constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
   begin
-    inherited create(op);
-    init(_size);
+    inherited Create(Op);
+    Init(S_W);
     ops:=3;
-    LoadReg(0,_op1);
-    LoadRef(1,_op2);
-    LoadReg(2,_op3);
+    LoadReg(0,SrcReg);
+    LoadConst(1,Value);
+    LoadReg(2,DstReg);
   end;
 constructor taicpu.op_const_ref_reg(op:tasmop;_size:topsize;_op1:aword;const _op2:treference;_op3:tregister);
   begin
@@ -421,18 +410,6 @@ procedure taicpu.Swatoperands;
           end;
     end;
   end;
-
-
-procedure taicpu.SetOperandOrder(order:TOperandOrder);
-  begin
-    if FOperandOrder<>order then
-     begin
-       Swatoperands;
-       FOperandOrder:=order;
-     end;
-  end;
-
-
 { This check must be done with the operand in ATT order
   i.e.after swapping in the intel reader
   but before swapping in the NASM and TASM writers PM }
@@ -711,8 +688,6 @@ begin
   optimize }
   if (Insentry=nil) or ((InsEntry^.flags and IF_PASS2)<>0) then
    begin
- { We need intel style operands }
- SetOperandOrder(op_intel);
  { create the .ot fields }
  create_ot;
  { set the file postion }
@@ -1138,7 +1113,10 @@ procedure InitAsm;
 end.
 {
     $Log$
-    Revision 1.11  2002-11-06 11:31:24  mazen
+    Revision 1.12  2002-11-10 19:07:46  mazen
+    * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+    Revision 1.11  2002/11/06 11:31:24  mazen
     * op_reg_reg_reg don't need any more a TOpSize parameter
 
     Revision 1.10  2002/11/05 16:15:00  mazen

+ 5 - 2
compiler/sparc/cga.pas

@@ -122,7 +122,7 @@ procedure emit_reg_reg(i:tasmop;s:topsize;reg1,reg2:tregister);
   end;
 procedure emit_const_reg_reg(i:tasmop;s:topsize;c:longint;reg1,reg2:tregister);
   begin
-    exprasmList.concat(Taicpu.Op_reg_const_reg(i,S_L,reg1,c,reg2));
+    exprasmList.concat(Taicpu.Op_reg_const_reg(i,reg1,c,reg2));
   end;
 procedure emit_reg_reg_reg(i:tasmop;s:topsize;reg1,reg2,reg3:tregister);
   begin
@@ -135,7 +135,10 @@ procedure emit_sym(i:tasmop;s:topsize;op:tasmsymbol);
 end.
 {
   $Log$
-  Revision 1.4  2002-11-06 11:31:24  mazen
+  Revision 1.5  2002-11-10 19:07:46  mazen
+  * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+  Revision 1.4  2002/11/06 11:31:24  mazen
   * op_reg_reg_reg don't need any more a TOpSize parameter
 
   Revision 1.3  2002/10/22 13:43:01  mazen

+ 11 - 9
compiler/sparc/cgcpu.pas

@@ -28,7 +28,6 @@ USES
   node,symconst;
 TYPE
   tcgSPARC=CLASS(tcg)
-    FreeParamRegSet:TRegisterSet;
 {This method is used to pass a parameter, which is located in a register, to a
 routine. It should give the parameter to the routine, as required by the
 specific processor ABI. It is overriden for each CPU target.
@@ -212,7 +211,7 @@ procedure tcgSPARC.a_load_const_reg(list:TAasmOutput;size:TCGSize;a:aword;reg:TR
     WITH List DO
       IF a<>0
       THEN{R_G0 is usually set to zero, so we use it}
-        Concat(taicpu.op_reg_const_reg(A_OR,TCGSize2OpSize[size],R_G0,a,reg))
+        Concat(taicpu.op_reg_const_reg(A_OR,R_G0,a,reg))
       ELSE{The is no A_MOV in sparc, that's why we use A_OR with help of R_G0}
         Concat(taicpu.op_reg_reg_reg(A_OR,R_G0,R_G0,reg));
   END;
@@ -668,7 +667,7 @@ procedure tcgSPARC.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegiste
                  ispowerof2(a,power) then
                 { can be done with a shift }
                 inherited a_op_const_reg_reg(list,op,size,a,src,dst);
-              list.concat(taicpu.op_reg_const_reg(A_SMUL,S_SW,src,a,dst));
+              list.concat(taicpu.op_reg_const_reg(A_SMUL,src,a,dst));
             end;
           OP_ADD, OP_SUB:
             if (a = 0) then
@@ -822,7 +821,7 @@ stack frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state
 before execution of the SAVE instrucion so it is the caller %i6, when the %i6
 after execution of that instruction is the called function stack pointer}
     with list do
-      concat(Taicpu.Op_reg_const_reg(A_SAVE,S_SW,Stack_Pointer_Reg,LocalSize,Stack_Pointer_Reg));
+      concat(Taicpu.Op_reg_const_reg(A_SAVE,Stack_Pointer_Reg,LocalSize,Stack_Pointer_Reg));
   end;
 procedure tcgSPARC.g_restore_frame_pointer(list:TAasmOutput);
   begin
@@ -847,7 +846,7 @@ If no inversion we can use just
         concat(Taicpu.Op_caddr_reg(A_JMPL,R_I7,8,R_G0));
 {We use trivial restore in the delay slot of the JMPL instruction, as we
 already set result onto %i0}
-        concat(Taicpu.Op_reg_const_reg(A_RESTORE,S_SW,R_G0,0,R_G0));
+        concat(Taicpu.Op_reg_const_reg(A_RESTORE,R_G0,0,R_G0));
       end
   end;
 procedure tcgSPARC.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);
@@ -1053,8 +1052,8 @@ procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;le
             { easy to notice in the generated assembler                     }
             inc(dst.offset,8);
             inc(src.offset,8);
-            list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,src.base,8,src.base));
-            list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,dst.base,8,dst.base));
+            list.concat(taicpu.op_reg_const_reg(A_SUB,src.base,8,src.base));
+            list.concat(taicpu.op_reg_const_reg(A_SUB,dst.base,8,dst.base));
             countreg := get_scratch_reg_int(list);
             a_load_const_reg(list,OS_32,count,countreg);
             { explicitely allocate R_O0 since it can be used safely here }
@@ -1062,7 +1061,7 @@ procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;le
             a_reg_alloc(list,R_F0);
             objectlibrary.getlabel(lab);
             a_label(list, lab);
-            list.concat(taicpu.op_reg_const_reg(A_SUB,S_SW,countreg,1,countreg));
+            list.concat(taicpu.op_reg_const_reg(A_SUB,countreg,1,countreg));
             list.concat(taicpu.op_reg_ref(A_LDF,R_F0,src));
             list.concat(taicpu.op_reg_ref(A_STD,R_F0,dst));
             //a_jmp(list,A_BC,C_NE,0,lab);
@@ -1254,7 +1253,10 @@ BEGIN
 END.
 {
   $Log$
-  Revision 1.22  2002-11-06 11:31:24  mazen
+  Revision 1.23  2002-11-10 19:07:46  mazen
+  * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+  Revision 1.22  2002/11/06 11:31:24  mazen
   * op_reg_reg_reg don't need any more a TOpSize parameter
 
   Revision 1.21  2002/11/05 16:15:00  mazen

+ 4 - 2
compiler/sparc/cpugas.pas

@@ -160,7 +160,6 @@ procedure TGasSPARC.WriteInstruction(hp:Tai);
 		if hp.typ<>ait_instruction
 		then
 			Exit;
-		taicpu(hp).SetOperandOrder(op_att);
 		op:=taicpu(hp).opcode;
 	 {call maybe not translated to call}
 		s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
@@ -210,7 +209,10 @@ initialization
 end.
 {
     $Log$
-    Revision 1.8  2002-10-25 19:37:53  mazen
+    Revision 1.9  2002-11-10 19:07:46  mazen
+    * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+    Revision 1.8  2002/10/25 19:37:53  mazen
     * bug of references name missing last character fixed
 
     Revision 1.7  2002/10/20 19:01:38  mazen

+ 7 - 4
compiler/sparc/cpupi.pas

@@ -72,9 +72,9 @@ procedure TSparcProcInfo.after_pass1;
     else
       procdef.localst.address_fixup:=6*4+(16+1)*4;
 		procinfo.firsttemp_offset:=procdef.localst.address_fixup+procdef.localst.datasize;
-	  WriteLn('Parameter copies start at: %i6-'+tostr(procdef.parast.address_fixup));
-		WriteLn('Locals start at: %o6-'+tostr(procdef.localst.address_fixup));
-	  WriteLn('Temp. space start: %o6-'+tostr(procinfo.firsttemp_offset));
+	  WriteLn('Parameter copies start at: %i6+'+tostr(procdef.parast.address_fixup));
+		WriteLn('Locals start at: %o6+'+tostr(procdef.localst.address_fixup));
+	  WriteLn('Temp. space start: %o6+'+tostr(procinfo.firsttemp_offset));
 		tg.firsttemp:=procinfo.firsttemp_offset;
 		tg.lasttemp:=procinfo.firsttemp_offset;
 	end;
@@ -83,7 +83,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.5  2002-11-03 20:22:40  mazen
+  Revision 1.6  2002-11-10 19:07:46  mazen
+  * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+  Revision 1.5  2002/11/03 20:22:40  mazen
   * parameter handling updated
 
   Revision 1.4  2002/10/20 19:01:38  mazen

+ 17 - 10
compiler/sparc/naddcpu.pas

@@ -122,7 +122,7 @@ procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
       begin
 {maybe we can reuse a constant register when the operation is a comparison that
 doesn't change the value of the register}
-        location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype IN [ltn,lten,gtn,gten,equaln,unequaln]));
+        location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
       end;
   end;
 procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extra_not,mboverflow:Boolean);
@@ -181,9 +181,10 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
               end
             ELSE IF(op=A_ADD)AND(right.location.loc=LOC_CONSTANT)AND(right.location.value=1)AND NOT(cs_check_overflow in aktlocalswitches)
             THEN
-              begin
-                emit_reg(A_INC,opsize,left.location.register);
-              end
+              with ExprAsmList,left.location do
+                begin
+                  concat(TAiCpu.op_reg_const_reg(A_ADD,register,1,register));
+                end
             ELSE IF(op=A_SUB)AND(right.location.loc=LOC_CONSTANT)AND(right.location.value=1)AND NOT(cs_check_overflow in aktlocalswitches)
             THEN
               begin
@@ -236,14 +237,17 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
 procedure TSparcAddNode.emit_op_right_left(op:TAsmOp);
   begin
     {left must be a register}
-    with exprasmlist do
-      case right.location.loc of
+    with left,location,exprasmlist do
+      case Right.Location.Loc of
         LOC_REGISTER,LOC_CREGISTER:
-          concat(taicpu.op_reg_reg_reg(op,right.location.register,left.location.register,left.location.register));
+          concat(taicpu.op_reg_reg_reg(op,Register,Right.Location.register,register));
         LOC_REFERENCE,LOC_CREFERENCE :
-          concat(taicpu.op_reg_ref_reg(op,S_W,left.location.register,right.location.reference,left.location.register));
+          begin
+            location_force_reg(exprasmlist,Right.Location,OS_32,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
+            concat(taicpu.op_reg_reg_reg(op,register,Right.Location.register,register));
+          end;
         LOC_CONSTANT:
-          concat(taicpu.op_reg_const_reg(op,S_W,left.location.register,right.location.value,left.location.register));
+          concat(taicpu.op_reg_const_reg(op,register,Right.Location.value,register));
         else
           InternalError(200203232);
       end;
@@ -404,7 +408,10 @@ begin
 end.
 {
     $Log$
-    Revision 1.8  2002-11-06 15:34:00  mazen
+    Revision 1.9  2002-11-10 19:07:46  mazen
+    * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+    Revision 1.8  2002/11/06 15:34:00  mazen
     *** empty log message ***
 
     Revision 1.7  2002/11/06 11:31:24  mazen

+ 12 - 9
compiler/sparc/ncpucnv.pas

@@ -236,13 +236,13 @@ implementation
             internalerror(200110012);
          end;
          tempreg := cg.get_scratch_reg_int(exprasmlist);
-         {$WARNING FIXME what reallty should be done?}
-         exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,S_L,tempreg,$4330,tempreg));
+         {$WARNING FIXME what really should be done?}
+         exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,tempreg,$4330,tempreg));
          cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
          cg.free_scratch_reg(exprasmlist,tempreg);
          if signed then
-         {$WARNING FIXME what reallty should be done?}
-           exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,S_L,leftreg,$8000,valuereg));
+         {$WARNING FIXME what really should be done?}
+           exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,leftreg,$8000,valuereg));
          inc(ref.offset,4);
          cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
          dec(ref.offset,4);
@@ -262,7 +262,7 @@ implementation
          tempconst.free;
 
          location.register := rg.getregisterfpu(exprasmlist);
-         {$WARNING FIXME what reallty should be done?}
+         {$WARNING FIXME what really should be done?}
          exprasmlist.concat(taicpu.op_reg_ref(A_LD,location.register,ref));
 
          tg.ungetiftemp(exprasmlist,ref);
@@ -273,7 +273,7 @@ implementation
 
          { work around bug in some PowerPC processors }
          if (tfloatdef(resulttype.def).typ = s32real) then
-         {$WARNING FIXME what reallty should be done?}
+         {$WARNING FIXME what really should be done?}
            exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
        end;
 
@@ -285,7 +285,7 @@ implementation
           { properly converted to singles                                   }
           if (tfloatdef(left.resulttype.def).typ = s64real) and
              (tfloatdef(resulttype.def).typ = s32real) then
-         {$WARNING FIXME what reallty should be done?}
+         {$WARNING FIXME what really should be done?}
             exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
        end;
 
@@ -323,7 +323,7 @@ implementation
                 else
                   hreg2 := left.location.register;
                 hreg1 := rg.getregisterint(exprasmlist);
-                exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,S_L,hreg1,1,
+                exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,hreg1,1,
                   hreg2));
                 exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,hreg1,hreg1,hreg2));
                 rg.ungetregister(exprasmlist,hreg2);
@@ -420,7 +420,10 @@ begin
 end.
 {
   $Log$
-  Revision 1.6  2002-11-06 11:31:24  mazen
+  Revision 1.7  2002-11-10 19:07:46  mazen
+  * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+
+  Revision 1.6  2002/11/06 11:31:24  mazen
   * op_reg_reg_reg don't need any more a TOpSize parameter
 
   Revision 1.5  2002/10/22 13:43:01  mazen