Przeglądaj źródła

* more sparc cleanup
* accumulator removed, splitted in function_return_reg (called) and
function_result_reg (caller)

peter 22 lat temu
rodzic
commit
414bd5fa22

+ 10 - 5
compiler/cgobj.pas

@@ -277,7 +277,7 @@ unit cgobj;
 
 
          {#
          {#
              This routine is used in exception management nodes. It should
              This routine is used in exception management nodes. It should
-             save the exception reason currently in the accumulator. The
+             save the exception reason currently in the FUNCTION_RETURN_REG. The
              save should be done either to a temp (pointed to by href).
              save should be done either to a temp (pointed to by href).
              or on the stack (pushing the value on the stack).
              or on the stack (pushing the value on the stack).
 
 
@@ -297,7 +297,7 @@ unit cgobj;
          procedure g_exception_reason_save_const(list : taasmoutput; const href : treference; a: aword);virtual;
          procedure g_exception_reason_save_const(list : taasmoutput; const href : treference; a: aword);virtual;
          {#
          {#
              This routine is used in exception management nodes. It should
              This routine is used in exception management nodes. It should
-             load the exception reason to the accumulator. The saved value
+             load the exception reason to the FUNCTION_RETURN_REG. The saved value
              should either be in the temp. area (pointed to by href , href should
              should either be in the temp. area (pointed to by href , href should
              *NOT* be freed) or on the stack (the value should be popped).
              *NOT* be freed) or on the stack (the value should be popped).
 
 
@@ -1645,7 +1645,7 @@ unit cgobj;
 
 
      begin
      begin
        r.enum:=R_INTREGISTER;;
        r.enum:=R_INTREGISTER;;
-       r.number:=NR_ACCUMULATOR;
+       r.number:=NR_FUNCTION_RETURN_REG;
        a_load_reg_ref(list, OS_S32, r, href);
        a_load_reg_ref(list, OS_S32, r, href);
      end;
      end;
 
 
@@ -1662,7 +1662,7 @@ unit cgobj;
 
 
      begin
      begin
        r.enum:=R_INTREGISTER;
        r.enum:=R_INTREGISTER;
-       r.number:=NR_ACCUMULATOR;
+       r.number:=NR_FUNCTION_RETURN_REG;
        a_load_ref_reg(list, OS_S32, href, r);
        a_load_ref_reg(list, OS_S32, href, r);
      end;
      end;
 
 
@@ -1691,7 +1691,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.102  2003-05-30 23:49:18  jonas
+  Revision 1.103  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.102  2003/05/30 23:49:18  jonas
     * a_load_loc_reg now has an extra size parameter for the destination
     * a_load_loc_reg now has an extra size parameter for the destination
       register (properly fixes what I worked around in revision 1.106 of
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)
       ncgutil.pas)

+ 21 - 22
compiler/i386/cpubase.inc

@@ -102,6 +102,7 @@
       max_scratch_regs = 1;
       max_scratch_regs = 1;
       scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
       scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
 {$endif}
 {$endif}
+
 {*****************************************************************************
 {*****************************************************************************
                                GDB Information
                                GDB Information
 *****************************************************************************}
 *****************************************************************************}
@@ -145,34 +146,27 @@
 *****************************************************************************}
 *****************************************************************************}
 
 
       {# Stack pointer register }
       {# Stack pointer register }
-      stack_pointer_reg = R_ESP;
       NR_STACK_POINTER_REG = NR_ESP;
       NR_STACK_POINTER_REG = NR_ESP;
       {# Frame pointer register }
       {# Frame pointer register }
-      frame_pointer_reg = R_EBP;
       NR_FRAME_POINTER_REG = NR_EBP;
       NR_FRAME_POINTER_REG = NR_EBP;
       {# Register for addressing absolute data in a position independant way,
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
       }
       }
-      pic_offset_reg = R_EBX;
-      {# Results are returned in this register (32-bit values) }
-      accumulator   = R_EAX;
-      RS_ACCUMULATOR   = RS_EAX;
-      NR_ACCUMULATOR   = NR_EAX;
-      { The return_result_reg is used inside the called function to store its return
-        value when that is a scalar value otherwise a pointer to the address of the
-        result is placed inside it}
-      return_result_reg = accumulator;
-      RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
-      NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
-
-      {the function_result_reg contains the function result after a call to a scalar
-      function othewise it contains a pointer to the returned result}
-        function_result_reg     =       accumulator;
-      {# Hi-Results are returned in this register (64-bit value high register) }
-      accumulatorhigh = R_EDX;
-      RS_ACCUMULATORHIGH  = RS_EDX;
-      NR_ACCUMULATORHIGH  = NR_EDX;
+      NR_PIC_OFFSET_REG = NR_EBX;
+      { Results are returned in this register (32-bit values) }
+      NR_FUNCTION_RETURN_REG = NR_EAX;
+      RS_FUNCTION_RETURN_REG = RS_EAX;
+      { High part of 64bit return value }
+      NR_FUNCTION_RETURNHIGH_REG = NR_EDX;
+      RS_FUNCTION_RETURNHIGH_REG = RS_EDX;
+      { The value returned from a function is available in this register }
+      NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
+      RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
+      { The high part of 64bit value returned from a function is available in this register }
+      NR_FUNCTION_RESULTHIGH_REG = NR_FUNCTION_RETURNHIGH_REG;
+      RS_FUNCTION_RESULTHIGH_REG = RS_FUNCTION_RETURNHIGH_REG;
+
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       fpu_result_reg = R_ST;
       fpu_result_reg = R_ST;
@@ -202,7 +196,12 @@
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2003-05-16 14:33:31  peter
+  Revision 1.4  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.3  2003/05/16 14:33:31  peter
     * regvar fixes
     * regvar fixes
 
 
   Revision 1.2  2002/04/25 16:12:09  florian
   Revision 1.2  2002/04/25 16:12:09  florian

+ 7 - 2
compiler/i386/cpupara.pas

@@ -60,7 +60,7 @@ unit cpupara;
         case target_info.system of
         case target_info.system of
           system_i386_win32 :
           system_i386_win32 :
             begin
             begin
-              { Win32 returns small records in the accumulator }
+              { Win32 returns small records in the FUNCTION_RETURN_REG }
               case def.deftype of
               case def.deftype of
                 recorddef :
                 recorddef :
                   begin
                   begin
@@ -133,7 +133,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.11  2003-05-13 15:16:13  peter
+  Revision 1.12  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.11  2003/05/13 15:16:13  peter
     * removed ret_in_acc, it's the reverse of ret_in_param
     * removed ret_in_acc, it's the reverse of ret_in_param
     * fixed ret_in_param for win32 cdecl array
     * fixed ret_in_param for win32 cdecl array
 
 

+ 10 - 5
compiler/i386/csopt386.pas

@@ -363,9 +363,9 @@ Begin {CheckSequence}
   OrgRegResult := False;
   OrgRegResult := False;
   with startRegInfo do
   with startRegInfo do
     begin
     begin
-      newRegsEncountered := [FRAME_POINTER_REG, STACK_POINTER_REG];
-      new2OldReg[FRAME_POINTER_REG].enum := FRAME_POINTER_REG;
-      new2OldReg[STACK_POINTER_REG].enum := STACK_POINTER_REG;
+      newRegsEncountered := [R_EBP, R_ESP];
+      new2OldReg[R_EBP].enum := R_EBP;
+      new2OldReg[R_ESP].enum := R_ESP;
       oldRegsEncountered := newRegsEncountered;
       oldRegsEncountered := newRegsEncountered;
     end;
     end;
 
 
@@ -1334,7 +1334,7 @@ begin
              (Taicpu(startmod).opcode = A_MOVSX) or
              (Taicpu(startmod).opcode = A_MOVSX) or
              (Taicpu(startmod).opcode = A_LEA)) and
              (Taicpu(startmod).opcode = A_LEA)) and
             (Taicpu(startmod).oper[0].typ = top_ref) and
             (Taicpu(startmod).oper[0].typ = top_ref) and
-            (Taicpu(startmod).oper[0].ref^.base.enum = STACK_POINTER_REG)) or
+            (Taicpu(startmod).oper[0].ref^.base.enum = R_ESP)) or
            not(reg.enum in pTaiprop(hp1.optInfo)^.usedRegs) or
            not(reg.enum in pTaiprop(hp1.optInfo)^.usedRegs) or
            findRegDealloc(reg,p))) then
            findRegDealloc(reg,p))) then
         pTaiprop(startMod.optInfo)^.canBeRemoved := true;
         pTaiprop(startMod.optInfo)^.canBeRemoved := true;
@@ -1997,7 +1997,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.45  2003-05-16 14:33:31  peter
+  Revision 1.46  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.45  2003/05/16 14:33:31  peter
     * regvar fixes
     * regvar fixes
 
 
   Revision 1.44  2003/04/27 11:21:35  peter
   Revision 1.44  2003/04/27 11:21:35  peter

+ 7 - 2
compiler/i386/n386cal.pas

@@ -197,7 +197,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.92  2003-05-26 21:17:18  peter
+  Revision 1.93  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.92  2003/05/26 21:17:18  peter
     * procinlinenode removed
     * procinlinenode removed
     * aktexit2label removed, fast exit removed
     * aktexit2label removed, fast exit removed
     + tcallnode.inlined_pass_2 added
     + tcallnode.inlined_pass_2 added
@@ -294,7 +299,7 @@ end.
     * old logs removed and tabs fixed
     * old logs removed and tabs fixed
 
 
   Revision 1.69  2002/09/01 18:43:27  peter
   Revision 1.69  2002/09/01 18:43:27  peter
-    * include accumulator in regs_to_push list
+    * include FUNCTION_RETURN_REG in regs_to_push list
 
 
   Revision 1.68  2002/09/01 12:13:00  peter
   Revision 1.68  2002/09/01 12:13:00  peter
     * use a_call_reg
     * use a_call_reg

+ 9 - 2
compiler/i386/popt386.pas

@@ -1376,7 +1376,9 @@ Begin
                              Taicpu(hp2).opcode := A_MOV;
                              Taicpu(hp2).opcode := A_MOV;
                              Taicpu(hp2).Loadoper(1,Taicpu(hp1).oper[0]);
                              Taicpu(hp2).Loadoper(1,Taicpu(hp1).oper[0]);
                              reference_reset_old(tmpref);
                              reference_reset_old(tmpref);
-                             tmpRef.base .enum:= STACK_POINTER_REG;
+                             tmpRef.base.enum:=R_INTREGISTER;
+                             tmpRef.base.number:=NR_STACK_POINTER_REG;
+                             convert_register_to_enum(tmpref.base);
                              tmpRef.offset := l;
                              tmpRef.offset := l;
                              Taicpu(hp2).loadRef(0,tmpRef);
                              Taicpu(hp2).loadRef(0,tmpRef);
                              hp4 := hp1;
                              hp4 := hp1;
@@ -2058,7 +2060,12 @@ End.
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.43  2003-04-27 11:21:35  peter
+  Revision 1.44  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.43  2003/04/27 11:21:35  peter
     * aktprocdef renamed to current_procdef
     * aktprocdef renamed to current_procdef
     * procinfo renamed to current_procinfo
     * procinfo renamed to current_procinfo
     * procinfo will now be stored in current_module so it can be
     * procinfo will now be stored in current_module so it can be

+ 12 - 4
compiler/i386/ra386att.pas

@@ -49,7 +49,8 @@ Implementation
        { parser }
        { parser }
        scanner,
        scanner,
        itx86att,
        itx86att,
-       rax86,rautils
+       rax86,rautils,
+       cginfo,cgobj
        ;
        ;
 
 
 type
 type
@@ -1402,6 +1403,8 @@ var
     end; { end case }
     end; { end case }
   end;
   end;
 
 
+const
+  regsize_2_size: array[S_B..S_L] of longint = (1,2,4);
 var
 var
   tempreg : tregister;
   tempreg : tregister;
   hl      : tasmlabel;
   hl      : tasmlabel;
@@ -1441,7 +1444,7 @@ Begin
          begin
          begin
            opr.typ:=OPR_REGISTER;
            opr.typ:=OPR_REGISTER;
            opr.reg:=actasmregister;
            opr.reg:=actasmregister;
-           size:=reg2opsize(actasmregister);
+           SetSize(regsize_2_size[reg2opsize(actasmregister)],true);
            Consume(AS_REGISTER);
            Consume(AS_REGISTER);
          end
          end
         else
         else
@@ -1594,7 +1597,7 @@ Begin
              Message(asmr_e_invalid_operand_type);
              Message(asmr_e_invalid_operand_type);
            opr.typ:=OPR_REGISTER;
            opr.typ:=OPR_REGISTER;
            opr.reg:=tempreg;
            opr.reg:=tempreg;
-           size:=reg2opsize(opr.reg);
+           SetSize(tcgsize2size[cg.reg_cgsize(opr.reg)],true);
          end
          end
         else
         else
          Message(asmr_e_syn_operand);
          Message(asmr_e_syn_operand);
@@ -2134,7 +2137,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.44  2003-05-22 21:32:29  peter
+  Revision 1.45  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.44  2003/05/22 21:32:29  peter
     * removed some unit dependencies
     * removed some unit dependencies
 
 
   Revision 1.43  2003/04/30 15:45:35  florian
   Revision 1.43  2003/04/30 15:45:35  florian

+ 15 - 10
compiler/i386/ra386int.pas

@@ -52,7 +52,7 @@ Implementation
        scanner,
        scanner,
        rautils,rax86,ag386int,
        rautils,rax86,ag386int,
        { codegen }
        { codegen }
-       cgbase
+       cginfo,cgbase,cgobj
        ;
        ;
 
 
 type
 type
@@ -1565,7 +1565,7 @@ Begin
             Message(asmr_e_invalid_operand_type);
             Message(asmr_e_invalid_operand_type);
            opr.typ:=OPR_REGISTER;
            opr.typ:=OPR_REGISTER;
            opr.reg:=tempreg;
            opr.reg:=tempreg;
-           size:=reg2opsize(opr.reg)
+           SetSize(tcgsize2size[cg.reg_cgsize(opr.reg)],true);
          end;
          end;
       end;
       end;
 
 
@@ -1620,7 +1620,7 @@ end;
 Procedure T386IntelInstruction.BuildOpCode;
 Procedure T386IntelInstruction.BuildOpCode;
 var
 var
   PrefixOp,OverrideOp: tasmop;
   PrefixOp,OverrideOp: tasmop;
-  size : topsize;
+  size : tcgsize;
   operandnum : longint;
   operandnum : longint;
 Begin
 Begin
   PrefixOp:=A_None;
   PrefixOp:=A_None;
@@ -1706,9 +1706,9 @@ Begin
           { load the size in a temp variable, so it can be set when the
           { load the size in a temp variable, so it can be set when the
             operand is read }
             operand is read }
           Case actasmtoken of
           Case actasmtoken of
-            AS_DWORD : size:=S_L;
-            AS_WORD  : size:=S_W;
-            AS_BYTE  : size:=S_B;
+            AS_DWORD : size:=OS_32;
+            AS_WORD  : size:=OS_16;
+            AS_BYTE  : size:=OS_8;
             AS_QWORD : begin
             AS_QWORD : begin
                           if (opcode=A_FCOM) or
                           if (opcode=A_FCOM) or
                             (opcode=A_FCOMP) or
                             (opcode=A_FCOMP) or
@@ -1721,11 +1721,11 @@ Begin
                             (opcode=A_FST) or
                             (opcode=A_FST) or
                             (opcode=A_FSTP) or
                             (opcode=A_FSTP) or
                             (opcode=A_FADD) then
                             (opcode=A_FADD) then
-                            size:=S_FL
+                            size:=OS_F64
                           else
                           else
-                            size:=S_IQ;
+                            size:=OS_64;
                        end;
                        end;
-            AS_TBYTE : size:=S_FX;
+            AS_TBYTE : size:=OS_F80;
           end;
           end;
           Consume(actasmtoken);
           Consume(actasmtoken);
           if actasmtoken=AS_PTR then
           if actasmtoken=AS_PTR then
@@ -1961,7 +1961,12 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-04-30 15:45:35  florian
+  Revision 1.48  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.47  2003/04/30 15:45:35  florian
     * merged more x86-64/i386 code
     * merged more x86-64/i386 code
 
 
   Revision 1.46  2003/04/27 11:21:35  peter
   Revision 1.46  2003/04/27 11:21:35  peter

+ 30 - 24
compiler/ncgcal.pas

@@ -426,7 +426,8 @@ implementation
           begin
           begin
             location_reset(location,LOC_CREFERENCE,OS_ADDR);
             location_reset(location,LOC_CREFERENCE,OS_ADDR);
             location.reference:=refcountedtemp;
             location.reference:=refcountedtemp;
-            r.enum:=accumulator;
+            r.enum:=R_INTREGISTER;
+            r.number:=NR_FUNCTION_RETURN_REG;
             cg.a_reg_alloc(exprasmlist,r);
             cg.a_reg_alloc(exprasmlist,r);
             cg.a_load_reg_ref(exprasmlist,OS_ADDR,r,location.reference);
             cg.a_load_reg_ref(exprasmlist,OS_ADDR,r,location.reference);
             cg.a_reg_dealloc(exprasmlist,r);
             cg.a_reg_dealloc(exprasmlist,r);
@@ -440,10 +441,10 @@ implementation
                 location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
                 location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
 {$ifdef cpufpemu}
 {$ifdef cpufpemu}
                 if cs_fp_emulation in aktmoduleswitches then
                 if cs_fp_emulation in aktmoduleswitches then
-                  location.register.enum := accumulator
-               else
+                  location.register.enum := FUNCTION_RESULT_REG
+                else
 {$endif cpufpemu}
 {$endif cpufpemu}
-                location.register.enum:=FPU_RESULT_REG;
+                  location.register.enum:=FPU_RESULT_REG;
 {$ifdef x86}
 {$ifdef x86}
                 inc(trgcpu(rg).fpuvaroffset);
                 inc(trgcpu(rg).fpuvaroffset);
 {$else x86}
 {$else x86}
@@ -466,26 +467,26 @@ implementation
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                    if cgsize in [OS_64,OS_S64] then
                    if cgsize in [OS_64,OS_S64] then
                     begin
                     begin
-                      {Move the function result to free registers, preferably the
-                       accumulator/accumulatorhigh, so no move is necessary.}
+                      { Move the function result to free registers, preferably the
+                        FUNCTION_RESULT_REG/FUNCTION_RESULTHIGH_REG, so no move is necessary.}
                       r.enum:=R_INTREGISTER;
                       r.enum:=R_INTREGISTER;
-                      r.number:=NR_ACCUMULATOR;
+                      r.number:=NR_FUNCTION_RESULT_REG;
                       hregister.enum:=R_INTREGISTER;
                       hregister.enum:=R_INTREGISTER;
-                      hregister.number:=NR_ACCUMULATORHIGH;
+                      hregister.number:=NR_FUNCTION_RESULTHIGH_REG;
 {$ifdef newra}
 {$ifdef newra}
-                      rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR);
-                      rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATORHIGH);
+                      rg.getexplicitregisterint(exprasmlist,NR_FUNCTION_RESULT_REG);
+                      rg.getexplicitregisterint(exprasmlist,NR_FUNCTION_RESULTHIGH_REG);
                       rg.ungetregisterint(exprasmlist,r);
                       rg.ungetregisterint(exprasmlist,r);
                       rg.ungetregisterint(exprasmlist,hregister);
                       rg.ungetregisterint(exprasmlist,hregister);
                       location.registerlow:=rg.getregisterint(exprasmlist,OS_INT);
                       location.registerlow:=rg.getregisterint(exprasmlist,OS_INT);
                       location.registerhigh:=rg.getregisterint(exprasmlist,OS_INT);
                       location.registerhigh:=rg.getregisterint(exprasmlist,OS_INT);
 {$else newra}
 {$else newra}
-                      if RS_ACCUMULATOR in rg.unusedregsint then
-                        location.registerlow:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATOR)
+                      if RS_FUNCTION_RESULT_REG in rg.unusedregsint then
+                        location.registerlow:=rg.getexplicitregisterint(exprasmlist,NR_FUNCTION_RESULT_REG)
                       else
                       else
                         cg.a_reg_alloc(exprasmlist,r);
                         cg.a_reg_alloc(exprasmlist,r);
-                      if RS_ACCUMULATORHIGH in rg.unusedregsint then
-                        location.registerhigh:=rg.getexplicitregisterint(exprasmlist,NR_ACCUMULATORHIGH)
+                      if RS_FUNCTION_RESULTHIGH_REG in rg.unusedregsint then
+                        location.registerhigh:=rg.getexplicitregisterint(exprasmlist,NR_FUNCTION_RETURNHIGH_REG)
                       else
                       else
                         cg.a_reg_alloc(exprasmlist,hregister);
                         cg.a_reg_alloc(exprasmlist,hregister);
                       { do this after both low,high are allocated, else it is possible that
                       { do this after both low,high are allocated, else it is possible that
@@ -502,8 +503,8 @@ implementation
 {$endif cpu64bit}
 {$endif cpu64bit}
                     begin
                     begin
                       {Move the function result to a free register, preferably the
                       {Move the function result to a free register, preferably the
-                       accumulator, so no move is necessary.}
-                      nr:=RS_ACCUMULATOR shl 8 or cgsize2subreg(cgsize);
+                       FUNCTION_RESULT_REG, so no move is necessary.}
+                      nr:=(RS_FUNCTION_RESULT_REG shl 8) or cgsize2subreg(cgsize);
                       r.enum:=R_INTREGISTER;
                       r.enum:=R_INTREGISTER;
                       r.number:=nr;
                       r.number:=nr;
 {$ifdef newra}
 {$ifdef newra}
@@ -512,7 +513,7 @@ implementation
                       location.register:=rg.getregisterint(exprasmlist,cgsize);
                       location.register:=rg.getregisterint(exprasmlist,cgsize);
 {$else newra}
 {$else newra}
                       cg.a_reg_alloc(exprasmlist,r);
                       cg.a_reg_alloc(exprasmlist,r);
-                      if RS_ACCUMULATOR in rg.unusedregsint then
+                      if RS_FUNCTION_RESULT_REG in rg.unusedregsint then
                         location.register:=rg.getexplicitregisterint(exprasmlist,nr)
                         location.register:=rg.getexplicitregisterint(exprasmlist,nr)
                       else
                       else
                         location.register:=rg.getregisterint(exprasmlist,cgsize);
                         location.register:=rg.getregisterint(exprasmlist,cgsize);
@@ -640,10 +641,10 @@ implementation
               if (not is_void(resulttype.def)) and
               if (not is_void(resulttype.def)) and
                  (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
                  (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
                begin
                begin
-                 include(regs_to_push_int,RS_ACCUMULATOR);
+                 include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                  if resulttype.def.size>sizeof(aword) then
                  if resulttype.def.size>sizeof(aword) then
-                   include(regs_to_push_int,RS_ACCUMULATORHIGH);
+                   include(regs_to_push_int,RS_FUNCTION_RESULTHIGH_REG);
 {$endif cpu64bit}
 {$endif cpu64bit}
                end;
                end;
               rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
               rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
@@ -1029,10 +1030,10 @@ implementation
          if (not is_void(resulttype.def)) and
          if (not is_void(resulttype.def)) and
             (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
             (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
           begin
           begin
-            include(regs_to_push_int,RS_ACCUMULATOR);
+            include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
             if resulttype.def.size>sizeof(aword) then
             if resulttype.def.size>sizeof(aword) then
-              include(regs_to_push_int,RS_ACCUMULATORHIGH);
+              include(regs_to_push_int,RS_FUNCTION_RESULTHIGH_REG);
 {$endif cpu64bit}
 {$endif cpu64bit}
           end;
           end;
          rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
          rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
@@ -1232,11 +1233,16 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.77  2003-05-29 10:05:40  jonas
+  Revision 1.78  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.77  2003/05/29 10:05:40  jonas
     * free callparatemps created for call-by-reference parameters
     * free callparatemps created for call-by-reference parameters
 
 
   Revision 1.76  2003/05/28 23:58:18  jonas
   Revision 1.76  2003/05/28 23:58:18  jonas
-    * added missing initialization of rg.usedint{in,by}proc
+    * added missing initialization of rg.usedintin,byproc
     * ppc now also saves/restores used fpu registers
     * ppc now also saves/restores used fpu registers
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
       i386
       i386
@@ -1478,7 +1484,7 @@ end.
     * several powerpc related stuff fixed
     * several powerpc related stuff fixed
 
 
   Revision 1.18  2002/09/01 18:43:27  peter
   Revision 1.18  2002/09/01 18:43:27  peter
-    * include accumulator in regs_to_push list
+    * include FUNCTION_RETURN_REG in regs_to_push list
 
 
   Revision 1.17  2002/09/01 12:13:00  peter
   Revision 1.17  2002/09/01 12:13:00  peter
     * use a_call_reg
     * use a_call_reg

+ 11 - 6
compiler/ncgflw.pas

@@ -893,7 +893,7 @@ implementation
       begin
       begin
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          r.enum:=R_INTREGISTER;
          r.enum:=R_INTREGISTER;
-         r.number:=NR_ACCUMULATOR;
+         r.number:=NR_FUNCTION_RESULT_REG;
          cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
          cg.a_param_reg(exprasmlist,OS_ADDR,r,paramanager.getintparaloc(1));
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
          cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
       end;
       end;
@@ -1021,7 +1021,7 @@ implementation
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
 
 
               r.enum:=R_INTREGISTER;
               r.enum:=R_INTREGISTER;
-              r.number:=NR_ACCUMULATOR;
+              r.number:=NR_FUNCTION_RESULT_REG;
               cg.a_param_reg(exprasmlist, OS_ADDR, r, paramanager.getintparaloc(1));
               cg.a_param_reg(exprasmlist, OS_ADDR, r, paramanager.getintparaloc(1));
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               cg.a_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               { we don't need to restore esi here because reraise never }
               { we don't need to restore esi here because reraise never }
@@ -1137,8 +1137,6 @@ implementation
       begin
       begin
          location_reset(location,LOC_VOID,OS_NO);
          location_reset(location,LOC_VOID,OS_NO);
 
 
-         r.enum:=R_INTREGISTER;
-         r.number:=NR_ACCUMULATOR;
          oldflowcontrol:=flowcontrol;
          oldflowcontrol:=flowcontrol;
          flowcontrol:=[];
          flowcontrol:=[];
          objectlibrary.getlabel(nextonlabel);
          objectlibrary.getlabel(nextonlabel);
@@ -1149,6 +1147,8 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
 
 
          { is it this catch? No. go to next onlabel }
          { is it this catch? No. go to next onlabel }
+         r.enum:=R_INTREGISTER;
+         r.number:=NR_FUNCTION_RESULT_REG;
          cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,r,nextonlabel);
          cg.a_cmp_const_reg_label(exprasmlist,OS_ADDR,OC_EQ,0,r,nextonlabel);
          ref.symbol:=nil;
          ref.symbol:=nil;
          tg.GetTemp(exprasmlist,pointer_size,tt_normal,ref);
          tg.GetTemp(exprasmlist,pointer_size,tt_normal,ref);
@@ -1329,7 +1329,7 @@ implementation
          { the value should now be in the exception handler }
          { the value should now be in the exception handler }
          cg.g_exception_reason_load(exprasmlist,href);
          cg.g_exception_reason_load(exprasmlist,href);
          r.enum:=R_INTREGISTER;
          r.enum:=R_INTREGISTER;
-         r.number:=NR_ACCUMULATOR;
+         r.number:=NR_FUNCTION_RESULT_REG;
          if implicitframe then
          if implicitframe then
            begin
            begin
              cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,r,endfinallylabel);
              cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,r,endfinallylabel);
@@ -1421,7 +1421,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.65  2003-05-30 18:55:21  jonas
+  Revision 1.66  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.65  2003/05/30 18:55:21  jonas
     * fixed several regvar related bugs for non-i386. make cycle with -Or now
     * fixed several regvar related bugs for non-i386. make cycle with -Or now
       works for ppc
       works for ppc
 
 

+ 8 - 3
compiler/ncgld.pas

@@ -146,14 +146,14 @@ implementation
                        if hregister.enum<>R_INTREGISTER then
                        if hregister.enum<>R_INTREGISTER then
                          internalerror(200301171);
                          internalerror(200301171);
                        { don't save the allocated register else the result will be destroyed later }
                        { don't save the allocated register else the result will be destroyed later }
-                       rg.saveusedintregisters(exprasmlist,pushed,[RS_ACCUMULATOR]-[hregister.number shr 8]);
+                       rg.saveusedintregisters(exprasmlist,pushed,[RS_FUNCTION_RESULT_REG]-[hregister.number shr 8]);
                        reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
                        reference_reset_symbol(href,objectlibrary.newasmsymboldata(tvarsym(symtableentry).mangledname),0);
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paramanager.getintparaloc(1));
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paramanager.getintparaloc(1));
                        { the called procedure isn't allowed to change }
                        { the called procedure isn't allowed to change }
                        { any register except EAX                    }
                        { any register except EAX                    }
                        cg.a_call_reg(exprasmlist,hregister);
                        cg.a_call_reg(exprasmlist,hregister);
                        r.enum:=R_INTREGISTER;
                        r.enum:=R_INTREGISTER;
-                       r.number:=NR_ACCUMULATOR;
+                       r.number:=NR_FUNCTION_RESULT_REG;
                        cg.a_load_reg_reg(exprasmlist,OS_INT,OS_ADDR,r,hregister);
                        cg.a_load_reg_reg(exprasmlist,OS_INT,OS_ADDR,r,hregister);
                        rg.restoreusedintregisters(exprasmlist,pushed);
                        rg.restoreusedintregisters(exprasmlist,pushed);
                        cg.a_label(exprasmlist,norelocatelab);
                        cg.a_label(exprasmlist,norelocatelab);
@@ -922,7 +922,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.63  2003-05-30 23:54:08  jonas
+  Revision 1.64  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.63  2003/05/30 23:54:08  jonas
     * forgot to commit, a_load_loc_reg change
     * forgot to commit, a_load_loc_reg change
 
 
   Revision 1.62  2003/05/26 19:38:28  peter
   Revision 1.62  2003/05/26 19:38:28  peter

+ 7 - 2
compiler/ncgset.pas

@@ -618,7 +618,7 @@ implementation
                   cg.a_call_name(exprasmlist,'FPC_SET_IN_BYTE');
                   cg.a_call_name(exprasmlist,'FPC_SET_IN_BYTE');
                   { result of value is always one full register }
                   { result of value is always one full register }
                   r.enum:=R_INTREGISTER;
                   r.enum:=R_INTREGISTER;
-                  r.number:=NR_ACCUMULATOR;
+                  r.number:=NR_FUNCTION_RESULT_REG;
                   cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,r,location.register);
                   cg.a_load_reg_reg(exprasmlist,OS_INT,OS_INT,r,location.register);
                   { release the allocated register  }
                   { release the allocated register  }
                   if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
                   if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
@@ -1121,7 +1121,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.37  2003-05-30 23:49:18  jonas
+  Revision 1.38  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.37  2003/05/30 23:49:18  jonas
     * a_load_loc_reg now has an extra size parameter for the destination
     * a_load_loc_reg now has an extra size parameter for the destination
       register (properly fixes what I worked around in revision 1.106 of
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)
       ncgutil.pas)

+ 29 - 23
compiler/ncgutil.pas

@@ -269,7 +269,7 @@ implementation
        cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
        cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
 
 
        r.enum:=R_INTREGISTER;
        r.enum:=R_INTREGISTER;
-       r.number:=NR_ACCUMULATOR;
+       r.number:=NR_FUNCTION_RESULT_REG;
        cg.a_param_reg(list,OS_ADDR,r,paramanager.getintparaloc(1));
        cg.a_param_reg(list,OS_ADDR,r,paramanager.getintparaloc(1));
        cg.a_call_name(list,'FPC_SETJMP');
        cg.a_call_name(list,'FPC_SETJMP');
 
 
@@ -290,7 +290,7 @@ implementation
           begin
           begin
             cg.g_exception_reason_load(list, href);
             cg.g_exception_reason_load(list, href);
             r.enum:=R_INTREGISTER;
             r.enum:=R_INTREGISTER;
-            r.number:=NR_ACCUMULATOR;
+            r.number:=NR_FUNCTION_RESULT_REG;
             cg.a_cmp_const_reg_label(list,OS_S32,OC_EQ,a,r,endexceptlabel);
             cg.a_cmp_const_reg_label(list,OS_S32,OC_EQ,a,r,endexceptlabel);
           end;
           end;
      end;
      end;
@@ -796,7 +796,8 @@ implementation
 {$endif GDB}
 {$endif GDB}
 
 
                   { this is the easiest case for inlined !! }
                   { this is the easiest case for inlined !! }
-                  r.enum:=stack_pointer_reg;
+                  r.enum:=R_INTREGISTER;
+                  r.number:=NR_STACK_POINTER_REG;
                   if calloption=pocall_inline then
                   if calloption=pocall_inline then
                    reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize)
                    reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize)
                   else
                   else
@@ -1229,7 +1230,7 @@ implementation
       end;
       end;
 
 
 
 
-    procedure handle_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
+    procedure load_return_value(list:TAAsmoutput; var uses_acc,uses_acchi,uses_fpu : boolean);
       var
       var
         href : treference;
         href : treference;
         hreg,r,r2 : tregister;
         hreg,r,r2 : tregister;
@@ -1240,7 +1241,7 @@ implementation
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            { Here, we return the function result. In most architectures, the value is
            { Here, we return the function result. In most architectures, the value is
-             passed into the accumulator, but in a windowed architecure like sparc a
+             passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
              function returns in a register and the caller receives it in an other one }
              function returns in a register and the caller receives it in an other one }
            case current_procdef.rettype.def.deftype of
            case current_procdef.rettype.def.deftype of
              orddef,
              orddef,
@@ -1248,14 +1249,14 @@ implementation
                begin
                begin
                  uses_acc:=true;
                  uses_acc:=true;
                  r.enum:=R_INTREGISTER;
                  r.enum:=R_INTREGISTER;
-                 r.number:=NR_RETURN_RESULT_REG;
+                 r.number:=NR_FUNCTION_RETURN_REG;
                  cg.a_reg_alloc(list,r);
                  cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                  if cgsize in [OS_64,OS_S64] then
                  if cgsize in [OS_64,OS_S64] then
                   begin
                   begin
                     uses_acchi:=true;
                     uses_acchi:=true;
                     r2.enum:=R_INTREGISTER;
                     r2.enum:=R_INTREGISTER;
-                    r2.number:=NR_ACCUMULATORHIGH;
+                    r2.number:=NR_FUNCTION_RETURNHIGH_REG;
                     cg.a_reg_alloc(list,r2);
                     cg.a_reg_alloc(list,r2);
                     cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                     cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                   end
                   end
@@ -1263,7 +1264,7 @@ implementation
 {$endif cpu64bit}
 {$endif cpu64bit}
                   begin
                   begin
                     hreg.enum:=R_INTREGISTER;
                     hreg.enum:=R_INTREGISTER;
-                    hreg.number:=RS_RETURN_RESULT_REG shl 8 or cgsize2subreg(cgsize);
+                    hreg.number:=(RS_FUNCTION_RETURN_REG shl 8) or cgsize2subreg(cgsize);
                     cg.a_load_ref_reg(list,cgsize,href,hreg);
                     cg.a_load_ref_reg(list,cgsize,href,hreg);
                   end;
                   end;
                end;
                end;
@@ -1272,10 +1273,10 @@ implementation
                  uses_fpu := true;
                  uses_fpu := true;
 {$ifdef cpufpemu}
 {$ifdef cpufpemu}
                   if cs_fp_emulation in aktmoduleswitches then
                   if cs_fp_emulation in aktmoduleswitches then
-                    r.enum := accumulator
+                    r.enum := FUNCTION_RETURN_REG
                  else
                  else
 {$endif cpufpemu}
 {$endif cpufpemu}
-                  r.enum:=fpu_result_reg;
+                  r.enum:=FPU_RESULT_REG;
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                end;
                end;
              else
              else
@@ -1284,7 +1285,7 @@ implementation
                   begin
                   begin
                     uses_acc:=true;
                     uses_acc:=true;
                     r.enum:=R_INTREGISTER;
                     r.enum:=R_INTREGISTER;
-                    r.number:=NR_RETURN_RESULT_REG;
+                    r.number:=NR_FUNCTION_RETURN_REG;
                     cg.a_reg_alloc(list,r);
                     cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                     { Win32 can return records in EAX:EDX }
                     { Win32 can return records in EAX:EDX }
@@ -1292,7 +1293,7 @@ implementation
                      begin
                      begin
                        uses_acchi:=true;
                        uses_acchi:=true;
                        r2.enum:=R_INTREGISTER;
                        r2.enum:=R_INTREGISTER;
-                       r2.number:=NR_ACCUMULATORHIGH;
+                       r2.number:=NR_FUNCTION_RETURNHIGH_REG;
                        cg.a_reg_alloc(list,r2);
                        cg.a_reg_alloc(list,r2);
                        cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                        cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                      end
                      end
@@ -1300,7 +1301,7 @@ implementation
 {$endif cpu64bit}
 {$endif cpu64bit}
                      begin
                      begin
                        hreg.enum:=R_INTREGISTER;
                        hreg.enum:=R_INTREGISTER;
-                       hreg.number:=RS_RETURN_RESULT_REG shl 8 or cgsize2subreg(cgsize);
+                       hreg.number:=RS_FUNCTION_RETURN_REG shl 8 or cgsize2subreg(cgsize);
                        cg.a_load_ref_reg(list,cgsize,href,hreg);
                        cg.a_load_ref_reg(list,cgsize,href,hreg);
                      end;
                      end;
                    end
                    end
@@ -1629,7 +1630,7 @@ implementation
                 { Success exit }
                 { Success exit }
                 cg.a_label(list,okexitlabel);
                 cg.a_label(list,okexitlabel);
                 r.enum:=R_INTREGISTER;
                 r.enum:=R_INTREGISTER;
-                r.number:=NR_ACCUMULATOR;
+                r.number:=NR_FUNCTION_RETURN_REG;
                 cg.a_reg_alloc(list,r);
                 cg.a_reg_alloc(list,r);
                 { return the self pointer }
                 { return the self pointer }
                 srsym:=tvarsym(current_procdef.parast.search('self'));
                 srsym:=tvarsym(current_procdef.parast.search('self'));
@@ -1641,7 +1642,7 @@ implementation
                 usesacc:=true;
                 usesacc:=true;
               end
               end
             else
             else
-              handle_return_value(list,usesacc,usesacchi,usesfpu)
+              load_return_value(list,usesacc,usesacchi,usesfpu)
           end;
           end;
 
 
 {$ifdef GDB}
 {$ifdef GDB}
@@ -1782,7 +1783,7 @@ implementation
                                  Inlining
                                  Inlining
 ****************************************************************************}
 ****************************************************************************}
 
 
-    procedure handle_inlined_return_value(list:TAAsmoutput);
+    procedure load_inlined_return_value(list:TAAsmoutput);
       var
       var
         href : treference;
         href : treference;
         r,r2 : tregister;
         r,r2 : tregister;
@@ -1793,7 +1794,7 @@ implementation
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            { Here, we return the function result. In most architectures, the value is
            { Here, we return the function result. In most architectures, the value is
-             passed into the accumulator, but in a windowed architecure like sparc a
+             passed into the FUNCTION_RETURN_REG, but in a windowed architecure like sparc a
              function returns in a register and the caller receives it in an other one }
              function returns in a register and the caller receives it in an other one }
            case current_procdef.rettype.def.deftype of
            case current_procdef.rettype.def.deftype of
              orddef,
              orddef,
@@ -1817,10 +1818,10 @@ implementation
                begin
                begin
 {$ifdef cpufpemu}
 {$ifdef cpufpemu}
                   if cs_fp_emulation in aktmoduleswitches then
                   if cs_fp_emulation in aktmoduleswitches then
-                    r.enum := accumulator
+                    r.enum := FUNCTION_RETURN_REG
                  else
                  else
 {$endif cpufpemu}
 {$endif cpufpemu}
-                  r.enum:=fpu_result_reg;
+                  r.enum:=FPU_RESULT_REG;
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                end;
                end;
              else
              else
@@ -1898,8 +1899,8 @@ implementation
           begin
           begin
             if (current_procdef.proctypeoption=potype_constructor) then
             if (current_procdef.proctypeoption=potype_constructor) then
              internalerror(200305263);
              internalerror(200305263);
-//            handle_inlined_return_value(list);
-             handle_return_value(list,usesacc,usesacchi,usesfpu)
+//            load_inlined_return_value(list);
+             load_return_value(list,usesacc,usesacchi,usesfpu)
           end;
           end;
 
 
         cleanup_regvars(list);
         cleanup_regvars(list);
@@ -1908,7 +1909,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.111  2003-05-30 23:49:18  jonas
+  Revision 1.112  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.111  2003/05/30 23:49:18  jonas
     * a_load_loc_reg now has an extra size parameter for the destination
     * a_load_loc_reg now has an extra size parameter for the destination
       register (properly fixes what I worked around in revision 1.106 of
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)
       ncgutil.pas)
@@ -2116,7 +2122,7 @@ end.
     * pass proccalloption to ret_in_xxx and push_xxx functions
     * pass proccalloption to ret_in_xxx and push_xxx functions
 
 
   Revision 1.61  2002/11/17 17:49:08  mazen
   Revision 1.61  2002/11/17 17:49:08  mazen
-  + return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
+  + return_result_reg and FUNCTION_RESULT_REG are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
 
 
   Revision 1.60  2002/11/17 16:31:56  carl
   Revision 1.60  2002/11/17 16:31:56  carl
     * memory optimization (3-4%) : cleanup of tai fields,
     * memory optimization (3-4%) : cleanup of tai fields,

+ 25 - 9
compiler/paramgr.pas

@@ -236,7 +236,8 @@ unit paramgr;
          result.loc:=LOC_REFERENCE;
          result.loc:=LOC_REFERENCE;
          result.size:=OS_ADDR;
          result.size:=OS_ADDR;
          result.sp_fixup:=pointer_size;
          result.sp_fixup:=pointer_size;
-         result.reference.index.enum:=stack_pointer_reg;
+         result.reference.index.enum:=R_INTREGISTER;
+         result.reference.index.number:=NR_STACK_POINTER_REG;
          result.reference.offset:=0;
          result.reference.offset:=0;
       end;
       end;
 
 
@@ -246,7 +247,8 @@ unit paramgr;
          result.loc:=LOC_REFERENCE;
          result.loc:=LOC_REFERENCE;
          result.size:=OS_ADDR;
          result.size:=OS_ADDR;
          result.sp_fixup:=pointer_size;
          result.sp_fixup:=pointer_size;
-         result.reference.index.enum:=stack_pointer_reg;
+         result.reference.index.enum:=R_INTREGISTER;
+         result.reference.index.number:=NR_STACK_POINTER_REG;
          result.reference.offset:=0;
          result.reference.offset:=0;
       end;
       end;
 
 
@@ -265,29 +267,38 @@ unit paramgr;
 {$ifndef cpu64bit}
 {$ifndef cpu64bit}
                if result.size in [OS_64,OS_S64] then
                if result.size in [OS_64,OS_S64] then
                 begin
                 begin
-                  result.register64.reghi.enum:=accumulatorhigh;
-                  result.register64.reglo.enum:=accumulator;
+                  result.register64.reghi.enum:=R_INTREGISTER;
+                  result.register64.reghi.number:=NR_FUNCTION_RETURNHIGH_REG;
+                  result.register64.reglo.enum:=R_INTREGISTER;
+                  result.register64.reglo.number:=NR_FUNCTION_RETURN_REG;
                 end
                 end
                else
                else
 {$endif cpu64bit}
 {$endif cpu64bit}
-               result.register.enum:=accumulator;
+                begin
+                  result.register.enum:=R_INTREGISTER;
+                  result.register.number:=NR_FUNCTION_RETURN_REG;
+                end;
              end;
              end;
            floatdef :
            floatdef :
              begin
              begin
                result.loc := LOC_FPUREGISTER;
                result.loc := LOC_FPUREGISTER;
 {$ifdef cpufpemu}
 {$ifdef cpufpemu}
                if cs_fp_emulation in aktmoduleswitches then
                if cs_fp_emulation in aktmoduleswitches then
-                  result.register.enum := accumulator
+                 begin
+                   result.register.enum:=R_INTREGISTER;
+                   result.register.number:=FUNCTION_RETURN_REG;
+                 end
                else
                else
 {$endif cpufpemu}
 {$endif cpufpemu}
-                  result.register.enum := FPU_RESULT_REG;
+                 result.register.enum := FPU_RESULT_REG;
              end;
              end;
           else
           else
              begin
              begin
                 if not ret_in_param(def,calloption) then
                 if not ret_in_param(def,calloption) then
                   begin
                   begin
                     result.loc := LOC_REGISTER;
                     result.loc := LOC_REGISTER;
-                    result.register.enum := accumulator;
+                    result.register.enum:=R_INTREGISTER;
+                    result.register.number:=NR_FUNCTION_RETURN_REG;
                   end
                   end
                 else
                 else
                    begin
                    begin
@@ -388,7 +399,12 @@ end.
 
 
 {
 {
    $Log$
    $Log$
-   Revision 1.38  2003-05-13 15:16:13  peter
+   Revision 1.39  2003-05-30 23:57:08  peter
+     * more sparc cleanup
+     * accumulator removed, splitted in function_return_reg (called) and
+       function_result_reg (caller)
+
+   Revision 1.38  2003/05/13 15:16:13  peter
      * removed ret_in_acc, it's the reverse of ret_in_param
      * removed ret_in_acc, it's the reverse of ret_in_param
      * fixed ret_in_param for win32 cdecl array
      * fixed ret_in_param for win32 cdecl array
 
 

+ 114 - 123
compiler/powerpc/cpubase.pas

@@ -221,6 +221,7 @@ uses
       NR_RTOC = NR_R2;
       NR_RTOC = NR_R2;
 
 
     {Super registers:}
     {Super registers:}
+      RS_NONE=$00;
       RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
       RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
       RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
       RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
       RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
       RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
@@ -380,7 +381,7 @@ uses
         case typ : toptype of
         case typ : toptype of
          top_none   : ();
          top_none   : ();
          top_reg    : (reg:tregister);
          top_reg    : (reg:tregister);
-         top_ref    : (ref:^treference);
+         top_ref    : (ref:preference);
          top_const  : (val:aword);
          top_const  : (val:aword);
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_bool  :  (b: boolean);
          top_bool  :  (b: boolean);
@@ -474,9 +475,6 @@ uses
     const
     const
       max_operands = 5;
       max_operands = 5;
 
 
-      lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
-                         LOC_CMMREGISTER];
-
       {# Constant defining possibly all registers which might require saving }
       {# Constant defining possibly all registers which might require saving }
 {$warning FIX ME !!!!!!!!! }
 {$warning FIX ME !!!!!!!!! }
       ALL_REGISTERS = [R_0..R_FPSCR];
       ALL_REGISTERS = [R_0..R_FPSCR];
@@ -591,47 +589,47 @@ uses
 
 
       }
       }
 
 
-          stab_regindex : array[firstreg..lastreg] of shortint =
-          (
-           { R_NO }
-           -1,
-           { R0..R7 }
-           0,1,2,3,4,5,6,7,
-           { R8..R15 }
-           8,9,10,11,12,13,14,15,
-           { R16..R23 }
-           16,17,18,19,20,21,22,23,
-           { R24..R32 }
-           24,25,26,27,28,29,30,31,
-           { F0..F7 }
-           32,33,34,35,36,37,38,39,
-           { F8..F15 }
-           40,41,42,43,44,45,46,47,
-           { F16..F23 }
-           48,49,50,51,52,53,54,55,
-           { F24..F31 }
-           56,57,58,59,60,61,62,63,
-           { M0..M7 Multimedia registers are not supported by GCC }
-           -1,-1,-1,-1,-1,-1,-1,-1,
-           { M8..M15 }
-           -1,-1,-1,-1,-1,-1,-1,-1,
-           { M16..M23 }
-           -1,-1,-1,-1,-1,-1,-1,-1,
-           { M24..M31 }
-           -1,-1,-1,-1,-1,-1,-1,-1,
-           { CR }
-           -1,
-           { CR0..CR7 }
-           68,69,70,71,72,73,74,75,
-           { XER }
-           76,
-           { LR }
-           65,
-           { CTR }
-           66,
-           { FPSCR }
-           -1
-        );
+      stab_regindex : array[firstreg..lastreg] of shortint =
+      (
+        { R_NO }
+        -1,
+        { R0..R7 }
+        0,1,2,3,4,5,6,7,
+        { R8..R15 }
+        8,9,10,11,12,13,14,15,
+        { R16..R23 }
+        16,17,18,19,20,21,22,23,
+        { R24..R32 }
+        24,25,26,27,28,29,30,31,
+        { F0..F7 }
+        32,33,34,35,36,37,38,39,
+        { F8..F15 }
+        40,41,42,43,44,45,46,47,
+        { F16..F23 }
+        48,49,50,51,52,53,54,55,
+        { F24..F31 }
+        56,57,58,59,60,61,62,63,
+        { M0..M7 Multimedia registers are not supported by GCC }
+        -1,-1,-1,-1,-1,-1,-1,-1,
+        { M8..M15 }
+        -1,-1,-1,-1,-1,-1,-1,-1,
+        { M16..M23 }
+        -1,-1,-1,-1,-1,-1,-1,-1,
+        { M24..M31 }
+        -1,-1,-1,-1,-1,-1,-1,-1,
+        { CR }
+        -1,
+        { CR0..CR7 }
+        68,69,70,71,72,73,74,75,
+        { XER }
+        76,
+        { LR }
+        65,
+        { CTR }
+        66,
+        { FPSCR }
+        -1
+      );
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -639,18 +637,11 @@ uses
 *****************************************************************************}
 *****************************************************************************}
 
 
       {# Stack pointer register }
       {# Stack pointer register }
-      stack_pointer_reg = R_1;
       NR_STACK_POINTER_REG = NR_R1;
       NR_STACK_POINTER_REG = NR_R1;
       RS_STACK_POINTER_REG = RS_R1;
       RS_STACK_POINTER_REG = RS_R1;
       {# Frame pointer register }
       {# Frame pointer register }
-      frame_pointer_reg = stack_pointer_reg;
       NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
       NR_FRAME_POINTER_REG = NR_STACK_POINTER_REG;
       RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
       RS_FRAME_POINTER_REG = RS_STACK_POINTER_REG;
-      {# Self pointer register : contains the instance address of an
-         object or class. }
-      self_pointer_reg = R_9;
-      NR_SELF_POINTER_REG = NR_R9;
-      RS_SELF_POINTER_REG = RS_R9;
       {# Register for addressing absolute data in a position independant way,
       {# Register for addressing absolute data in a position independant way,
          such as in PIC code. The exact meaning is ABI specific. For
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -658,28 +649,23 @@ uses
          Taken from GCC rs6000.h
          Taken from GCC rs6000.h
       }
       }
 {$warning As indicated in rs6000.h, but can't find it anywhere else!}
 {$warning As indicated in rs6000.h, but can't find it anywhere else!}
-      pic_offset_reg = R_30;
-      {# Results are returned in this register (32-bit values) }
-      accumulator   = R_3;
-      NR_ACCUMULATOR = NR_R3;
-      RS_ACCUMULATOR = RS_R3;
-  {the return_result_reg, is used inside the called function to store its return
-  value when that is a scalar value otherwise a pointer to the address of the
-  result is placed inside it}
-        return_result_reg               =       accumulator;
-      NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
-      RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
-
-  {the function_result_reg contains the function result after a call to a scalar
-  function othewise it contains a pointer to the returned result}
-        function_result_reg     =       accumulator;
-      {# Hi-Results are returned in this register (64-bit value high register) }
-      accumulatorhigh = R_4;
-      NR_ACCUMULATORHIGH = NR_R4;
-      RS_ACCUMULATORHIGH = RS_R4;
+      NR_PIC_OFFSET_REG = NR_R30;
+      { Results are returned in this register (32-bit values) }
+      NR_FUNCTION_RETURN_REG = NR_R3;
+      RS_FUNCTION_RETURN_REG = RS_R3;
+      { High part of 64bit return value }
+      NR_FUNCTION_RETURNHIGH_REG = NR_R4;
+      RS_FUNCTION_RETURNHIGH_REG = RS_R4;
+      { The value returned from a function is available in this register }
+      NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
+      RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
+      { The high part of 64bit value returned from a function is available in this register }
+      NR_FUNCTION_RESULTHIGH_REG = NR_FUNCTION_RETURNHIGH_REG;
+      RS_FUNCTION_RESULTHIGH_REG = RS_FUNCTION_RETURNHIGH_REG;
+
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { WARNING: don't change to R_ST0!! See comments above implementation of }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       { a_loadfpu* methods in rgcpu (JM)                                      }
-      fpu_result_reg = R_F1;
+      FPU_RESULT_REG = R_F1;
       mmresultreg = R_M0;
       mmresultreg = R_M0;
 
 
 {*****************************************************************************
 {*****************************************************************************
@@ -731,6 +717,7 @@ uses
     procedure convert_register_to_enum(var r:Tregister);
     procedure convert_register_to_enum(var r:Tregister);
     function cgsize2subreg(s:Tcgsize):Tsubregister;
     function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 
+
 implementation
 implementation
 
 
     uses
     uses
@@ -792,7 +779,6 @@ implementation
 
 
 
 
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
-
       begin
       begin
         r.simple := true;
         r.simple := true;
         r.cond := cond;
         r.cond := cond;
@@ -803,64 +789,69 @@ implementation
         end;
         end;
       end;
       end;
 
 
-    procedure convert_register_to_enum(var r:Tregister);
 
 
-    begin
-      if r.enum = R_INTREGISTER then
-        if (r.number >= NR_NO) and
-           (r.number <= NR_R31) then
-          r.enum := toldregister(r.number shr 8)
-        else
+    procedure convert_register_to_enum(var r:Tregister);
+      begin
+        if r.enum = R_INTREGISTER then
+         if (r.number >= NR_NO) and
+            (r.number <= NR_R31) then
+           r.enum := toldregister(r.number shr 8)
+         else
 {        case r.number of
 {        case r.number of
-          NR_NO: r.enum:= R_NO;
-
-          NR_R0: r.enum:= R_0;
-          NR_R1: r.enum:= R_1;
-          NR_R2: r.enum:= R_2;
-          NR_R3: r.enum:= R_3;
-          NR_R4: r.enum:= R_4;
-          NR_R5: r.enum:= R_5;
-          NR_R6: r.enum:= R_6;
-          NR_R7: r.enum:= R_7;
-          NR_R8: r.enum:= R_8;
-          NR_R9: r.enum:= R_9;
-          NR_R10: r.enum:= R_10;
-          NR_R11: r.enum:= R_11;
-          NR_R12: r.enum:= R_12;
-          NR_R13: r.enum:= R_13;
-          NR_R14: r.enum:= R_14;
-          NR_R15: r.enum:= R_15;
-          NR_R16: r.enum:= R_16;
-          NR_R17: r.enum:= R_17;
-          NR_R18: r.enum:= R_18;
-          NR_R19: r.enum:= R_19;
-          NR_R20: r.enum:= R_20;
-          NR_R21: r.enum:= R_21;
-          NR_R22: r.enum:= R_22;
-          NR_R23: r.enum:= R_23;
-          NR_R24: r.enum:= R_24;
-          NR_R25: r.enum:= R_25;
-          NR_R26: r.enum:= R_26;
-          NR_R27: r.enum:= R_27;
-          NR_R28: r.enum:= R_28;
-          NR_R29: r.enum:= R_29;
-          NR_R30: r.enum:= R_30;
-          NR_R31: r.enum:= R_31;
+            NR_NO: r.enum:= R_NO;
+
+            NR_R0: r.enum:= R_0;
+            NR_R1: r.enum:= R_1;
+            NR_R2: r.enum:= R_2;
+            NR_R3: r.enum:= R_3;
+            NR_R4: r.enum:= R_4;
+            NR_R5: r.enum:= R_5;
+            NR_R6: r.enum:= R_6;
+            NR_R7: r.enum:= R_7;
+            NR_R8: r.enum:= R_8;
+            NR_R9: r.enum:= R_9;
+            NR_R10: r.enum:= R_10;
+            NR_R11: r.enum:= R_11;
+            NR_R12: r.enum:= R_12;
+            NR_R13: r.enum:= R_13;
+            NR_R14: r.enum:= R_14;
+            NR_R15: r.enum:= R_15;
+            NR_R16: r.enum:= R_16;
+            NR_R17: r.enum:= R_17;
+            NR_R18: r.enum:= R_18;
+            NR_R19: r.enum:= R_19;
+            NR_R20: r.enum:= R_20;
+            NR_R21: r.enum:= R_21;
+            NR_R22: r.enum:= R_22;
+            NR_R23: r.enum:= R_23;
+            NR_R24: r.enum:= R_24;
+            NR_R25: r.enum:= R_25;
+            NR_R26: r.enum:= R_26;
+            NR_R27: r.enum:= R_27;
+            NR_R28: r.enum:= R_28;
+            NR_R29: r.enum:= R_29;
+            NR_R30: r.enum:= R_30;
+            NR_R31: r.enum:= R_31;
         else}
         else}
-          internalerror(200301082);
+            internalerror(200301082);
 {        end;}
 {        end;}
-    end;
+      end;
 
 
-    function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 
-    begin
-      cgsize2subreg:=R_SUBWHOLE;
-    end;
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+      begin
+        cgsize2subreg:=R_SUBWHOLE;
+      end;
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.53  2003-05-30 18:49:59  jonas
+  Revision 1.54  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.53  2003/05/30 18:49:59  jonas
     * changed scratchregs from r28-r30 to r29-r31
     * changed scratchregs from r28-r30 to r29-r31
     * made sure the regvar registers don't overlap with the scratchregs
     * made sure the regvar registers don't overlap with the scratchregs
       anymore
       anymore
@@ -924,10 +915,10 @@ end.
     + some comments describing the fields of treference
     + some comments describing the fields of treference
 
 
   Revision 1.36  2002/11/17 18:26:16  mazen
   Revision 1.36  2002/11/17 18:26:16  mazen
-  * fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
+  * fixed a compilation bug accmulator-->FUNCTION_RETURN_REG, in definition of return_result_reg
 
 
   Revision 1.35  2002/11/17 17:49:09  mazen
   Revision 1.35  2002/11/17 17:49:09  mazen
-  + return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
+  + return_result_reg and FUNCTION_RESULT_REG are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
 
 
   Revision 1.34  2002/09/17 18:54:06  jonas
   Revision 1.34  2002/09/17 18:54:06  jonas
     * a_load_reg_reg() now has two size parameters: source and dest. This
     * a_load_reg_reg() now has two size parameters: source and dest. This

+ 13 - 4
compiler/powerpc/radirect.pas

@@ -83,6 +83,7 @@ interface
          srsym,sym : tsym;
          srsym,sym : tsym;
          srsymtable : tsymtable;
          srsymtable : tsymtable;
          code : TAAsmoutput;
          code : TAAsmoutput;
+         framereg : tregister;
          i,l : longint;
          i,l : longint;
 
 
        procedure writeasmline;
        procedure writeasmline;
@@ -104,6 +105,9 @@ interface
 
 
      begin
      begin
        ende:=false;
        ende:=false;
+       framereg.enum:=R_INTREGISTER;
+       framereg.number:=NR_STACK_POINTER_REG;
+       convert_register_to_enum(framereg);
        s:='';
        s:='';
        if assigned(current_procdef.funcretsym) and
        if assigned(current_procdef.funcretsym) and
           is_fpu(current_procdef.rettype.def) then
           is_fpu(current_procdef.rettype.def) then
@@ -191,11 +195,11 @@ interface
                                                     if (tvarsym(sym).reg.enum<>R_NO) then
                                                     if (tvarsym(sym).reg.enum<>R_NO) then
 // until new regallocator stuff settles down
 // until new regallocator stuff settles down
 //                                                      hs:=gas_reg2str[procinfo.framepointer.enum]
 //                                                      hs:=gas_reg2str[procinfo.framepointer.enum]
-                                                      hs:=gas_reg2str[STACK_POINTER_REG]
+                                                      hs:=gas_reg2str[framereg.enum]
                                                     else
                                                     else
                                                       hs:=tostr(tvarsym(sym).address)+
                                                       hs:=tostr(tvarsym(sym).address)+
 //                                                        '('+gas_reg2str[procinfo.framepointer.enum]+')';
 //                                                        '('+gas_reg2str[procinfo.framepointer.enum]+')';
-                                                        '('+gas_reg2str[STACK_POINTER_REG]+')';
+                                                        '('+gas_reg2str[framereg.enum]+')';
                                                  end;
                                                  end;
                                             end
                                             end
                                           else
                                           else
@@ -217,7 +221,7 @@ interface
                                                     { set offset }
                                                     { set offset }
                                                     inc(l,current_procdef.parast.address_fixup);
                                                     inc(l,current_procdef.parast.address_fixup);
 //                                                    hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer.enum]+')';
 //                                                    hs:=tostr(l)+'('+gas_reg2str[procinfo.framepointer.enum]+')';
-                                                    hs:=tostr(l)+'('+gas_reg2str[STACK_POINTER_REG]+')';
+                                                    hs:=tostr(l)+'('+gas_reg2str[framereg.enum]+')';
                                                     if pos(',',s) > 0 then
                                                     if pos(',',s) > 0 then
                                                       tvarsym(sym).varstate:=vs_used;
                                                       tvarsym(sym).varstate:=vs_used;
                                                  end;
                                                  end;
@@ -347,7 +351,12 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.13  2003-04-27 11:21:36  peter
+  Revision 1.14  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.13  2003/04/27 11:21:36  peter
     * aktprocdef renamed to current_procdef
     * aktprocdef renamed to current_procdef
     * procinfo renamed to current_procinfo
     * procinfo renamed to current_procinfo
     * procinfo will now be stored in current_module so it can be
     * procinfo will now be stored in current_module so it can be

+ 7 - 2
compiler/psub.pas

@@ -1210,8 +1210,13 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.119  2003-05-28 23:58:18  jonas
-    * added missing initialization of rg.usedint{in,by}proc
+  Revision 1.120  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.119  2003/05/28 23:58:18  jonas
+    * added missing initialization of rg.usedintin,byproc
     * ppc now also saves/restores used fpu registers
     * ppc now also saves/restores used fpu registers
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
       i386
       i386

+ 21 - 17
compiler/rautils.pas

@@ -28,7 +28,7 @@ Interface
 
 
 Uses
 Uses
   cutils,cclasses,
   cutils,cclasses,
-  globtype,aasmbase,aasmtai,cpubase,cpuinfo,
+  globtype,aasmbase,aasmtai,cpubase,cpuinfo,cginfo,
   symconst,symbase,symtype,symdef;
   symconst,symbase,symtype,symdef;
 
 
 Const
 Const
@@ -85,14 +85,14 @@ type
   end;
   end;
 
 
   TOperand = class
   TOperand = class
-    size   : topsize;
     hastype,          { if the operand has typecasted variable }
     hastype,          { if the operand has typecasted variable }
     hasvar : boolean; { if the operand is loaded with a variable }
     hasvar : boolean; { if the operand is loaded with a variable }
+    size   : TCGSize;
     opr    : TOprRec;
     opr    : TOprRec;
     constructor create;
     constructor create;
     destructor  destroy;override;
     destructor  destroy;override;
     Procedure BuildOperand;virtual;
     Procedure BuildOperand;virtual;
-    Procedure SetSize(_size:longint;force:boolean);
+    Procedure SetSize(_size:longint;force:boolean);virtual;
     Procedure SetCorrectSize(opcode:tasmop);virtual;
     Procedure SetCorrectSize(opcode:tasmop);virtual;
     Function  SetupResult:boolean;virtual;
     Function  SetupResult:boolean;virtual;
     Function  SetupSelf:boolean;
     Function  SetupSelf:boolean;
@@ -104,7 +104,6 @@ type
 
 
   TInstruction = class
   TInstruction = class
     opcode    : tasmop;
     opcode    : tasmop;
-    opsize    : topsize;
     condition : tasmcond;
     condition : tasmcond;
     ops       : byte;
     ops       : byte;
     labeled   : boolean;
     labeled   : boolean;
@@ -690,7 +689,7 @@ end;
 
 
 constructor TOperand.Create;
 constructor TOperand.Create;
 begin
 begin
-  size:=S_NO;
+  size:=OS_NO;
   hastype:=false;
   hastype:=false;
   hasvar:=false;
   hasvar:=false;
   FillChar(Opr,sizeof(Opr),0);
   FillChar(Opr,sizeof(Opr),0);
@@ -702,32 +701,33 @@ begin
 end;
 end;
 
 
 
 
-Procedure TOperand.SetCorrectSize(opcode:tasmop);
-begin
-end;
-
 Procedure TOperand.SetSize(_size:longint;force:boolean);
 Procedure TOperand.SetSize(_size:longint;force:boolean);
 begin
 begin
   if force or
   if force or
-     ((size = S_NO) and (_size<=extended_size)) then
+     ((size = OS_NO) and (_size<=extended_size)) then
    Begin
    Begin
      case _size of
      case _size of
-      1 : size:=S_B;
-      2 : size:=S_W{ could be S_IS};
-      4 : size:=S_L{ could be S_IL or S_FS};
-      8 : size:=S_IQ{ could be S_D or S_FL};
+      1 : size:=OS_8;
+      2 : size:=OS_16{ could be S_IS};
+      4 : size:=OS_32{ could be S_IL or S_FS};
+      8 : size:=OS_64{ could be S_D or S_FL};
      else
      else
       begin
       begin
         { extended_size can also be 8, resulting in a
         { extended_size can also be 8, resulting in a
           duplicate label }
           duplicate label }
         if _size=extended_size then
         if _size=extended_size then
-          size:=S_FX;
+          size:=OS_F80;
       end;
       end;
      end;
      end;
    end;
    end;
 end;
 end;
 
 
 
 
+Procedure TOperand.SetCorrectSize(opcode:tasmop);
+begin
+end;
+
+
 Function TOperand.SetupResult:boolean;
 Function TOperand.SetupResult:boolean;
 Begin
 Begin
   SetupResult:=false;
   SetupResult:=false;
@@ -1016,7 +1016,6 @@ end;
 constructor TInstruction.create;
 constructor TInstruction.create;
 Begin
 Begin
   Opcode:=A_NONE;
   Opcode:=A_NONE;
-  Opsize:=S_NO;
   Condition:=C_NONE;
   Condition:=C_NONE;
   Ops:=0;
   Ops:=0;
   InitOperands;
   InitOperands;
@@ -1554,7 +1553,12 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.61  2003-05-25 08:55:49  peter
+  Revision 1.62  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.61  2003/05/25 08:55:49  peter
     * load result using hidden parameter
     * load result using hidden parameter
 
 
   Revision 1.60  2003/05/15 18:58:53  peter
   Revision 1.60  2003/05/15 18:58:53  peter

+ 223 - 350
compiler/sparc/aasmcpu.pas

@@ -1,10 +1,8 @@
-{*****************************************************************************
+{
     $Id$
     $Id$
-    Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
+    Copyright (c) 1999-2002 by Mazen Neifer
 
 
-    * This code was inspired by the NASM sources
-      The Netwide Assembler is copyright (C) 1996 Simon Tatham and
-      Julian Hall. All rights reserved.
+    Contains the assembler object for the SPARC
 
 
     This program is free software; you can redistribute it and/or modify
     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
     it under the terms of the GNU General Public License as published by
@@ -19,379 +17,254 @@
     You should have received a copy of the GNU General Public License
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************}
+
+ ****************************************************************************
+}
 unit aasmcpu;
 unit aasmcpu;
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
+
 interface
 interface
+
 uses
 uses
-  cclasses,globals,verbose,
-  cpuinfo,cpubase,
-  symppu,
-  aasmbase,aasmtai;
-const
-  MaxPrefixes=4;
-type
-  { alignment for operator }
-  tai_align=class(tai_align_abstract)
- reg:tregister;
- constructor create(b:byte);
- constructor create_op(b:byte; _op:byte);
-  end;
-  taicpu = class(taicpu_abstract)
-    opsize:topsize;
-    constructor op_none(op:tasmop);
-    constructor op_reg(op:tasmop;reg:tregister);
-    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;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 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_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_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);
-
- { this is for Jmp instructions }
-    constructor op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
-    constructor op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
-    constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
-    constructor op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
-    constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
-    procedure changeopsize(siz:topsize);
-  private
-    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 }
-    procedure SetCondition(const c:TAsmCond);
-  private
-    { next fields are filled in pass1, so pass2 is faster }
-    procedure Swatoperands;
-  end;
-PROCEDURE DoneAsm;
-PROCEDURE InitAsm;
+  cclasses,aasmtai,
+  aasmbase,globals,verbose,
+  cpubase,cpuinfo;
+
+    type
+      taicpu = class(taicpu_abstract)
+         constructor op_none(op : tasmop);
+
+         constructor op_reg(op : tasmop;_op1 : tregister);
+         constructor op_ref(op : tasmop;const _op1 : treference);
+         constructor op_const(op : tasmop;_op1 : aword);
+
+         constructor op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+         constructor op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : 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);
+
+         constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+         constructor op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
+         constructor op_reg_const_reg(op:tasmop;_op1:TRegister;_op2:aword;_op3:tregister);
+         constructor op_const_ref_reg(op:tasmop;_op1:aword;const _op2:treference;_op3:tregister);
+         constructor op_const_reg_ref(op:tasmop;_op1:aword;_op2:tregister;const _op3:treference);
+
+         { this is for Jmp instructions }
+         constructor op_cond_sym(op : tasmop;cond:TAsmCond;_op1 : tasmsymbol);
+         constructor op_sym(op : tasmop;_op1 : tasmsymbol);
+         constructor op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+      end;
+
+      tai_align = class(tai_align_abstract)
+        { nothing to add }
+      end;
+
+    procedure InitAsm;
+    procedure DoneAsm;
+
+
 implementation
 implementation
-uses
-  cutils,
-  CpuGas;
-const
-  _size=S_SW;{To be removed soon}
-{****************************************************************************
-                          TAI_ALIGN
- ****************************************************************************}
-constructor tai_align.create(b:byte);
-  begin
-    inherited create(b);
-    reg.enum:= R_NONE;
-  end;
-constructor tai_align.create_op(b:byte; _op:byte);
-  begin
-    inherited create_op(b,_op);
-    reg.enum:= R_NONE;
-  end;
-{*****************************************************************************
-                             Taicpu Constructors
-*****************************************************************************}
-procedure taicpu.changeopsize(siz:topsize);
-  begin
-    opsize:=siz;
-  end;
-procedure taicpu.init(_size:topsize);
-  begin
-    opsize:=_size;
-  end;
-constructor taicpu.op_none(op:tasmop);
-  begin
-     inherited create(op);
-     init(_size);
-  end;
-constructor taicpu.op_reg(op:tasmop;reg:tregister);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=1;
-     loadreg(0,reg);
-  end;
-constructor taicpu.op_const(op:tasmop;_op1:aword);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=1;
-     loadconst(0,aword(_op1));
-  end;
-constructor taicpu.op_ref(op:tasmop;const _op1:treference);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=1;
-     loadref(0,_op1);
-  end;
-constructor taicpu.op_reg_reg(op:tasmop;_op1,_op2:tregister);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadreg(0,_op1);
-     loadreg(1,_op2);
-  end;
-constructor taicpu.op_reg_const(op:tasmop;_op1:tregister; _op2:aword);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadreg(0,_op1);
-     loadconst(1,aword(_op2));
-  end;
-constructor taicpu.op_reg_ref(Op:TAsmOp;Reg:TRegister;const Ref:TReference);
-  begin
-    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
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadconst(0,aword(_op1));
-     loadreg(1,_op2);
-  end;
-constructor TAiCpu.op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg:TRegister);
-  begin
-    if not(Op in [A_JMPL,A_FLUSH,A_LDSB..A_LDDC,A_RETT,A_SWAP])
-    then
-      InternalError(2003042900);
-    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
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadref(0,_op1);
-     loadref(1,_op2);
-  end;
-constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=3;
-     loadreg(0,_op1);
-     loadreg(1,_op2);
-     loadreg(2,_op3);
-  end;
-constructor taicpu.op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=3;
-     loadreg(0,_op1);
-     loadref(1,_op2);
-     loadreg(2,_op3);
-  end;
-constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
-  begin
-    inherited Create(Op);
-    Init(S_W);
-    ops:=3;
-    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
-     inherited create(op);
-     init(_size);
-     ops:=3;
-     loadconst(0,aword(_op1));
-     loadref(1,_op2);
-     loadreg(2,_op3);
-  end;
-constructor taicpu.op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=3;
-     loadconst(0,aword(_op1));
-     loadreg(1,_op2);
-     loadref(2,_op3);
-  end;
-constructor taicpu.op_cond_sym(op:tasmop;cond:TAsmCond;_size:topsize;_op1:tasmsymbol);
-  begin
-     inherited create(op);
-     init(_size);
-     condition:=cond;
-     ops:=1;
-     loadsymbol(0,_op1,0);
-  end;
-constructor taicpu.op_sym(op:tasmop;_size:topsize;_op1:tasmsymbol);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=1;
-     loadsymbol(0,_op1,0);
-  end;
-constructor taicpu.op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=1;
-     loadsymbol(0,_op1,_op1ofs);
-  end;
-constructor taicpu.op_sym_ofs_reg(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;_op2:tregister);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadsymbol(0,_op1,_op1ofs);
-     loadreg(1,_op2);
-  end;
-
-
-constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
-  begin
-     inherited create(op);
-     init(_size);
-     ops:=2;
-     loadsymbol(0,_op1,_op1ofs);
-     loadref(1,_op2);
-  end;
-
-procedure taicpu.Swatoperands;
-  var
-    p:TOper;
-  begin
-    { Fix the operands which are in AT&T style and we need them in Intel style }
-    case ops of
-      2:begin
-            { 0,1 -> 1,0 }
-            p:=oper[0];
-            oper[0]:=oper[1];
-            oper[1]:=p;
-          end;
-      3:begin
-            { 0,1,2 -> 2,1,0 }
-            p:=oper[0];
-            oper[0]:=oper[2];
-            oper[2]:=p;
-          end;
-    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 }
+
 {*****************************************************************************
 {*****************************************************************************
-                            Assembler
+                                 taicpu Constructors
 *****************************************************************************}
 *****************************************************************************}
-procedure TAiCpu.SetCondition(const c:TAsmCond);
-  const
-    AsmCond2OpCode:array[TAsmCond]of TAsmOp=
-      (A_BN,A_BNE,A_BE,A_BG,A_BLE,A_BGE,A_BL,A_BGU,A_BLEU,A_BCC,
-A_BCS,A_BPOS,A_NEG,A_BVC,A_BVS,A_BA,A_BNE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE,A_NONE);
-  begin
-    inherited SetCondition(c);
-    if Opcode=A_BA
-    then
+
+    constructor taicpu.op_none(op : tasmop);
       begin
       begin
-        is_jmp:=true;
-        Opcode:=AsmCond2OpCode[c];
-      {$IFDEF EXTDEBUG}
-        WriteLn('In TAiCpu.SetCondition TAsmCond=',cond2str[c],'==>',std_op2str[OpCode]);
-      {$ENDIF EXTDEBUG}
+         inherited create(op);
       end;
       end;
-  end;
-procedure DoneAsm;
-  begin
-  end;
-procedure InitAsm;
-  begin
-  end;
-end.
-{
-    $Log$
-    Revision 1.26  2003-05-28 23:18:31  florian
-      * started to fix and clean up the sparc port
 
 
-    Revision 1.25  2003/05/07 11:45:02  mazen
-    - removed unused code
 
 
-    Revision 1.24  2003/05/07 11:28:26  mazen
-    - method CheckNonCommutativeOpcode removed as not used
+    constructor taicpu.op_reg(op : tasmop;_op1 : tregister);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031207);
+         ops:=1;
+         loadreg(0,_op1);
+      end;
+
+
+    constructor taicpu.op_ref(op : tasmop;const _op1 : treference);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadref(0,_op1);
+      end;
+
+
+    constructor taicpu.op_const(op : tasmop;_op1 : aword);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadconst(0,_op1);
+      end;
+
+
+    constructor taicpu.op_reg_reg(op : tasmop;_op1,_op2 : tregister);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031205);
+         if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then
+           internalerror(2003031206);
+         ops:=2;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+      end;
+
+    constructor taicpu.op_reg_const(op:tasmop; _op1: tregister; _op2: aword);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031208);
+         ops:=2;
+         loadreg(0,_op1);
+         loadconst(1,_op2);
+      end;
+
+     constructor taicpu.op_const_reg(op:tasmop; _op1: aword; _op2: tregister);
+      begin
+         inherited create(op);
+         if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then
+           internalerror(2003031209);
+         ops:=2;
+         loadconst(0,_op1);
+         loadreg(1,_op2);
+      end;
+
 
 
-    Revision 1.23  2003/05/06 20:27:43  mazen
-    * A_BI changed to A_BL
+    constructor taicpu.op_reg_ref(op : tasmop;_op1 : tregister;const _op2 : treference);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031210);
+         ops:=2;
+         loadreg(0,_op1);
+         loadref(1,_op2);
+      end;
 
 
-    Revision 1.22  2003/05/06 15:00:36  mazen
-    - non used code removed to bring up with powerpc changes
 
 
-    Revision 1.21  2003/04/29 11:06:15  mazen
-    * test of invalid opcode/operand combination gives internal error
+    constructor taicpu.op_ref_reg(op : tasmop;const _op1 : treference;_op2 : tregister);
+      begin
+         inherited create(op);
+         if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then
+           internalerror(2003031210);
+         ops:=2;
+         loadref(0,_op1);
+         loadreg(1,_op2);
+      end;
+
+
+    constructor taicpu.op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031211);
+         if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then
+           internalerror(2003031212);
+         if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then
+           internalerror(2003031213);
+         ops:=3;
+         loadreg(0,_op1);
+         loadreg(1,_op2);
+         loadreg(2,_op3);
+      end;
+
+
+    constructor taicpu.op_reg_ref_reg(op:tasmop;_op1:TRegister;_op2:TReference;_op3:tregister);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031214);
+         if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then
+           internalerror(2003031215);
+         ops:=3;
+         loadreg(0,_op1);
+         loadref(1,_op2);
+         loadreg(2,_op3);
+      end;
 
 
-    Revision 1.20  2003/04/28 09:40:47  mazen
-    * Debug message in SetCondition more explicit.
 
 
-    Revision 1.19  2003/03/15 22:51:58  mazen
-    * remaking sparc rtl compile
+    constructor taicpu.op_reg_const_reg(op:tasmop;_op1:TRegister;_op2:aword;_op3:tregister);
+      begin
+         inherited create(op);
+         if (_op1.enum = R_INTREGISTER) and (_op1.number = NR_NO) then
+           internalerror(2003031216);
+         if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then
+           internalerror(2003031217);
+         ops:=3;
+         loadreg(0,_op1);
+         loadconst(1,_op2);
+         loadreg(2,_op3);
+      end;
 
 
-    Revision 1.18  2003/03/10 21:59:54  mazen
-    * fixing index overflow in handling new registers arrays.
 
 
-    Revision 1.17  2003/02/18 22:00:20  mazen
-    * asm condition generation modified by TAiCpu.SetCondition
+    constructor taicpu.op_const_ref_reg(op:tasmop;_op1:aword;const _op2:treference;_op3:tregister);
+      begin
+         inherited create(op);
+         if (_op3.enum = R_INTREGISTER) and (_op3.number = NR_NO) then
+           internalerror(2003031218);
+         ops:=3;
+         loadconst(0,_op1);
+         loadref(1,_op2);
+         loadreg(2,_op3);
+      end;
 
 
-    Revision 1.16  2003/01/08 18:43:58  daniel
-     * Tregister changed into a record
 
 
-    Revision 1.15  2003/01/05 21:32:35  mazen
-    * fixing several bugs compiling the RTL
+    constructor taicpu.op_const_reg_ref(op:tasmop;_op1:aword;_op2:tregister;const _op3:treference);
+      begin
+         inherited create(op);
+         if (_op2.enum = R_INTREGISTER) and (_op2.number = NR_NO) then
+           internalerror(2003031219);
+         ops:=3;
+         loadconst(0,_op1);
+         loadreg(1,_op2);
+         loadref(2,_op3);
+      end;
 
 
-    Revision 1.14  2002/12/14 15:02:03  carl
-      * maxoperands -> max_operands (for portability in rautils.pas)
-      * fix some range-check errors with loadconst
-      + add ncgadd unit to m68k
-      * some bugfix of a_param_reg with LOC_CREFERENCE
+    constructor taicpu.op_cond_sym(op:tasmop;cond:TAsmCond;_op1:tasmsymbol);
+      begin
+         inherited create(op);
+         condition:=cond;
+         ops:=1;
+         loadsymbol(0,_op1,0);
+      end;
 
 
-    Revision 1.13  2002/11/17 16:32:04  carl
-      * memory optimization (3-4%) : cleanup of tai fields,
-         cleanup of tdef and tsym fields.
-      * make it work for m68k
 
 
-    Revision 1.12  2002/11/10 19:07:46  mazen
-    * SPARC calling mechanism almost OK (as in GCC./mppcsparc )
+    constructor taicpu.op_sym(op : tasmop;_op1 : tasmsymbol);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadsymbol(0,_op1,0);
+      end;
 
 
-    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
-    *** empty log message ***
+    constructor taicpu.op_sym_ofs(op : tasmop;_op1 : tasmsymbol;_op1ofs:longint);
+      begin
+         inherited create(op);
+         ops:=1;
+         loadsymbol(0,_op1,_op1ofs);
+      end;
 
 
-    Revision 1.9  2002/10/28 20:59:17  mazen
-    * TOpSize values changed S_L --> S_SW
 
 
-    Revision 1.8  2002/10/22 13:43:01  mazen
-    - cga.pas redueced to an empty unit
+    procedure InitAsm;
+      begin
+      end;
 
 
-    Revision 1.7  2002/10/20 19:01:38  mazen
-    + op_raddr_reg and op_caddr_reg added to fix functions prologue
 
 
-    Revision 1.6  2002/10/19 20:35:07  mazen
-    * carl's patch applied
+    procedure DoneAsm;
+      begin
+      end;
 
 
-    Revision 1.5  2002/10/15 09:00:28  mazen
-    * sone coding style modified
+end.
+{
+  $Log$
+  Revision 1.27  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
 
 
-    Revision 1.4  2002/10/13 21:46:07  mazen
-    * assembler output format fixed
 }
 }

Plik diff jest za duży
+ 540 - 860
compiler/sparc/cgcpu.pas


+ 782 - 612
compiler/sparc/cpubase.pas

@@ -1,8 +1,8 @@
-{******************************************************************************
+{
     $Id$
     $Id$
-    Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
+    Copyright (c) 1998-2002 by Florian Klaempfl
 
 
-    Contains the base types for the Scalable Processor ARChitecture (SPARC)
+    Contains the base types for the SPARC
 
 
     This program is free software; you can redistribute it and/or modify
     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
     it under the terms of the GNU General Public License as published by
@@ -17,255 +17,356 @@
     You should have received a copy of the GNU General Public License
     You should have received a copy of the GNU General Public License
     along with this program; if not, write to the Free Software
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************}
-unit cpuBase;
+
+ ****************************************************************************
+}
+{ This Unit contains the base types for the PowerPC
+}
+unit cpubase;
 
 
 {$i fpcdefs.inc}
 {$i fpcdefs.inc}
 
 
 interface
 interface
 
 
-  uses
-    globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
-
-const
-  {Size of the instruction table converted by nasmconv.pas}
-  maxinfolen=8;
-  {Defines the default address size for a processor}
-  OS_ADDR=OS_32;
-  {the natural int size for a processor}
-  OS_INT=OS_32;
-  {the maximum float size for a processor}
-  OS_FLOAT=OS_F64;
-  {the size of a vector register for a processor}
-  OS_VECTOR=OS_M64;
-type
+uses
+  strings,cutils,cclasses,aasmbase,cpuinfo,cginfo;
+
+
+{*****************************************************************************
+                                Assembler Opcodes
+*****************************************************************************}
+
+    type
 {$WARNING CPU32 opcodes do not fully include the Ultra SPRAC instruction set.}
 {$WARNING CPU32 opcodes do not fully include the Ultra SPRAC instruction set.}
-  { don't change the order of these opcodes! }
-  TAsmOp=({$INCLUDE opcode.inc});
-  op2strtable=array[TAsmOp]OF STRING[11];
-CONST
-  FirstOp=Low(TAsmOp);
-  LastOp=High(TAsmOp);
-  std_op2str:op2strtable=({$INCLUDE strinst.inc});
+      { don't change the order of these opcodes! }
+      TAsmOp=({$INCLUDE opcode.inc});
+
+      {# This should define the array of instructions as string }
+      op2strtable=array[tasmop] of string[11];
+
+    Const
+      {# First value of opcode enumeration }
+      firstop = low(tasmop);
+      {# Last value of opcode enumeration  }
+      lastop  = high(tasmop);
+
+      std_op2str:op2strtable=({$INCLUDE strinst.inc});
+
 {*****************************************************************************
 {*****************************************************************************
-                                Operand Sizes
+                                  Registers
 *****************************************************************************}
 *****************************************************************************}
-type
-  TOpSize=(S_NO,
-           S_B,{Byte}
-           S_H,{Half word}
-           S_W,{Word}
-           S_L:=S_W,
-           S_D,{Double Word}
-           S_Q,{Quad word}
-           S_IQ:=S_Q,
-           S_SB,{Signed byte}
-           S_SH,{Signed half word}
-           S_SW,{Signed word}
-           S_SD,{Signed double word}
-           S_SQ,{Signed quad word}
-           S_FS,{Float single word}
-           S_FX:=S_FS,
-           S_FD,{Float double word}
-           S_FQ,{Float quad word}
-           S_NEAR,
-           S_FAR,
-           S_SHORT);
-{*****************************************************************************}
-{                               Conditions                                    }
-{*****************************************************************************}
-type
-  TAsmCond=(C_None,
-    C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
-    C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
-    C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
-  );
-CONST
-  cond2str:array[TAsmCond] of string[3]=('',
-    'a','ae','b','be','c','e','g','ge','l','le','na','nae',
-    'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
-    'ns','nz','o','p','pe','po','s','z'
-  );
-  inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
-    C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
-    C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
-    C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
-  );
-CONST
-  CondAsmOps=3;
-  CondAsmOp:array[0..CondAsmOps-1] of TAsmOp=(A_FCMPd, A_JMPL, A_FCMPs);
-  CondAsmOpStr:array[0..CondAsmOps-1] of string[7]=('FCMPd','JMPL','FCMPs');
-{*****************************************************************************}
-{                                 Registers                                   }
-{*****************************************************************************}
-type
-  { enumeration for registers, don't change the order }
-  { it's used by the register size conversions        }
-  TCpuRegister=({$INCLUDE cpuregs.inc});
-  TOldRegister=TCpuRegister;
-  Tnewregister=word;
-  Tsuperregister=byte;
-  Tsubregister=byte;
-  Tregister=record
-    enum:TCpuRegister;
-    number:Tnewregister;
-  end;
-  TRegister64=PACKED RECORD
-  {A type to store register locations for 64 Bit values.}
-     RegLo,RegHi:TRegister;
-  end;
-  treg64=tregister64;{alias for compact code}
-  TRegisterSet=SET OF TCpuRegister;
-  Tsupregset=set of Tsuperregister;
-const
-  R_NO=R_NONE;
-  firstreg = Succ(R_NONE);
-  lastreg  = Pred(R_INTREGISTER);
-{General registers.}
-
-const
-  NR_NONE=$0000;
-  NR_NO=NR_NONE;
-  NR_G0=$0001;
-  NR_G1=$0002;
-  NR_G2=$0003;
-  NR_G3=$0004;
-  NR_G4=$0005;
-  NR_G5=$0006;
-  NR_G6=$0007;
-  NR_G7=$0008;
-  NR_O0=$0100;
-  NR_O1=$0200;
-  NR_O2=$0300;
-  NR_O3=$0400;
-  NR_O4=$0500;
-  NR_O5=$0600;
-  NR_O6=$0700;
-  NR_O7=$0800;
-  NR_L0=$0900;
-  NR_L1=$0A00;
-  NR_L2=$0B00;
-  NR_L3=$0C00;
-  NR_L4=$0D00;
-  NR_L5=$0E00;
-  NR_L6=$0F00;
-  NR_L7=$1000;
-  NR_I0=$1100;
-  NR_I1=$1200;
-  NR_I2=$1300;
-  NR_I3=$1400;
-  NR_I4=$1500;
-  NR_I5=$1600;
-  NR_I6=$1700;
-  NR_I7=$1800;
-{Floating point}
-  NR_F0=$2000;
-  NR_F1=$2000;
-  NR_F2=$2000;
-  NR_F3=$2000;
-  NR_F4=$2000;
-  NR_F5=$2000;
-  NR_F6=$2000;
-  NR_F7=$2000;
-  NR_F8=$2000;
-  NR_F9=$2000;
-  NR_F10=$2000;
-  NR_F11=$2000;
-  NR_F12=$2000;
-  NR_F13=$2000;
-  NR_F14=$2000;
-  NR_F15=$2000;
-  NR_F16=$2000;
-  NR_F17=$2000;
-  NR_F18=$2000;
-  NR_F19=$2000;
-  NR_F20=$2000;
-  NR_F21=$2000;
-  NR_F22=$2000;
-  NR_F23=$2000;
-  NR_F24=$2000;
-  NR_F25=$2000;
-  NR_F26=$2000;
-  NR_F27=$2000;
-  NR_F28=$2000;
-  NR_F29=$2000;
-  NR_F30=$2000;
-  NR_F31=$2000;
-{Coprocessor point}
-  NR_C0=$3000;
-  NR_C1=$3000;
-  NR_C2=$3000;
-  NR_C3=$3000;
-  NR_C4=$3000;
-  NR_C5=$3000;
-  NR_C6=$3000;
-  NR_C7=$3000;
-  NR_C8=$3000;
-  NR_C9=$3000;
-  NR_C10=$3000;
-  NR_C11=$3000;
-  NR_C12=$3000;
-  NR_C13=$3000;
-  NR_C14=$3000;
-  NR_C15=$3000;
-  NR_C16=$3000;
-  NR_C17=$3000;
-  NR_C18=$3000;
-  NR_C19=$3000;
-  NR_C20=$3000;
-  NR_C21=$3000;
-  NR_C22=$3000;
-  NR_C23=$3000;
-  NR_C24=$3000;
-  NR_C25=$3000;
-  NR_C26=$3000;
-  NR_C27=$3000;
-  NR_C28=$3000;
-  NR_C29=$3000;
-  NR_C30=$3000;
-  NR_C31=$3000;
-{ASR}
-  NR_ASR0=$4000;
-  NR_ASR1=$4000;
-  NR_ASR2=$4000;
-  NR_ASR3=$4000;
-  NR_ASR4=$4000;
-  NR_ASR5=$4000;
-  NR_ASR6=$4000;
-  NR_ASR7=$4000;
-  NR_ASR8=$4000;
-  NR_ASR9=$4000;
-  NR_ASR10=$4000;
-  NR_ASR11=$4000;
-  NR_ASR12=$4000;
-  NR_ASR13=$4000;
-  NR_ASR14=$4000;
-  NR_ASR15=$4000;
-  NR_ASR16=$4000;
-  NR_ASR17=$4000;
-  NR_ASR18=$4000;
-  NR_ASR19=$4000;
-  NR_ASR20=$4000;
-  NR_ASR21=$4000;
-  NR_ASR22=$4000;
-  NR_ASR23=$4000;
-  NR_ASR24=$4000;
-  NR_ASR25=$4000;
-  NR_ASR26=$4000;
-  NR_ASR27=$4000;
-  NR_ASR28=$4000;
-  NR_ASR29=$4000;
-  NR_ASR30=$4000;
-  NR_ASR31=$4000;
-{Floating point status/"front of queue" registers}
-  NR_FSR=$5000;
-  NR_FQ=$5001; { was $50001, probably typo (FK) }
-  NR_CSR=$5000;
-  NR_CQ=$5000;
-  NR_PSR=$5000;
-  NR_TBR=$5000;
-  NR_WIM=$5000;
-  NR_Y=$5000;
+
+    type
+      TCpuRegister=(
+        R_NO
+        {General purpose global registers}
+        ,R_G0{This register is usually set to zero and used as a scratch register}
+        ,R_G1,R_G2,R_G3,R_G4,R_G5,R_G6,R_G7
+        {General purpose out registers}
+        ,R_O0,R_O1,R_O2,R_O3,R_O4,R_O5,R_O6
+        ,R_O7{This register is used to save the address of the last CALL instruction}
+        {General purpose local registers}
+        ,R_L0
+        ,R_L1{This register is used to save the Program Counter (PC) after a Trap}
+        ,R_L2{This register is used to save the Program Counter (nPC) after a Trap}
+        ,R_L3,R_L4,R_L5,R_L6,R_L7
+        {General purpose in registers}
+        ,R_I0,R_I1,R_I2,R_I3,R_I4,R_I5,R_I6,R_I7
+        {Floating point registers}
+        ,R_F0,R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7
+        ,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13,R_F14,R_F15
+        ,R_F16,R_F17,R_F18,R_F19,R_F20,R_F21,R_F22,R_F23
+        ,R_F24,R_F25,R_F26,R_F27,R_F28,R_F29,R_F30,R_F31
+        {Floating point status/"front of queue" registers}
+        ,R_FSR,R_FQ
+        {Coprocessor registers}
+        ,R_C0,R_C1,R_C2,R_C3,R_C4,R_C5,R_C6,R_C7
+        ,R_C8,R_C9,R_C10,R_C11,R_C12,R_C13,R_C14,R_C15
+        ,R_C16,R_C17,R_C18,R_C19,R_C20,R_C21,R_C22,R_C23
+        ,R_C24,R_C25,R_C26,R_C27,R_C28,R_C29,R_C30,R_C31
+        {Coprocessor status/queue registers}
+        ,R_CSR
+        ,R_CQ
+        {Integer Unit control & status registers}
+        ,R_PSR{Processor Status Register : informs upon the program status}
+        ,R_TBR{Trap Base Register : saves the Trap vactor base address}
+        ,R_WIM{Window Invalid Mask : }
+        ,R_Y{Multiply/Devide Register : }
+        {Ancillary State Registers : these are implementation dependent registers and
+        thus, are not specified by the SPARC Reference Manual. I did choose the SUN's
+        implementation according to the Assembler Refernce Manual.(MN)}
+        ,R_ASR0,R_ASR1,R_ASR2,R_ASR3,R_ASR4,R_ASR5,R_ASR6,R_ASR7
+        ,R_ASR8,R_ASR9,R_ASR10,R_ASR11,R_ASR12,R_ASR13,R_ASR14,R_ASR15
+        ,R_ASR16,R_ASR17,R_ASR18,R_ASR19,R_ASR20,R_ASR21,R_ASR22,R_ASR23
+        ,R_ASR24,R_ASR25,R_ASR26,R_ASR27,R_ASR28,R_ASR29,R_ASR30,R_ASR31
+        {The following registers are just used with the new register allocator}
+        ,R_INTREGISTER,R_FLOATREGISTER,R_MMXREGISTER,R_KNIREGISTER
+      );
+
+      TOldRegister=TCpuRegister;
+
+      Tnewregister=word;
+      Tsuperregister=byte;
+      Tsubregister=byte;
+
+      Tregister=record
+        enum:Toldregister;
+        number:Tnewregister;
+      end;
+
+      {# Set type definition for registers }
+      tregisterset = set of Toldregister;
+      Tsupregset=set of Tsuperregister;
+
+      { A type to store register locations for 64 Bit values. }
+      tregister64 = packed record
+        reglo,reghi : tregister;
+      end;
+
+      { alias for compact code }
+      treg64 = tregister64;
+
+
+    Const
+      {# First register in the tregister enumeration }
+      firstreg = low(Toldregister);
+      {# Last register in the tregister enumeration }
+      lastreg  = R_ASR31;
+    type
+      {# Type definition for the array of string of register nnames }
+      treg2strtable = array[firstreg..lastreg] of string[7];
+
+    const
+      std_reg2str:treg2strtable=(
+        '',
+          {general purpose global registers}
+        '%g0','%g1','%g2','%g3','%g4','%g5','%g6','%g7',
+          {general purpose out registers}
+        '%o0','%o1','%o2','%o3','%o4','%o5','%o6','%o7',
+          {general purpose local registers}
+        '%l0','%l1','%l2','%l3','%l4','%l5','%l6','%l7',
+          {general purpose in registers}
+        '%i0','%i1','%i2','%i3','%i4','%i5','%i6','%i7',
+          {floating point registers}
+        '%f0','%f1','%f2','%f3','%f4','%f5','%f6','%f7',
+        '%f8','%f9','%f10','%f11','%f12','%f13','%f14','%f15',
+        '%f16','%f17','%f18','%f19','%f20','%f21','%f22','%f23',
+        '%f24','%f25','%f26','%f27','%f28','%f29','%f30','%f31',
+          {floating point status/"front of queue" registers}
+        '%fSR','%fQ',
+          {coprocessor registers}
+        '%c0','%c1','%c2','%c3','%c4','%c5','%c6','%c7',
+        '%c8','%c9','%c10','%c11','%c12','%c13','%c14','%c15',
+        '%c16','%c17','%c18','%c19','%c20','%c21','%c22','%c23',
+        '%c24','%c25','%c26','%c27','%c28','%c29','%c30','%c31',
+          {coprocessor status/queue registers}
+        '%csr','%cq',
+          {"Program status"/"Trap vactor base address register"/"Window invalid mask"/Y registers}
+        '%psr','%tbr','%wim','%y',
+          {Ancillary state registers}
+        '%asr0','%asr1','%asr2','%asr3','%asr4','%asr5','%asr6','%asr7',
+        '%asr8','%asr9','%asr10','%asr11','%asr12','%asr13','%asr14','%asr15',
+        '%asr16','%asr17','%asr18','%asr19','%asr20','%asr21','%asr22','%asr23',
+        '%asr24','%asr25','%asr26','%asr27','%asr28','%asr29','%asr30','%asr31'
+      );
+
+    {New register coding:}
+
+    {Special registers:}
+    const
+      NR_NO=$0000;  {Invalid register}
+
+    {Normal registers:}
+
+    {General purpose registers:}
+      NR_G0=$0100;
+      NR_G1=$0200;
+      NR_G2=$0300;
+      NR_G3=$0400;
+      NR_G4=$0500;
+      NR_G5=$0600;
+      NR_G6=$0700;
+      NR_G7=$0800;
+      NR_O0=$0900;
+      NR_O1=$0a00;
+      NR_O2=$0b00;
+      NR_O3=$0c00;
+      NR_O4=$0d00;
+      NR_O5=$0e00;
+      NR_O6=$0f00;
+      NR_O7=$1000;
+      NR_L0=$1100;
+      NR_L1=$1200;
+      NR_L2=$1300;
+      NR_L3=$1400;
+      NR_L4=$1500;
+      NR_L5=$1600;
+      NR_L6=$1700;
+      NR_L7=$1800;
+      NR_I0=$1900;
+      NR_I1=$1A00;
+      NR_I2=$1B00;
+      NR_I3=$1C00;
+      NR_I4=$1D00;
+      NR_I5=$1E00;
+      NR_I6=$1F00;
+      NR_I7=$2000;
+{$ifdef dummy}
+    { Floating point }
+      NR_F0=$2000;
+      NR_F1=$2000;
+      NR_F2=$2000;
+      NR_F3=$2000;
+      NR_F4=$2000;
+      NR_F5=$2000;
+      NR_F6=$2000;
+      NR_F7=$2000;
+      NR_F8=$2000;
+      NR_F9=$2000;
+      NR_F10=$2000;
+      NR_F11=$2000;
+      NR_F12=$2000;
+      NR_F13=$2000;
+      NR_F14=$2000;
+      NR_F15=$2000;
+      NR_F16=$2000;
+      NR_F17=$2000;
+      NR_F18=$2000;
+      NR_F19=$2000;
+      NR_F20=$2000;
+      NR_F21=$2000;
+      NR_F22=$2000;
+      NR_F23=$2000;
+      NR_F24=$2000;
+      NR_F25=$2000;
+      NR_F26=$2000;
+      NR_F27=$2000;
+      NR_F28=$2000;
+      NR_F29=$2000;
+      NR_F30=$2000;
+      NR_F31=$2000;
+    { Coprocessor point }
+      NR_C0=$3000;
+      NR_C1=$3000;
+      NR_C2=$3000;
+      NR_C3=$3000;
+      NR_C4=$3000;
+      NR_C5=$3000;
+      NR_C6=$3000;
+      NR_C7=$3000;
+      NR_C8=$3000;
+      NR_C9=$3000;
+      NR_C10=$3000;
+      NR_C11=$3000;
+      NR_C12=$3000;
+      NR_C13=$3000;
+      NR_C14=$3000;
+      NR_C15=$3000;
+      NR_C16=$3000;
+      NR_C17=$3000;
+      NR_C18=$3000;
+      NR_C19=$3000;
+      NR_C20=$3000;
+      NR_C21=$3000;
+      NR_C22=$3000;
+      NR_C23=$3000;
+      NR_C24=$3000;
+      NR_C25=$3000;
+      NR_C26=$3000;
+      NR_C27=$3000;
+      NR_C28=$3000;
+      NR_C29=$3000;
+      NR_C30=$3000;
+      NR_C31=$3000;
+    { ASR }
+      NR_ASR0=$4000;
+      NR_ASR1=$4000;
+      NR_ASR2=$4000;
+      NR_ASR3=$4000;
+      NR_ASR4=$4000;
+      NR_ASR5=$4000;
+      NR_ASR6=$4000;
+      NR_ASR7=$4000;
+      NR_ASR8=$4000;
+      NR_ASR9=$4000;
+      NR_ASR10=$4000;
+      NR_ASR11=$4000;
+      NR_ASR12=$4000;
+      NR_ASR13=$4000;
+      NR_ASR14=$4000;
+      NR_ASR15=$4000;
+      NR_ASR16=$4000;
+      NR_ASR17=$4000;
+      NR_ASR18=$4000;
+      NR_ASR19=$4000;
+      NR_ASR20=$4000;
+      NR_ASR21=$4000;
+      NR_ASR22=$4000;
+      NR_ASR23=$4000;
+      NR_ASR24=$4000;
+      NR_ASR25=$4000;
+      NR_ASR26=$4000;
+      NR_ASR27=$4000;
+      NR_ASR28=$4000;
+      NR_ASR29=$4000;
+      NR_ASR30=$4000;
+      NR_ASR31=$4000;
+    { Floating point status/"front of queue" registers }
+      NR_FSR=$5000;
+      NR_FQ=$5000;
+      NR_CSR=$5000;
+      NR_CQ=$5000;
+      NR_PSR=$5000;
+      NR_TBR=$5000;
+      NR_WIM=$5000;
+      NR_Y=$5000;
+{$endif dummy}
+
+    {Super registers:}
+      RS_NO=$00;
+      RS_O0=$01;
+      RS_O1=$02;
+      RS_O2=$03;
+      RS_O3=$04;
+      RS_O4=$05;
+      RS_O5=$06;
+      RS_O6=$07;
+      RS_O7=$08;
+      RS_L0=$09;
+      RS_L1=$0A;
+      RS_L2=$0B;
+      RS_L3=$0C;
+      RS_L4=$0D;
+      RS_L5=$0E;
+      RS_L6=$0F;
+      RS_L7=$10;
+      RS_I0=$11;
+      RS_I1=$12;
+      RS_I2=$13;
+      RS_I3=$14;
+      RS_I4=$15;
+      RS_I5=$16;
+      RS_I6=$17;
+      RS_I7=$18;
+      RS_G0=$19;
+      RS_G1=$1A;
+      RS_G2=$1B;
+      RS_G3=$1C;
+      RS_G4=$1D;
+      RS_G5=$1E;
+      RS_G6=$1F;
+      RS_G7=$20;
+
+      first_supreg = $01;
+      last_supreg = $20;
+
+      first_imreg = $21;
+      last_imreg = $ff;
+
+    { Subregisters, situation unknown!! }
+      R_SUBWHOLE=$00;
+      R_SUBL=$00;
+
 {Conversion between TCpuRegister and NewRegisters}
 {Conversion between TCpuRegister and NewRegisters}
   RegEnum2Number:array[TCpuRegister]of cardinal=(
   RegEnum2Number:array[TCpuRegister]of cardinal=(
     NR_NO,
     NR_NO,
@@ -410,121 +511,127 @@ const
     NR_NO,
     NR_NO,
     NR_NO
     NR_NO
   );
   );
-{Superregisters.}
-
-const
-  RS_O0=$01;
-  RS_O1=$02;
-  RS_O2=$03;
-  RS_O3=$04;
-  RS_O4=$05;
-  RS_O5=$06;
-  RS_O6=$07;
-  RS_O7=$08;
-  RS_L0=$09;
-  RS_L1=$0A;
-  RS_L2=$0B;
-  RS_L3=$0C;
-  RS_L4=$0D;
-  RS_L5=$0E;
-  RS_L6=$0F;
-  RS_L7=$10;
-  RS_I0=$11;
-  RS_I1=$12;
-  RS_I2=$13;
-  RS_I3=$14;
-  RS_I4=$15;
-  RS_I5=$16;
-  RS_I6=$17;
-  RS_I7=$18;
-  RS_G0=$19;
-  RS_G1=$1A;
-  RS_G2=$1B;
-  RS_G3=$1C;
-  RS_G4=$1D;
-  RS_G5=$1E;
-  RS_G6=$1F;
-  RS_G7=$20;
-
-  first_supreg = $01;
-  last_supreg = $20;
-
-  first_imreg = $21;
-  last_imreg = $ff;
-
-  {Subregisters; nothing known about.}
-  R_SUBWHOLE=$00;
-  R_SUBL=$00;
 
 
-type
-  reg2strtable=array[TCpuRegister] OF STRING[7];
-  TCpuReg=array[TCpuRegister]of TRegister;
-const
-  std_reg2str:reg2strtable=({$INCLUDE strregs.inc});
-  CpuReg:TCpuReg=({$INCLUDE registers.inc});
+{*****************************************************************************
+                                Conditions
+*****************************************************************************}
+
+    type
+      TAsmCond=(C_None,
+        C_A,C_AE,C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_NA,C_NAE,
+        C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_NO,C_NP,
+        C_NS,C_NZ,C_O,C_P,C_PE,C_PO,C_S,C_Z
+      );
+
+    const
+      cond2str:array[TAsmCond] of string[3]=('',
+        'a','ae','b','be','c','e','g','ge','l','le','na','nae',
+        'nb','nbe','nc','ne','ng','nge','nl','nle','no','np',
+        'ns','nz','o','p','pe','po','s','z'
+      );
+
+      inverse_cond:array[TAsmCond] of TAsmCond=(C_None,
+        C_NA,C_NAE,C_NB,C_NBE,C_NC,C_NE,C_NG,C_NGE,C_NL,C_NLE,C_A,C_AE,
+        C_B,C_BE,C_C,C_E,C_G,C_GE,C_L,C_LE,C_O,C_P,
+        C_S,C_Z,C_NO,C_NP,C_NP,C_P,C_NS,C_NZ
+      );
+
+    const
+      CondAsmOps=3;
+      CondAsmOp:array[0..CondAsmOps-1] of TAsmOp=(
+        A_FCMPd, A_JMPL, A_FCMPs
+      );
+      CondAsmOpStr:array[0..CondAsmOps-1] of string[7]=(
+        'FCMPd','JMPL','FCMPs'
+      );
+
 {*****************************************************************************
 {*****************************************************************************
                                    Flags
                                    Flags
 *****************************************************************************}
 *****************************************************************************}
-type
-  TResFlags=(
-    F_E,  {Equal}
-    F_NE, {Not Equal}
-    F_G,  {Greater}
-    F_L,  {Less}
-    F_GE, {Greater or Equal}
-    F_LE, {Less or Equal}
-    F_C,  {Carry}
-    F_NC, {Not Carry}
-    F_A,  {Above}
-    F_AE, {Above or Equal}
-    F_B,  {Below}
-    F_BE  {Below or Equal}
-  );
+
+    type
+      TResFlags=(
+        F_E,  {Equal}
+        F_NE, {Not Equal}
+        F_G,  {Greater}
+        F_L,  {Less}
+        F_GE, {Greater or Equal}
+        F_LE, {Less or Equal}
+        F_C,  {Carry}
+        F_NC, {Not Carry}
+        F_A,  {Above}
+        F_AE, {Above or Equal}
+        F_B,  {Below}
+        F_BE  {Below or Equal}
+      );
+
 {*****************************************************************************
 {*****************************************************************************
                                 Reference
                                 Reference
 *****************************************************************************}
 *****************************************************************************}
-type
-  TRefOptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
-
-  { since we have no full 32 bit offsets, we need to be able to specify the high
-    and low bits of the address of a symbol                                      }
-  trefsymaddr = (refs_full,refs_hi,refs_lo);
-
-  { immediate/reference record }
-  poperreference = ^treference;
-  Preference=^Treference;
-  treference = packed record
-     base,
-     index       : tregister;
-     offset      : LongInt;
-     symbol      : tasmsymbol;
-     symaddr     : trefsymaddr;
-     offsetfixup : LongInt;
-     options     : trefoptions;
-     alignment   : byte;
-  end;
-
-  { reference record }
-  PParaReference=^TParaReference;
-  TParaReference = packed record
-    Index : TRegister;
-    Offset : longint;
-  end;
+
+    type
+      TRefOptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
+
+      { since we have no full 32 bit offsets, we need to be able to specify the high
+        and low bits of the address of a symbol                                      }
+      trefsymaddr = (refs_full,refs_hi,refs_lo);
+
+      { reference record }
+      preference = ^treference;
+      treference = packed record
+         { base register, R_NO if none }
+         base,
+         { index register, R_NO if none }
+         index       : tregister;
+         { offset, 0 if none }
+         offset      : longint;
+         { symbol this reference refers to, nil if none }
+         symbol      : tasmsymbol;
+         { used in conjunction with symbols and offsets: refs_full means }
+         { means a full 32bit reference, refs_hi means the upper 16 bits }
+         { and refs_lo the lower 16 bits of the address                   }
+         symaddr     : trefsymaddr;
+         { changed when inlining and possibly in other cases, don't }
+         { set manually                                             }
+         offsetfixup : longint;
+         { used in conjunction with the previous field }
+         options     : trefoptions;
+         { alignment this reference is guaranteed to have }
+         alignment   : byte;
+      end;
+
+      { reference record }
+      pparareference = ^tparareference;
+      tparareference = packed record
+         index       : tregister;
+         offset      : aword;
+      end;
+
+    const
+      symaddr2str: array[trefsymaddr] of string[3] = ('','%hi','%lo');
+
 
 
 {*****************************************************************************
 {*****************************************************************************
-                                Operands
+                                Operand
+*****************************************************************************}
+
+    type
+      toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
+      toper=record
+        ot:LongInt;
+        case typ:toptype of
+          top_none:();
+          top_reg:(reg:tregister);
+          top_ref:(ref:preference);
+          top_const:(val:aword);
+          top_symbol:(sym:tasmsymbol;symofs:LongInt);
+      end;
+
+{*****************************************************************************
+                                Operand Sizes
 *****************************************************************************}
 *****************************************************************************}
-  { Types of operand }
-  toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
-  toper=record
-    ot:LongInt;
-    case typ:toptype of
-      top_none:();
-      top_reg:(reg:tregister);
-      top_ref:(ref:poperreference);
-      top_const:(val:aword);
-      top_symbol:(sym:tasmsymbol;symofs:LongInt);
-  end;
+
+{$ifdef dummy}
 {*****************************************************************************
 {*****************************************************************************
                              Argument Classification
                              Argument Classification
 *****************************************************************************}
 *****************************************************************************}
@@ -539,310 +646,373 @@ type
      AC_FPUUP,
      AC_FPUUP,
      AC_SSE,
      AC_SSE,
      AC_SSEUP);
      AC_SSEUP);
+{$endif dummy}
 
 
 {*****************************************************************************
 {*****************************************************************************
                                Generic Location
                                Generic Location
 *****************************************************************************}
 *****************************************************************************}
-type
-  { tparamlocation describes where a parameter for a procedure is stored.
-    References are given from the caller's point of view. The usual TLocation isn't
-    used, because contains a lot of unnessary fields. }
-  TParaLocation=packed record
-    Size:TCGSize;
-    Loc:TCGLoc;
-    sp_fixup:LongInt;
-    CASE TCGLoc OF
-      LOC_REFERENCE:(reference:tparareference);
-            { segment in reference at the same place as in loc_register }
-      LOC_REGISTER,LOC_CREGISTER : (
-        CASE LongInt OF
+
+    type
+      { tparamlocation describes where a parameter for a procedure is stored.
+        References are given from the caller's point of view. The usual
+        TLocation isn't used, because contains a lot of unnessary fields.
+      }
+      tparalocation = packed record
+         size : TCGSize;
+         { The location type where the parameter is passed, usually
+           LOC_REFERENCE,LOC_REGISTER or LOC_FPUREGISTER
+         }
+         loc  : TCGLoc;
+         { The stack pointer must be decreased by this value before
+           the parameter is copied to the given destination.
+           This allows to "encode" pushes with tparalocation.
+           On the PowerPC, this field is unsed but it is there
+           because several generic code accesses it.
+         }
+         sp_fixup : longint;
+         case TCGLoc of
+            LOC_REFERENCE : (reference : tparareference);
+            LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
+              LOC_REGISTER,LOC_CREGISTER : (
+              case longint of
+                1 : (register,registerhigh : tregister);
+                { overlay a registerlow }
+                2 : (registerlow : tregister);
+                { overlay a 64 Bit register type }
+                3 : (reg64 : tregister64);
+                4 : (register64 : tregister64);
+            );
+      end;
+
+      treglocation = packed record
+        case longint of
           1 : (register,registerhigh : tregister);
           1 : (register,registerhigh : tregister);
-              { overlay a registerlow }
+          { overlay a registerlow }
           2 : (registerlow : tregister);
           2 : (registerlow : tregister);
-              { overlay a 64 Bit register type }
+          { overlay a 64 Bit register type }
           3 : (reg64 : tregister64);
           3 : (reg64 : tregister64);
           4 : (register64 : tregister64);
           4 : (register64 : tregister64);
-        );
-      { it's only for better handling }
-      LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
-    end;
+       end;
 
 
-    TLocation=packed record
-         loc  : TCGLoc;
+
+      tlocation = packed record
          size : TCGSize;
          size : TCGSize;
-         case TCGLoc of
-            LOC_FLAGS : (resflags : tresflags);
+         loc : tcgloc;
+         case tcgloc of
+            LOC_CREFERENCE,LOC_REFERENCE : (reference : treference);
             LOC_CONSTANT : (
             LOC_CONSTANT : (
               case longint of
               case longint of
+{$ifdef FPC_BIG_ENDIAN}
+                1 : (_valuedummy,value : AWord);
+{$else FPC_BIG_ENDIAN}
                 1 : (value : AWord);
                 1 : (value : AWord);
-                2 : (valuelow, valuehigh:AWord);
+{$endif FPC_BIG_ENDIAN}
+                { can't do this, this layout depends on the host cpu. Use }
+                { lo(valueqword)/hi(valueqword) instead (JM)              }
+                { 2 : (valuelow, valuehigh:AWord);                        }
                 { overlay a complete 64 Bit value }
                 { overlay a complete 64 Bit value }
                 3 : (valueqword : qword);
                 3 : (valueqword : qword);
               );
               );
-            LOC_CREFERENCE,
-            LOC_REFERENCE : (reference : treference);
-            { segment in reference at the same place as in loc_register }
-            LOC_REGISTER,LOC_CREGISTER : (
-              case longint of
-                1 : (register,registerhigh,segment : tregister);
-                { overlay a registerlow }
-                2 : (registerlow : tregister);
-                { overlay a 64 Bit register type }
-                3 : (reg64 : tregister64);
-                4 : (register64 : tregister64);
-              );
-            { it's only for better handling }
-            LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
+            LOC_FPUREGISTER, LOC_CFPUREGISTER, LOC_MMREGISTER, LOC_CMMREGISTER,
+              LOC_REGISTER,LOC_CREGISTER : (
+                case longint of
+                  1 : (registerlow,registerhigh : tregister);
+                  2 : (register : tregister);
+                  { overlay a 64 Bit register type }
+                  3 : (reg64 : tregister64);
+                  4 : (register64 : tregister64);
+                );
+            LOC_FLAGS : (resflags : tresflags);
       end;
       end;
+
 {*****************************************************************************
 {*****************************************************************************
                                  Constants
                                  Constants
 *****************************************************************************}
 *****************************************************************************}
 
 
-const
-  general_registers = [R_G0..R_I7];
-  general_superregisters = [RS_O0..RS_I7];
-  { legend:                                                                }
-  { xxxregs = set of all possibly used registers of that type in the code  }
-  {           generator                                                    }
-  { usableregsxxx = set of all 32bit components of registers that can be   }
-  {           possible allocated to a regvar or using getregisterxxx (this }
-  {           excludes registers which can be only used for parameter      }
-  {           passing on ABI's that define this)                           }
-  { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
-  IntRegs=[R_G0..R_I7];
-  usableregsint=[RS_O0..RS_I7];
-  c_countusableregsint = 24;
-  fpuregs=[R_F0..R_F31];
-  usableregsfpu=[R_F0..R_F31];
-  c_countusableregsfpu=32;
-  mmregs=[];
-  usableregsmm=[];
-  c_countusableregsmm=0;
-  { no distinction on this platform }
-  maxaddrregs = 0;
-  addrregs    = [];
-  usableregsaddr = [];
-  c_countusableregsaddr = 0;
-
-
-  firstsaveintreg = RS_O0;
-  lastsaveintreg = RS_I7;
-  firstsavefpureg = R_F0;
-  lastsavefpureg = R_F31;
-  firstsavemmreg = R_NONE;
-  lastsavemmreg = R_NONE;
-  lowsavereg = R_G0;
-  highsavereg = R_I7;
-
-  ALL_REGISTERS = [lowsavereg..highsavereg];
-  ALL_INTREGISTERS = [1..255];
-
-  lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
-    LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
+    const
+      max_operands = 3;
+
+      {# Constant defining possibly all registers which might require saving }
+      ALL_REGISTERS = [R_G0..R_I7];
+      ALL_INTREGISTERS = [1..255];
+
+      general_registers = [R_G0..R_I7];
+      general_superregisters = [RS_O0..RS_I7];
+
+      {# low and high of the available maximum width integer general purpose }
+      { registers                                                            }
+      LoGPReg = R_G0;
+      HiGPReg = R_I7;
+
+      {# low and high of every possible width general purpose register (same as }
+      { above on most architctures apart from the 80x86)                        }
+      LoReg = R_G0;
+      HiReg = R_I7;
+
+      {# Table of registers which can be allocated by the code generator
+         internally, when generating the code.
+      }
+      { legend:                                                                }
+      { xxxregs = set of all possibly used registers of that type in the code  }
+      {           generator                                                    }
+      { usableregsxxx = set of all 32bit components of registers that can be   }
+      {           possible allocated to a regvar or using getregisterxxx (this }
+      {           excludes registers which can be only used for parameter      }
+      {           passing on ABI's that define this)                           }
+      { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
+
+      maxintregs = 8;
+      intregs = [R_G0..R_I7];
+      usableregsint = [RS_O0..RS_I7];
+      c_countusableregsint = 24;
+
+      maxfpuregs = 8;
+      fpuregs=[R_F0..R_F31];
+      usableregsfpu=[R_F0..R_F31];
+      c_countusableregsfpu=32;
+
+      mmregs     = [];
+      usableregsmm  = [];
+      c_countusableregsmm  = 0;
+
+      { no distinction on this platform }
+      maxaddrregs = 0;
+      addrregs    = [];
+      usableregsaddr = [];
+      c_countusableregsaddr = 0;
+
+      firstsaveintreg = RS_O0;
+      lastsaveintreg = RS_I7;
+      firstsavefpureg = R_F0;
+      lastsavefpureg = R_F31;
+      firstsavemmreg = R_NO;
+      lastsavemmreg = R_NO;
+
+      maxvarregs = 8;
+      varregs : Array [1..maxvarregs] of Tnewregister =
+                (RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7);
+
+      maxfpuvarregs = 1;
+      fpuvarregs : Array [1..maxfpuvarregs] of Toldregister =
+                (R_F2);
+
+      {
+      max_param_regs_int = 6;
+      param_regs_int: Array[1..max_param_regs_int] of Toldregister =
+        (R_3,R_4,R_5,R_6,R_7,R_8,R_9,R_10);
+
+      max_param_regs_fpu = 13;
+      param_regs_fpu: Array[1..max_param_regs_fpu] of Toldregister =
+        (R_F1,R_F2,R_F3,R_F4,R_F5,R_F6,R_F7,R_F8,R_F9,R_F10,R_F11,R_F12,R_F13);
+
+      max_param_regs_mm = 13;
+      param_regs_mm: Array[1..max_param_regs_mm] of Toldregister =
+        (R_M1,R_M2,R_M3,R_M4,R_M5,R_M6,R_M7,R_M8,R_M9,R_M10,R_M11,R_M12,R_M13);
+      }
+
+      {# Registers which are defined as scratch and no need to save across
+         routine calls or in assembler blocks.
+      }
+      max_scratch_regs = 2;
+      scratch_regs: Array[1..max_scratch_regs] of Tsuperregister = (RS_O7,RS_G2);
+
+{*****************************************************************************
+                          Default generic sizes
+*****************************************************************************}
+
+      {# Defines the default address size for a processor, }
+      OS_ADDR = OS_32;
+      {# the natural int size for a processor,             }
+      OS_INT = OS_32;
+      {# the maximum float size for a processor,           }
+      OS_FLOAT = OS_F64;
+      {# the size of a vector register for a processor     }
+      OS_VECTOR = OS_M64;
+
 {*****************************************************************************
 {*****************************************************************************
                                GDB Information
                                GDB Information
 *****************************************************************************}
 *****************************************************************************}
-  {# Register indexes for stabs information, when some parameters or variables
-  are stored in registers.
-  Taken from rs6000.h (DBX_REGISTER_NUMBER) from GCC 3.x source code.}
-  stab_regindex:array[TCpuRegister]OF ShortInt=({$INCLUDE stabregi.inc});
-{*************************** generic register names **************************}
-  stack_pointer_reg   = R_O6;
-  NR_STACK_POINTER_REG = NR_O6;
-  RS_STACK_POINTER_REG = RS_O6;
-  frame_pointer_reg   = R_I6;
-  NR_FRAME_POINTER_REG = NR_I6;
-  RS_FRAME_POINTER_REG = RS_I6;
-  {the return_result_reg, is used inside the called function to store its return
-  value when that is a scalar value otherwise a pointer to the address of the
-  result is placed inside it}
-  return_result_reg   = R_I0;
-  NR_RETURN_RESULT_REG = NR_I0;
-  RS_RETURN_RESULT_REG = RS_I0;
-  {the function_result_reg contains the function result after a call to a scalar
-  function othewise it contains a pointer to the returned result}
-  function_result_reg = R_O0;
-  NR_FUNCTION_RESULT_REG = NR_O0;
-  RS_FUNCTION_RESULT_REG = RS_O0;
-  self_pointer_reg  =R_G5;
-  NR_SELF_POINTER_REG = NR_G5;
-{  RS_SELF_POINTER_REG = RS_G5;}
-  {There is no accumulator in the SPARC architecture. There are just families
-  of registers. All registers belonging to the same family are identical except
-  in the "global registers" family where GO is different from the others :
-  G0 gives always 0 when it is red and thows away any value written to it.
-  Nevertheless, scalar routine results are returned onto R_O0.}
-  accumulator     = R_O0;
-  NR_ACCUMULATOR = NR_O0;
-  RS_ACCUMULATOR = RS_O1;
-  accumulatorhigh = R_O1;
-  NR_ACCUMULATORHIGH = NR_O1;
-  RS_ACCUMULATORHIGH = RS_O1;
-  fpu_result_reg  = R_F0;
-  mmresultreg     = R_G0;
-
-{*****************************************************************************}
-{                        GCC /ABI linking information                         }
-{*****************************************************************************}
-  { Registers which must be saved when calling a routine declared as cppdecl,
-    cdecl, stdcall, safecall, palmossyscall. The registers saved should be the ones
-    as defined in the target ABI and / or GCC.
-
-    This value can be deduced from the CALLED_USED_REGISTERS array in the GCC
-    source.
-  }
-  std_saved_registers=[];
-
-  {  Required parameter alignment when calling a routine declared as stdcall and
-     cdecl. The alignment value should be the one defined by GCC or the target ABI.
-
-     The value of this constant is equal to the constant
-     PARM_BOUNDARY / BITS_PER_UNIT in the GCC source. }
-  std_param_align=4;
-
-  { Registers which are defined as scratch and no need to save across routine
-    calls or in assembler blocks.}
-  ScratchRegsCount=2;
-  scratch_regs:array[1..ScratchRegsCount] OF Tsuperregister=(RS_O7,RS_G2);
-
-  { low and high of the available maximum width integer general purpose
-    registers                                                           }
-  LoGPReg = R_G0;
-  HiGPReg = R_I7;
-
-  { low and high of every possible width general purpose register (same as
-    above on most architctures apart from the 80x86)                       }
-  LoReg = R_G0;
-  HiReg = R_I7;
-
-  cpuflags = [];
-
-  { sizes }
-  pointersize   = 4;
-  extended_size = 8;  { SPARC architecture uses IEEE floating point numbers}
-  mmreg_size = 8;
-  SizePostfix_pointer = S_SW;
+
+      {# Register indexes for stabs information, when some
+         parameters or variables are stored in registers.
+
+         Taken from rs6000.h (DBX_REGISTER_NUMBER)
+         from GCC 3.x source code.
+      }
+
+      stab_regindex : array[firstreg..lastreg] of shortint =
+      (
+        0{R_NO}
+        {General purpose global registers}
+        ,1{R_G0}{This register is usually set to zero and used as a scratch register}
+        ,2{R_G1},3{R_G2},4{R_G3},5{R_G4},6{R_G5},7{R_G6},8{R_G7}
+        {General purpose out registers}
+        ,9{R_O0},10{R_O1},11{R_O2},12{R_O3},13{R_O4},14{R_O5},15{R_O6}
+        ,16{R_O7}{This register is used to save the address of the last CALL instruction}
+        {General purpose local registers}
+        ,16{R_L0}
+        ,17{R_L1}{This register is used to save the Program Counter (PC) after a Trap}
+        ,18{R_L2}{This register is used to save the Program Counter (nPC) after a Trap}
+        ,19{R_L3},20{R_L4},21{R_L5},22{R_L6},23{R_L7}
+        {General purpose in registers}
+        ,24{R_I0},25{R_I1},26{R_I2},27{R_I3},28{R_I4},29{R_I5},30{R_I6},31{R_I7}
+        {Floating point registers}
+        ,32{R_F0},33{R_F1},34{R_F2},35{R_F3},36{R_F4},37{R_F5},38{R_F6},39{R_F7}
+        ,40{R_F8},41{R_F9},42{R_F10},43{R_F11},44{R_F12},45{R_F13},46{R_F14},47{R_F15}
+        ,48{R_F16},49{R_F17},50{R_F18},51{R_F19},52{R_F20},53{R_F21},54{R_F22},55{R_F23}
+        ,56{R_F24},57{R_F25},58{R_F26},59{R_F27},60{R_F28},61{R_F29},62{R_F30},63{R_F31}
+        {Floating point status/"front of queue" registers}
+        ,64{R_FSR},65{R_FQ}
+        {Coprocessor registers}
+        ,66{R_C0},67{R_C1},68{R_C2},69{R_C3},70{R_C4},71{R_C5},72{R_C6},73{R_C7}
+        ,74{R_C8},75{R_C9},76{R_C10},77{R_C11},78{R_C12},79{R_C13},80{R_C14},81{R_C15}
+        ,82{R_C16},83{R_C17},84{R_C18},85{R_C19},86{R_C20},87{R_C21},88{R_C22},89{R_C23}
+        ,90{R_C24},91{R_C25},92{R_C26},93{R_C27},94{R_C28},95{R_C29},96{R_C30},98{R_C31}
+        {Coprocessor status/queue registers}
+        ,99{R_CSR}
+        ,100{R_CQ}
+        {Integer Unit control & status registers}
+        ,101{R_PSR}{Processor Status Register : informs upon the program status}
+        ,102{R_TBR}{Trap Base Register : saves the Trap vactor base address}
+        ,103{R_WIM}{Window Invalid Mask : }
+        ,104{R_Y}{Multiply/Devide Register : }
+        {Ancillary State Registers : these are implementation dependent registers and
+        thus, are not specified by the SPARC Reference Manual. I did choose the SUN's
+        implementation according to the Assembler Refernce Manual.(MN)}
+        ,105{R_ASR0},106{R_ASR1},107{R_ASR2},108{R_ASR3},109{R_ASR4},110{R_ASR5},111{R_ASR6},112{R_ASR7}
+        ,113{R_ASR8},114{R_ASR9},115{R_ASR10},116{R_ASR11},117{R_ASR12},118{R_ASR13},119{R_ASR14},120{R_ASR15}
+        ,121{R_ASR16},122{R_ASR17},123{R_ASR18},124{R_ASR19},125{R_ASR20},126{R_ASR21},127{R_ASR22},127{R_ASR23}
+        ,127{R_ASR24},127{R_ASR25},127{R_ASR26},127{R_ASR27},127{R_ASR28},127{R_ASR29},127{R_ASR30},127{R_ASR31}
+      );
 
 
 
 
 {*****************************************************************************
 {*****************************************************************************
-                              Instruction table
+                          Generic Register names
 *****************************************************************************}
 *****************************************************************************}
 
 
-{$ifndef NOAG386BIN}
-type
-  tinsentry=packed record
-    opcode  : tasmop;
-    ops     : byte;
-    optypes : array[0..2] of LongInt;
-    code    : array[0..maxinfolen] of char;
-    flags   : LongInt;
-  end;
-  pinsentry=^tinsentry;
-
-  TInsTabCache=array[TasmOp] of LongInt;
-  PInsTabCache=^TInsTabCache;
-VAR
-  InsTabCache : PInsTabCache;
-{$endif NOAG386BIN}
+      {# Stack pointer register }
+      NR_STACK_POINTER_REG = NR_O6;
+      RS_STACK_POINTER_REG = RS_O6;
+      {# Frame pointer register }
+      NR_FRAME_POINTER_REG = NR_I6;
+      RS_FRAME_POINTER_REG = RS_I6;
+      {# Register for addressing absolute data in a position independant way,
+         such as in PIC code. The exact meaning is ABI specific. For
+         further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
+
+         Taken from GCC rs6000.h
+      }
+{$warning As indicated in rs6000.h, but can't find it anywhere else!}
+      {PIC_OFFSET_REG = R_30;}
+      { the return_result_reg, is used inside the called function to store its return
+      value when that is a scalar value otherwise a pointer to the address of the
+      result is placed inside it }
+      NR_FUNCTION_RETURN_REG = NR_I0;
+      RS_FUNCTION_RETURN_REG = RS_I0;
+      { The high part of 64bit value returned by this function }
+      NR_FUNCTION_RETURNHIGH_REG = NR_I1;
+      RS_FUNCTION_RETURNHIGH_REG = RS_I1;
+      { the FUNCTION_RESULT_REG contains the function result after a call to a scalar
+        function othewise it contains a pointer to the returned result}
+      NR_FUNCTION_RESULT_REG = NR_O0;
+      RS_FUNCTION_RESULT_REG = RS_O0;
+      { The high part of 64bit value returned from a function is available in this register }
+      NR_FUNCTION_RESULTHIGH_REG = NR_O1;
+      RS_FUNCTION_RESULTHIGH_REG = RS_O1;
+
+      FPU_RESULT_REG = R_F0;
+      mmresultreg = R_NO;
+
+{*****************************************************************************
+                       GCC /ABI linking information
+*****************************************************************************}
+
+      {# Registers which must be saved when calling a routine declared as
+         cppdecl, cdecl, stdcall, safecall, palmossyscall. The registers
+         saved should be the ones as defined in the target ABI and / or GCC.
+
+         This value can be deduced from CALLED_USED_REGISTERS array in the
+         GCC source.
+      }
+      std_saved_registers = [];
+
+      {# Required parameter alignment when calling a routine declared as
+         stdcall and cdecl. The alignment value should be the one defined
+         by GCC or the target ABI.
+
+         The value of this constant is equal to the constant
+         PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.
+      }
+      std_param_align = 4;  { for 32-bit version only }
+
+{*****************************************************************************
+                            CPU Dependent Constants
+*****************************************************************************}
+
+
 {*****************************************************************************
 {*****************************************************************************
                                   Helpers
                                   Helpers
 *****************************************************************************}
 *****************************************************************************}
-const
-  maxvarregs=8;
-  VarRegs:array[1..maxvarregs] of tnewregister = (
-             RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7
-        );
-  maxfpuvarregs = 8;
-  max_operands = 3;
-  maxintregs = maxvarregs;
-  maxfpuregs = maxfpuvarregs;
-  max_scratch_regs=8;
-
-
-function is_calljmp(o:tasmop):boolean;
-function flags_to_cond(CONST f:TResFlags):TAsmCond;
-procedure convert_register_to_enum(var Reg:Tregister);
-function cgsize2subreg(s:Tcgsize):Tsubregister;
+
+    function  is_calljmp(o:tasmop):boolean;
+
+    function  flags_to_cond(const f: TResFlags) : TAsmCond;
+    procedure convert_register_to_enum(var r:Tregister);
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
 
 
 implementation
 implementation
 
 
-  uses
-    verbose;
-  const
-    CallJmpOp=[A_JMPL..A_CBccc];
-
-  function is_calljmp(o:tasmop):boolean;
-    begin
-      if o in CallJmpOp
-      then
-        is_calljmp:=true
-      else
-        is_calljmp:=false;
-    end;
-
-function flags_to_cond(const f:TResFlags):TAsmCond;
-  CONST
-    flags_2_cond:array[TResFlags]OF TAsmCond=
-    (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
-  BEGIN
-    result:=flags_2_cond[f];
-  end;
-
-procedure convert_register_to_enum(var Reg:Tregister);
-  begin
-    with Reg do
-      if(enum=R_INTREGISTER)
-      then
-        if(number<=RegEnum2Number[R_I7])
-        then
-          begin
-            enum:=Low(enum);
-            repeat
-              Inc(enum);
-            until(number=RegEnum2Number[enum])or(enum=High(enum));
-          end
-        else
-          internalerror(200301082);
-  end;
-
-function cgsize2subreg(s:Tcgsize):Tsubregister;
-begin
-  cgsize2subreg:=R_SUBWHOLE;
-end;
-end.
-{
-  $Log$
-  Revision 1.34  2003-05-28 23:18:31  florian
-    * started to fix and clean up the sparc port
+    uses
+      verbose;
+
+{*****************************************************************************
+                                  Helpers
+*****************************************************************************}
+
+    function is_calljmp(o:tasmop):boolean;
+      const
+        CallJmpOp=[A_JMPL..A_CBccc];
+      begin
+        is_calljmp:=(o in CallJmpOp);
+      end;
 
 
-  Revision 1.33  2003/05/26 22:08:42  mazen
-  + RegEnum2Number to ease handling register pairs
-  * changed convert_register_to_enum to use above
-    array
 
 
-  Revision 1.32  2003/05/23 21:10:50  florian
-    * fixed sparc compiler compilation
+    function flags_to_cond(const f:TResFlags):TAsmCond;
+      const
+        flags_2_cond:array[TResFlags] of TAsmCond=
+          (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_C,C_NC,C_A,C_AE,C_B,C_BE);
+      begin
+        result:=flags_2_cond[f];
+      end;
 
 
-  Revision 1.31  2003/05/22 16:11:22  florian
-    * fixed sparc compilation partially
 
 
-  Revision 1.30  2003/05/06 14:58:46  mazen
-  - non used constants OT_* removed
-  * some keywords moved lower case
+    procedure convert_register_to_enum(var r:Tregister);
+      begin
+        with R do
+          if(enum=R_INTREGISTER) then
+            if(number<=RegEnum2Number[R_I7]) then
+              begin
+                enum:=Low(enum);
+                repeat
+                  Inc(enum);
+                until(number=RegEnum2Number[enum])or(enum=High(enum));
+              end
+            else
+              internalerror(200301082);
+      end;
 
 
-  Revision 1.29  2003/04/29 12:03:52  mazen
-  * TOldRegister isnow just an alias for TCpuRegister
-  * TCpuRegister is used to define cpu register set physically available
-  + CpuRegs array to easially create correspondence between TCpuRegister and TRegister
 
 
-  Revision 1.28  2003/04/28 09:46:30  mazen
-  + max_scratch_regs variable added because requested by common compiler code
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+      begin
+        cgsize2subreg:=R_SUBWHOLE;
+      end;
 
 
-  Revision 1.27  2003/04/23 13:35:39  peter
-    * fix sparc compile
+end.
+{
+  $Log$
+  Revision 1.35  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
 
 
-  Revision 1.26  2003/04/23 12:35:35  florian
-    * fixed several issues with powerpc
-    + applied a patch from Jonas for nested function calls (PowerPC only)
-    * ...
 }
 }

+ 11 - 9
compiler/sparc/cpugas.pas

@@ -48,20 +48,17 @@ unit cpugas;
           begin
           begin
             inc(offset,offsetfixup);
             inc(offset,offsetfixup);
             offsetfixup:=0;
             offsetfixup:=0;
-            if base.enum>lastreg then
+            if (base.enum<>R_INTREGISTER) or (index.enum<>R_INTREGISTER) then
               internalerror(200301081);
               internalerror(200301081);
-            if index.enum>lastreg then
-              internalerror(200301081);
-
             if assigned(symbol) then
             if assigned(symbol) then
               begin
               begin
+                 if (base.number<>NR_NO) or (index.number<>NR_NO) then
+                   internalerror(2003052601);
                  GetReferenceString:=symbol.name;
                  GetReferenceString:=symbol.name;
                  if offset>0 then
                  if offset>0 then
                    GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
                    GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
                  else if offset<0 then
                  else if offset<0 then
                    GetReferenceString:=GetReferenceString+ToStr(offset);
                    GetReferenceString:=GetReferenceString+ToStr(offset);
-                 if (base.enum<>R_NONE) or (index.enum<>R_NONE) then
-                   internalerror(2003052601);
                  if symaddr=refs_hi then
                  if symaddr=refs_hi then
                    GetReferenceString:='%hi('+GetReferenceString+')'
                    GetReferenceString:='%hi('+GetReferenceString+')'
                  else if symaddr=refs_lo then
                  else if symaddr=refs_lo then
@@ -71,9 +68,9 @@ unit cpugas;
               end
               end
             else
             else
               begin
               begin
-                if base.enum<>R_NONE then
+                if base.number<>NR_NO then
                   GetReferenceString:=std_reg2str[base.enum]+'+';
                   GetReferenceString:=std_reg2str[base.enum]+'+';
-                if index.enum<>R_NONE then
+                if index.number<>NR_NO then
                   GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
                   GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
                 if Offset<>0 then
                 if Offset<>0 then
                    internalerror(2003052603);
                    internalerror(2003052603);
@@ -199,7 +196,12 @@ begin
 end.
 end.
 {
 {
     $Log$
     $Log$
-    Revision 1.15  2003-05-28 23:18:31  florian
+    Revision 1.16  2003-05-30 23:57:08  peter
+      * more sparc cleanup
+      * accumulator removed, splitted in function_return_reg (called) and
+        function_result_reg (caller)
+
+    Revision 1.15  2003/05/28 23:18:31  florian
       * started to fix and clean up the sparc port
       * started to fix and clean up the sparc port
 
 
     Revision 1.14  2003/05/07 11:55:34  mazen
     Revision 1.14  2003/05/07 11:55:34  mazen

+ 267 - 240
compiler/sparc/cpupara.pas

@@ -1,8 +1,8 @@
-{******************************************************************************
+{
     $Id$
     $Id$
-    Copyright (c) 2002 by Florian Klaempfl
+    Copyright (c) 1998-2002 by Florian Klaempfl
 
 
-    PowerPC specific calling conventions
+    Calling conventions for the SPARC
 
 
     This program is free software; you can redistribute it and/or modify
     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
     it under the terms of the GNU General Public License as published by
@@ -19,269 +19,296 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *****************************************************************************}
  *****************************************************************************}
 unit cpupara;
 unit cpupara;
-{SPARC specific calling conventions are handled by this unit}
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
+
 interface
 interface
-uses
-  cpubase,
-  symconst,symbase,symtype,symdef,paramgr;
-type
-  TSparcParaManager=class(TParaManager)
-    {Returns a structure giving the information on the storage of the parameter
-    (which must be an integer parameter)
-    @param(nr Parameter number of routine, starting from 1)}
-    function GetIntParaLoc(nr:longint):TParaLocation;override;
-    {Creates location information related to the parameter of the function}
-    procedure create_param_loc_info(p:TAbstractProcDef);override;
-    {Returns the location where the invisible parameter for structured function
-    results will be passed.}
-    function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
-  end;
+
+    uses
+      cpubase,
+      symconst,symbase,symtype,symdef,paramgr;
+
+    type
+      TSparcParaManager=class(TParaManager)
+        {Returns a structure giving the information on the storage of the parameter
+        (which must be an integer parameter)
+        @param(nr Parameter number of routine, starting from 1)}
+        function GetIntParaLoc(nr:longint):TParaLocation;override;
+        {Creates location information related to the parameter of the function}
+        procedure create_param_loc_info(p:TAbstractProcDef);override;
+        {Returns the location where the invisible parameter for structured function
+        results will be passed.}
+        function GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;override;
+      end;
+
+
 implementation
 implementation
-uses
-  verbose,
-  cpuinfo,cginfo,cgbase,
-  defutil;
-function TSparcParaManager.GetIntParaLoc(nr:longint):TParaLocation;
-  begin
-    if nr<1
-    then
-      InternalError(2002100806);
-    FillChar(GetIntParaLoc,SizeOf(TParaLocation),0);
-    Dec(nr);
-    with GetIntParaLoc do
-      if nr<6
-      then{The six first parameters are passed into registers}
-        begin
-          loc:=LOC_REGISTER;
-          register.enum:=ToldRegister(LongInt(R_i0)+nr);
-        end
-      else{The other parameters are passed into the frame}
-        begin
-          loc:=LOC_REFERENCE;
-          reference.index.enum:=frame_pointer_reg;
-          reference.offset:=-68-nr*4;
-        end;
-  end;
-function GetParaLoc(p:TDef):TCGLoc;
-  begin
-{Later, the LOC_REFERENCE is in most cases changed into LOC_REGISTER if
-push_addr_param for the def is true}
-    case p.DefType of
-      OrdDef:
-        GetParaLoc:=LOC_REGISTER;
-      FloatDef:
-        GetParaLoc:=LOC_FPUREGISTER;
-      enumdef:
-        getparaloc:=LOC_REGISTER;
-      pointerdef:
-        getparaloc:=LOC_REGISTER;
-      formaldef:
-        getparaloc:=LOC_REGISTER;
-      classrefdef:
-        getparaloc:=LOC_REGISTER;
-      recorddef:
-        getparaloc:=LOC_REFERENCE;
-      objectdef:
-        if is_object(p)
-        then
-          getparaloc:=LOC_REFERENCE
-        else
-          getparaloc:=LOC_REGISTER;
-      stringdef:
-        if is_shortstring(p) or is_longstring(p)
-        then
-          getparaloc:=LOC_REFERENCE
-        else
-          getparaloc:=LOC_REGISTER;
-      procvardef:
-        if (po_methodpointer in tprocvardef(p).procoptions)
-        then
-          getparaloc:=LOC_REFERENCE
-        else
-          getparaloc:=LOC_REGISTER;
-      filedef:
-        getparaloc:=LOC_REGISTER;
-      arraydef:
-        getparaloc:=LOC_REFERENCE;
-      setdef:
-        if is_smallset(p)
-        then
-          getparaloc:=LOC_REGISTER
-        else
-          getparaloc:=LOC_REFERENCE;
-      variantdef:
-        getparaloc:=LOC_REFERENCE;
-      { avoid problems with errornous definitions }
-      errordef:
-        getparaloc:=LOC_REGISTER;
-      else
-        internalerror(2002071001);
-    end;
-  end;
-procedure TSparcParaManager.create_param_loc_info(p:TAbstractProcDef);
-  var
-    nextintreg,nextfloatreg:tregister;
-    stack_offset:aword;
-    hp:tparaitem;
-    loc:tcgloc;
-    is_64bit:boolean;
-  begin
-    nextintreg.enum:=R_O0;
-    nextfloatreg.enum:=R_F0;
-    stack_offset:=92;
-    hp:=TParaItem(p.para.First);
-    while assigned(hp) do
+
+    uses
+      verbose,
+      cpuinfo,cginfo,cgbase,
+      defutil;
+
+    function TSparcParaManager.GetIntParaLoc(nr:longint):TParaLocation;
       begin
       begin
-        loc:=GetParaLoc(hp.paratype.def);
-        case loc of
-          LOC_REGISTER:
+        if nr<1 then
+          InternalError(2002100806);
+        FillChar(GetIntParaLoc,SizeOf(TParaLocation),0);
+        Dec(nr);
+        with GetIntParaLoc do
+         begin
+           { The six first parameters are passed into registers }
+           if nr<6 then
             begin
             begin
-              hp.paraloc.size:=def_cgSize(hp.paratype.def);
-              if hp.paraloc.size=OS_NO
-              then
-                hp.paraloc.size:=OS_ADDR;
-              is_64bit:=hp.paraloc.size in [OS_64,OS_S64];
-              if NextIntReg.enum<=ToldRegister(ord(R_i5)-ord(is_64bit))
-              then
+              loc:=LOC_REGISTER;
+              register.enum:=R_INTREGISTER;
+              register.number:=(RS_I0+nr) shl 8;
+            end
+           else
+           { The other parameters are passed into the frame }
+            begin
+              loc:=LOC_REFERENCE;
+              reference.index.enum:=R_INTREGISTER;
+              reference.index.number:=NR_FRAME_POINTER_REG;
+              reference.offset:=-68-nr*4;
+            end;
+         end;
+      end;
+
+
+    function GetParaLoc(p:TDef):TCGLoc;
+      begin
+        { Later, the LOC_REFERENCE is in most cases changed into
+          LOC_REGISTER if push_addr_param for the def is true}
+        case p.DefType of
+          OrdDef:
+            GetParaLoc:=LOC_REGISTER;
+          FloatDef:
+            GetParaLoc:=LOC_FPUREGISTER;
+          enumdef:
+            getparaloc:=LOC_REGISTER;
+          pointerdef:
+            getparaloc:=LOC_REGISTER;
+          formaldef:
+            getparaloc:=LOC_REGISTER;
+          classrefdef:
+            getparaloc:=LOC_REGISTER;
+          recorddef:
+            getparaloc:=LOC_REFERENCE;
+          objectdef:
+            if is_object(p) then
+              getparaloc:=LOC_REFERENCE
+            else
+              getparaloc:=LOC_REGISTER;
+          stringdef:
+            if is_shortstring(p) or is_longstring(p) then
+              getparaloc:=LOC_REFERENCE
+            else
+              getparaloc:=LOC_REGISTER;
+          procvardef:
+            if (po_methodpointer in tprocvardef(p).procoptions) then
+              getparaloc:=LOC_REFERENCE
+            else
+              getparaloc:=LOC_REGISTER;
+          filedef:
+            getparaloc:=LOC_REGISTER;
+          arraydef:
+            getparaloc:=LOC_REFERENCE;
+          setdef:
+            if is_smallset(p) then
+              getparaloc:=LOC_REGISTER
+            else
+              getparaloc:=LOC_REFERENCE;
+          variantdef:
+            getparaloc:=LOC_REFERENCE;
+          { avoid problems with errornous definitions }
+          errordef:
+            getparaloc:=LOC_REGISTER;
+          else
+            internalerror(2002071001);
+        end;
+      end;
+
+
+    procedure TSparcParaManager.create_param_loc_info(p:TAbstractProcDef);
+      var
+        nextintreg : tsuperregister;
+        nextfloatreg : toldregister;
+        stack_offset : longint;
+        hp : tparaitem;
+        loc : tcgloc;
+        is_64bit : boolean;
+      begin
+        nextintreg:=RS_O0;
+        nextfloatreg:=R_F0;
+        stack_offset:=92;
+        hp:=TParaItem(p.para.First);
+        while assigned(hp) do
+          begin
+            loc:=GetParaLoc(hp.paratype.def);
+            case loc of
+              LOC_REGISTER:
                 begin
                 begin
-                  hp.paraloc.loc:=LOC_REGISTER;
-                  hp.paraloc.registerlow:=NextIntReg;
-                  inc(NextIntReg.enum);
-                  if is_64bit
-                  then
+                  hp.paraloc.size:=def_cgSize(hp.paratype.def);
+                  if hp.paraloc.size=OS_NO then
+                    hp.paraloc.size:=OS_ADDR;
+                  is_64bit:=(hp.paraloc.size in [OS_64,OS_S64]);
+                  if NextIntReg<=RS_I5-ord(is_64bit) then
                     begin
                     begin
-                      hp.paraloc.registerhigh:=nextintreg;
-                      inc(nextintreg.enum);
-                    end;
-                end
-              else
-                begin
-                  nextintreg.enum:=R_i6;
-                  hp.paraloc.loc:=LOC_REFERENCE;
-                  hp.paraloc.reference.index.enum:=stack_pointer_reg;
-                  hp.paraloc.reference.offset:=stack_offset;
-                  if not is_64bit
-                  then
-                    inc(stack_offset,4)
+                      hp.paraloc.loc:=LOC_REGISTER;
+                      hp.paraloc.registerlow.enum:=R_INTREGISTER;
+                      hp.paraloc.registerlow.number:=NextIntReg shl 8;
+                      inc(NextIntReg);
+                      if is_64bit then
+                        begin
+                          hp.paraloc.registerhigh.enum:=R_INTREGISTER;
+                          hp.paraloc.registerhigh.number:=nextintreg shl 8;
+                          inc(nextintreg);
+                        end;
+                    end
                   else
                   else
-                    inc(stack_offset,8);
+                    begin
+                      nextintreg:=RS_I6;
+                      hp.paraloc.loc:=LOC_REFERENCE;
+                      hp.paraloc.reference.index.enum:=R_INTREGISTER;
+                      hp.paraloc.reference.index.number:=NR_STACK_POINTER_REG;
+                      hp.paraloc.reference.offset:=stack_offset;
+                      if not is_64bit then
+                        inc(stack_offset,4)
+                      else
+                        inc(stack_offset,8);
+                    end;
                 end;
                 end;
-            end;
-          LOC_FPUREGISTER:
-            begin
-              if hp.paratyp in [vs_var,vs_out]
-              then
+
+              LOC_FPUREGISTER:
                 begin
                 begin
-                  if NextIntReg.enum<=R_O5
-                  then
+                  if hp.paratyp in [vs_var,vs_out] then
                     begin
                     begin
-                      hp.paraloc.size:=OS_ADDR;
-                      hp.paraloc.loc:=LOC_REGISTER;
-                      hp.paraloc.register:=nextintreg;
-                      inc(nextintreg.enum);
+                      if NextIntReg<=RS_O5 then
+                        begin
+                          hp.paraloc.size:=OS_ADDR;
+                          hp.paraloc.loc:=LOC_REGISTER;
+                          hp.paraloc.register.enum:=R_INTREGISTER;
+                          hp.paraloc.register.number:=nextintreg shl 8;
+                          inc(nextintreg);
+                        end
+                      else
+                        begin
+                          {!!!!!!!}
+                          hp.paraloc.size:=def_cgsize(hp.paratype.def);
+                          internalerror(2002071006);
+                        end;
+                    end
+                  else if nextfloatreg<=R_F10 then
+                    begin
+                      hp.paraloc.size:=def_cgsize(hp.paratype.def);
+                      hp.paraloc.loc:=LOC_FPUREGISTER;
+                      hp.paraloc.register.enum:=nextfloatreg;
+                      inc(nextfloatreg);
                     end
                     end
                   else
                   else
                     begin
                     begin
                       {!!!!!!!}
                       {!!!!!!!}
                       hp.paraloc.size:=def_cgsize(hp.paratype.def);
                       hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                      internalerror(2002071006);
+                      internalerror(2002071004);
                     end;
                     end;
-                end
-              else if nextfloatreg.enum<=R_F10 then
-                begin
-                  hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                  hp.paraloc.loc:=LOC_FPUREGISTER;
-                  hp.paraloc.register:=nextfloatreg;
-                  inc(nextfloatreg.enum);
-                end
-              else
+                end;
+
+              LOC_REFERENCE:
                 begin
                 begin
-                  {!!!!!!!}
-                  hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                  internalerror(2002071004);
+                   hp.paraloc.size:=OS_ADDR;
+                   if push_addr_param(hp.paratype.def,p.proccalloption) or (hp.paratyp in [vs_var,vs_out]) then
+                     begin
+                        if nextintreg<=RS_O5 then
+                          begin
+                             hp.paraloc.loc:=LOC_REGISTER;
+                             hp.paraloc.register.enum:=R_INTREGISTER;
+                             hp.paraloc.register.number:=nextintreg shl 8;
+                             inc(nextintreg);
+                          end
+                        else
+                           begin
+                              hp.paraloc.loc:=LOC_REFERENCE;
+                              hp.paraloc.reference.index.enum:=R_INTREGISTER;
+                              hp.paraloc.reference.index.number:=NR_STACK_POINTER_REG;
+                              hp.paraloc.reference.offset:=stack_offset;
+                              inc(stack_offset,4);
+                          end;
+                     end
+                   else
+                     begin
+                        hp.paraloc.loc:=LOC_REFERENCE;
+                        hp.paraloc.reference.index.enum:=R_INTREGISTER;
+                        hp.paraloc.reference.index.number:=NR_STACK_POINTER_REG;
+                        hp.paraloc.reference.offset:=stack_offset;
+                        inc(stack_offset,hp.paratype.def.size);
+                     end;
                 end;
                 end;
+
+              else
+                internalerror(2002071002);
             end;
             end;
-                 LOC_REFERENCE:
-                   begin
-                      hp.paraloc.size:=OS_ADDR;
-                      if push_addr_param(hp.paratype.def,p.proccalloption) or (hp.paratyp in [vs_var,vs_out]) then
-                        begin
-                           if nextintreg.enum<=R_O5 then
-                             begin
-                                hp.paraloc.loc:=LOC_REGISTER;
-                                hp.paraloc.register:=nextintreg;
-                                inc(nextintreg.enum);
-                             end
-                           else
-                              begin
-                                 hp.paraloc.loc:=LOC_REFERENCE;
-                                 hp.paraloc.reference.index.enum:=stack_pointer_reg;
-                                 hp.paraloc.reference.offset:=stack_offset;
-                                 inc(stack_offset,4);
-                             end;
-                        end
-                      else
-                        begin
-                           hp.paraloc.loc:=LOC_REFERENCE;
-                           hp.paraloc.reference.index.enum:=stack_pointer_reg;
-                           hp.paraloc.reference.offset:=stack_offset;
-                           inc(stack_offset,hp.paratype.def.size);
-                        end;
-                   end;
-                 else
-                   internalerror(2002071002);
-        end;
-      hp:=TParaItem(hp.Next);
-    end;
-  end;
-function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
-  begin
-    with GetFuncRetParaLoc do
-      case p.rettype.def.deftype of
-        orddef,enumdef:
-          begin
-            loc:=LOC_REGISTER;
-            register.enum:=return_result_reg;
-            size:=def_cgsize(p.rettype.def);
-            if size in [OS_S64,OS_64]
-            then
-              RegisterHigh.enum:=R_I1;
-          end;
-        floatdef:
-          begin
-            loc:=LOC_FPUREGISTER;
-            register.enum:=R_F1;
-            size:=def_cgsize(p.rettype.def);
+            hp:=TParaItem(hp.Next);
           end;
           end;
-        setdef,
-        variantdef,
-        pointerdef,
-        formaldef,
-        classrefdef,
-        recorddef,
-        objectdef,
-        stringdef,
-        procvardef,
-        filedef,
-        arraydef,
-        errordef:
-          begin
-            loc:=LOC_REFERENCE;
-            reference.index.enum:=frame_pointer_reg;
-            reference.offset:=64;
-            size:=OS_ADDR;
-          end;
-        else
-          internalerror(2002090903);
       end;
       end;
-  end;
+
+
+    function tSparcParaManager.GetFuncRetParaLoc(p:TAbstractProcDef):TParaLocation;
+      begin
+        with GetFuncRetParaLoc do
+         begin
+           case p.rettype.def.deftype of
+             orddef,enumdef:
+               begin
+                 loc:=LOC_REGISTER;
+                 register.enum:=R_INTREGISTER;
+                 register.number:=NR_FUNCTION_RETURN_REG;
+                 size:=def_cgsize(p.rettype.def);
+                 if size in [OS_S64,OS_64] then
+                   internalerror(200305309);
+               end;
+             floatdef:
+               begin
+                 loc:=LOC_FPUREGISTER;
+                 register.enum:=R_F1;
+                 size:=def_cgsize(p.rettype.def);
+               end;
+             setdef,
+             variantdef,
+             pointerdef,
+             formaldef,
+             classrefdef,
+             recorddef,
+             objectdef,
+             stringdef,
+             procvardef,
+             filedef,
+             arraydef,
+             errordef:
+               begin
+                 loc:=LOC_REFERENCE;
+                 reference.index.enum:=R_INTREGISTER;
+                 reference.index.number:=NR_FRAME_POINTER_REG;
+                 reference.offset:=64;
+                 size:=OS_ADDR;
+               end;
+             else
+               internalerror(2002090903);
+           end;
+         end;
+      end;
+
 begin
 begin
    ParaManager:=TSparcParaManager.create;
    ParaManager:=TSparcParaManager.create;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.16  2003-04-23 13:35:39  peter
+  Revision 1.17  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.16  2003/04/23 13:35:39  peter
     * fix sparc compile
     * fix sparc compile
 
 
   Revision 1.15  2003/04/23 12:35:35  florian
   Revision 1.15  2003/04/23 12:35:35  florian

+ 7 - 2
compiler/sparc/cpupi.pas

@@ -101,7 +101,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.15  2003-05-23 22:33:48  florian
+  Revision 1.16  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.15  2003/05/23 22:33:48  florian
     * fix some small flaws which prevent sparc linux system unit from compiling
     * fix some small flaws which prevent sparc linux system unit from compiling
     * some reformatting done
     * some reformatting done
 
 
@@ -133,7 +138,7 @@ end.
   + added debug output on screen with -an command line option
   + added debug output on screen with -an command line option
 
 
   Revision 1.8  2002/11/17 17:49:09  mazen
   Revision 1.8  2002/11/17 17:49:09  mazen
-  + return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
+  + return_result_reg and FUNCTION_RESULT_REG are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
 
 
   Revision 1.7  2002/11/14 21:42:08  mazen
   Revision 1.7  2002/11/14 21:42:08  mazen
   * fixing return value variable address
   * fixing return value variable address

+ 6 - 3
compiler/sparc/cputarg.pas

@@ -48,14 +48,17 @@ implementation
 **************************************}
 **************************************}
 
 
       ,CpuGas
       ,CpuGas
-      ,ogcoff
-      ,ogelf
       ;
       ;
 
 
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2003-05-23 21:10:50  florian
+  Revision 1.4  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.3  2003/05/23 21:10:50  florian
     * fixed sparc compiler compilation
     * fixed sparc compiler compilation
 
 
   Revision 1.2  2002/09/07 15:25:14  peter
   Revision 1.2  2002/09/07 15:25:14  peter

+ 56 - 65
compiler/sparc/ncpuadd.pas

@@ -34,8 +34,8 @@ type
     procedure second_addfloat;
     procedure second_addfloat;
     function GetResFlags(unsigned:Boolean):TResFlags;
     function GetResFlags(unsigned:Boolean):TResFlags;
     procedure emit_compare(unsigned:boolean);
     procedure emit_compare(unsigned:boolean);
-    procedure left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
-    procedure emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extra_not,mboverflow:Boolean);
+    procedure left_must_be_reg(OpSize:TcgSize;NoSwap:Boolean);
+    procedure emit_generic_code(op:TAsmOp;OpSize:TcgSize;unsigned,extra_not,mboverflow:Boolean);
     procedure emit_op_right_left(op:TAsmOp);
     procedure emit_op_right_left(op:TAsmOp);
     procedure Load_left_right(cmpop,load_constants:Boolean);
     procedure Load_left_right(cmpop,load_constants:Boolean);
     procedure pass_left_and_right;
     procedure pass_left_and_right;
@@ -47,12 +47,11 @@ uses
   cutils,verbose,globals,
   cutils,verbose,globals,
   symconst,symdef,SymType,paramgr,
   symconst,symdef,SymType,paramgr,
   aasmbase,aasmtai,aasmcpu,defutil,htypechk,
   aasmbase,aasmtai,aasmcpu,defutil,htypechk,
-  cgbase,pass_2,regvars,
+  cpuinfo,cgbase,pass_2,regvars,
   cpupara,
   cpupara,
   ncon,nset,
   ncon,nset,
   ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
   ncgutil,tgobj,rgobj,rgcpu,cgobj,cg64f32;
-const
-  opsize_2_cgSize:array[S_B..S_L]of TCgSize=(OS_8,OS_16,OS_32);
+
 procedure TSparcAddNode.clear_left_right(cmpop:Boolean);
 procedure TSparcAddNode.clear_left_right(cmpop:Boolean);
   begin
   begin
     if(right.location.loc in [LOC_REGISTER,LOC_FPUREGISTER])and(cmpop or(location.register.enum <> right.location.register.enum))
     if(right.location.loc in [LOC_REGISTER,LOC_FPUREGISTER])and(cmpop or(location.register.enum <> right.location.register.enum))
@@ -160,7 +159,7 @@ procedure TSparcAddNode.second_addboolean;
               then
               then
                 exprasmlist.concat(taicpu.op_reg_reg(A_JMPL,left.location.register,right.location.register))
                 exprasmlist.concat(taicpu.op_reg_reg(A_JMPL,left.location.register,right.location.register))
               else
               else
-                exprasmlist.concat(taicpu.op_reg_const(A_JMPL,left.location.register,longint(right.location.value)));
+                exprasmlist.concat(taicpu.op_reg_const(A_JMPL,left.location.register,right.location.value));
               location.resflags := GetResFlags(true);
               location.resflags := GetResFlags(true);
             end;
             end;
           else
           else
@@ -280,7 +279,7 @@ function TSparcAddNode.GetResFlags(unsigned:Boolean):TResFlags;
             end;
             end;
     end;
     end;
   end;
   end;
-procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
+procedure TSparcAddNode.left_must_be_reg(OpSize:TcgSize;NoSwap:Boolean);
   begin
   begin
     if(left.location.loc=LOC_REGISTER)
     if(left.location.loc=LOC_REGISTER)
     then
     then
@@ -296,10 +295,10 @@ procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
       begin
       begin
 {maybe we can reuse a constant register when the operation is a comparison that
 {maybe we can reuse a constant register when the operation is a comparison that
 doesn't change the value of the register}
 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,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
       end;
       end;
   end;
   end;
-procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extra_not,mboverflow:Boolean);
+procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TcgSize;unsigned,extra_not,mboverflow:Boolean);
   var
   var
     power:LongInt;
     power:LongInt;
     hl4:TAsmLabel;
     hl4:TAsmLabel;
@@ -398,12 +397,12 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
         IF cs_check_overflow IN aktlocalswitches
         IF cs_check_overflow IN aktlocalswitches
         THEN
         THEN
           begin
           begin
-      //      getlabel(hl4);
+            objectlibrary.getlabel(hl4);
             IF unsigned
             IF unsigned
             THEN
             THEN
-              exprasmList.concat(Taicpu.Op_sym(A_JMPL,S_NO,hl4))
+              exprasmList.concat(Taicpu.Op_sym(A_JMPL,hl4))
             ELSE
             ELSE
-              exprasmList.concat(Taicpu.Op_sym(A_JMPL,S_NO,hl4));
+              exprasmList.concat(Taicpu.Op_sym(A_JMPL,hl4));
             cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
             cg.a_call_name(exprasmlist,'FPC_OVERFLOW');
             cg.a_label(exprasmlist,hl4);
             cg.a_label(exprasmlist,hl4);
           end;
           end;
@@ -425,7 +424,7 @@ procedure TSparcAddNode.emit_compare(unsigned:boolean);
     then
     then
       begin
       begin
 {$ifdef ExtDebug}
 {$ifdef ExtDebug}
-        if (right.location.size in [OS_64,OS_S64]) and (hi(right.location.valueqword)<>0) and ((hi(right.location.valueqword)<>$ffffffff) or unsigned)
+        if (right.location.size in [OS_64,OS_S64]) and (hi(right.location.valueqword)<>0) and ((hi(right.location.valueqword)<>aword($ffffffff)) or unsigned)
         then
         then
           internalerror(2002080301);
           internalerror(2002080301);
 {$endif extdebug}
 {$endif extdebug}
@@ -463,7 +462,7 @@ procedure TSparcAddNode.emit_compare(unsigned:boolean);
           if useconst
           if useconst
           then
           then
             exprasmlist.concat(taicpu.op_reg_const(op,
             exprasmlist.concat(taicpu.op_reg_const(op,
-              left.location.register,longint(right.location.value)))
+              left.location.register,right.location.value))
           else
           else
             begin
             begin
               exprasmlist.concat(taicpu.op_reg_reg(op,left.location.register,tmpreg));
               exprasmlist.concat(taicpu.op_reg_reg(op,left.location.register,tmpreg));
@@ -495,7 +494,6 @@ procedure TSparcAddNode.second_add64bit;
   var
   var
     op         : TOpCG;
     op         : TOpCG;
     op1,op2    : TAsmOp;
     op1,op2    : TAsmOp;
-    hl4        : tasmlabel;
     cmpop,
     cmpop,
     unsigned   : boolean;
     unsigned   : boolean;
     r          : Tregister;
     r          : Tregister;
@@ -600,6 +598,7 @@ procedure TSparcAddNode.second_add64bit;
 
 
     var
     var
       tempreg64: tregister64;
       tempreg64: tregister64;
+      zeroreg : tregister;
 
 
       begin
       begin
         firstcomplex(self);
         firstcomplex(self);
@@ -681,7 +680,7 @@ procedure TSparcAddNode.second_add64bit;
                             tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                             tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                           else
                             tempreg64.reglo := left.location.registerlow;
                             tempreg64.reglo := left.location.registerlow;
-                          if ((right.location.valueqword shr 32) <> 0) then
+                          if (hi(right.location.valueqword) <> 0) then
                             tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                             tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                           else
                             tempreg64.reghi := left.location.registerhigh;
                             tempreg64.reghi := left.location.registerhigh;
@@ -690,25 +689,25 @@ procedure TSparcAddNode.second_add64bit;
                       if (right.location.valueqword <> 0) then
                       if (right.location.valueqword <> 0) then
                         { negative values can be handled using SUB, }
                         { negative values can be handled using SUB, }
                         { positive values < 65535 using XOR.        }
                         { positive values < 65535 using XOR.        }
-                        if (longint(right.location.valueqword) >= -32767) and
-                           (longint(right.location.valueqword) < 0) then
+                        if (longint(lo(right.location.valueqword)) >= -32767) and
+                           (longint(lo(right.location.valueqword)) < 0) then
                           cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
                           cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
-                            right.location.valueqword,
+                            lo(right.location.valueqword),
                             left.location.registerlow,tempreg64.reglo)
                             left.location.registerlow,tempreg64.reglo)
                         else
                         else
                           cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
                           cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
-                            right.location.valueqword,
+                            lo(right.location.valueqword),
                             left.location.registerlow,tempreg64.reglo);
                             left.location.registerlow,tempreg64.reglo);
 
 
-                      if ((right.location.valueqword shr 32) <> 0) then
-                        if (longint(right.location.valueqword shr 32) >= -32767) and
-                           (longint(right.location.valueqword shr 32) < 0) then
+                      if (hi(right.location.valueqword)<>0) then
+                        if (longint(hi(right.location.valueqword))>= -32767) and
+                           (longint(hi(right.location.valueqword)) < 0) then
                           cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
                           cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
-                            right.location.valueqword shr 32,
+                            hi(right.location.valueqword),
                             left.location.registerhigh,tempreg64.reghi)
                             left.location.registerhigh,tempreg64.reghi)
                         else
                         else
                           cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
                           cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
-                            right.location.valueqword shr 32,
+                            hi(right.location.valueqword),
                             left.location.registerhigh,tempreg64.reghi);
                             left.location.registerhigh,tempreg64.reghi);
                     end
                     end
                   else
                   else
@@ -720,14 +719,14 @@ procedure TSparcAddNode.second_add64bit;
                          tempreg64);
                          tempreg64);
                     end;
                     end;
 
 
-                  r.enum:=R_G0;
-                  cg.a_reg_alloc(exprasmlist,r);
-                  exprasmlist.concat(taicpu.op_reg_reg_reg(A_OR,r,
-                    tempreg64.reglo,tempreg64.reghi));
-                  cg.a_reg_dealloc(exprasmlist,r);
-                  if (tempreg64.reglo.enum <> left.location.registerlow.enum) then
+                  zeroreg.enum:=R_INTREGISTER;
+                  zeroreg.number:=NR_G0;
+                  cg.a_reg_alloc(exprasmlist,zeroreg);
+                  exprasmlist.concat(taicpu.op_reg_reg_reg(A_OR,zeroreg,tempreg64.reglo,tempreg64.reghi));
+                  cg.a_reg_dealloc(exprasmlist,zeroreg);
+                  if (tempreg64.reglo.number <> left.location.registerlow.number) then
                     cg.free_scratch_reg(exprasmlist,tempreg64.reglo);
                     cg.free_scratch_reg(exprasmlist,tempreg64.reglo);
-                  if (tempreg64.reghi.enum <> left.location.registerhigh.enum) then
+                  if (tempreg64.reghi.number <> left.location.registerhigh.number) then
                     cg.free_scratch_reg(exprasmlist,tempreg64.reghi);
                     cg.free_scratch_reg(exprasmlist,tempreg64.reghi);
 
 
                   location_reset(location,LOC_FLAGS,OS_NO);
                   location_reset(location,LOC_FLAGS,OS_NO);
@@ -735,7 +734,7 @@ procedure TSparcAddNode.second_add64bit;
                 end;
                 end;
               xorn,orn,andn,addn:
               xorn,orn,andn,addn:
                 begin
                 begin
-                  if (location.registerlow.enum = R_NO) then
+                  if (location.registerlow.number = NR_NO) then
                     begin
                     begin
                       location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                       location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                       location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                       location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -757,7 +756,7 @@ procedure TSparcAddNode.second_add64bit;
 
 
                   if left.location.loc <> LOC_CONSTANT then
                   if left.location.loc <> LOC_CONSTANT then
                     begin
                     begin
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                         begin
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -775,7 +774,7 @@ procedure TSparcAddNode.second_add64bit;
                     end
                     end
                   else if ((left.location.valueqword shr 32) = 0) then
                   else if ((left.location.valueqword shr 32) = 0) then
                     begin
                     begin
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                         begin
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -802,7 +801,7 @@ procedure TSparcAddNode.second_add64bit;
                   else if (left.location.valueqword = 0) then
                   else if (left.location.valueqword = 0) then
                     begin
                     begin
                       // (const32 shl 32) - reg64
                       // (const32 shl 32) - reg64
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                         begin
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -821,7 +820,7 @@ procedure TSparcAddNode.second_add64bit;
                         def_cgsize(left.resulttype.def),true);
                         def_cgsize(left.resulttype.def),true);
                       if (left.location.loc = LOC_REGISTER) then
                       if (left.location.loc = LOC_REGISTER) then
                         location.register64 := left.location.register64
                         location.register64 := left.location.register64
-                      else if (location.registerlow.enum = R_NO) then
+                      else if (location.registerlow.number = NR_NO) then
                         begin
                         begin
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -1009,30 +1008,21 @@ procedure TSparcAddNode.set_result_location(cmpOp,unsigned:Boolean);
     ELSE
     ELSE
       location_copy(location,left.location);
       location_copy(location,left.location);
   end;
   end;
-function def_opsize(p1:tdef):topsize;
-  begin
-    case p1.size of
-      1:def_opsize:=S_B;
-      2:def_opsize:=S_W;
-      4:def_opsize:=S_L;
-      8:def_opsize:=S_L;
-      else
-        InternalError(130820001);
-    end;
-  end;
+
+
 procedure TSparcAddNode.pass_2;
 procedure TSparcAddNode.pass_2;
 {is also being used for "xor", and "mul", "sub", or and comparative operators}
 {is also being used for "xor", and "mul", "sub", or and comparative operators}
   var
   var
     popeax,popedx,pushedfpu,mboverflow,cmpop:Boolean;
     popeax,popedx,pushedfpu,mboverflow,cmpop:Boolean;
     op:TAsmOp;
     op:TAsmOp;
     power:LongInt;
     power:LongInt;
-    OpSize:TOpSize;
+    OpSize:TcgSize;
     unsigned:Boolean;{true, if unsigned types are compared}
     unsigned:Boolean;{true, if unsigned types are compared}
     extra_not:Boolean;
     extra_not:Boolean;
     cgop:TOpCg;
     cgop:TOpCg;
   begin
   begin
-{to make it more readable, string and set (not smallset!) have their own
-procedures }
+    { to make it more readable, string and set (not smallset!) have their own
+      procedures }
     case left.resulttype.def.deftype of
     case left.resulttype.def.deftype of
       orddef:
       orddef:
         if is_boolean(left.resulttype.def)and is_boolean(right.resulttype.def)
         if is_boolean(left.resulttype.def)and is_boolean(right.resulttype.def)
@@ -1070,7 +1060,7 @@ procedures }
     cmpop:=nodetype in [ltn,lten,gtn,gten,equaln,unequaln];
     cmpop:=nodetype in [ltn,lten,gtn,gten,equaln,unequaln];
     unsigned:=not(is_signed(left.resulttype.def))or
     unsigned:=not(is_signed(left.resulttype.def))or
               not(is_signed(right.resulttype.def));
               not(is_signed(right.resulttype.def));
-    opsize:=def_opsize(left.resulttype.def);
+    opsize:=def_cgsize(left.resulttype.def);
     pass_left_and_right;
     pass_left_and_right;
     { set result location }
     { set result location }
     if not cmpop
     if not cmpop
@@ -1079,8 +1069,7 @@ procedures }
     else
     else
       location_reset(location,LOC_FLAGS,OS_NO);
       location_reset(location,LOC_FLAGS,OS_NO);
     load_left_right(cmpop,(cs_check_overflow in aktlocalswitches)and(nodetype in [addn,subn,muln]));
     load_left_right(cmpop,(cs_check_overflow in aktlocalswitches)and(nodetype in [addn,subn,muln]));
-    if(location.register.enum = R_NO)and not(cmpop)
-    then
+    if (location.register.number = NR_NO) and not(cmpop) then
       location.register := rg.getregisterint(exprasmlist,OS_INT);
       location.register := rg.getregisterint(exprasmlist,OS_INT);
     if not(cs_check_overflow in aktlocalswitches)or cmpop or (nodetype in [orn,andn,xorn])
     if not(cs_check_overflow in aktlocalswitches)or cmpop or (nodetype in [orn,andn,xorn])
     then
     then
@@ -1122,22 +1111,18 @@ procedures }
           CGMessage(type_e_mismatch);
           CGMessage(type_e_mismatch);
         end;
         end;
    { Convert flags to register first }
    { Convert flags to register first }
-        if(left.location.loc=LOC_FLAGS)
-        then
-          location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],false);
-        if (right.location.loc=LOC_FLAGS)
-        then
-          location_force_reg(exprasmlist,right.location,opsize_2_cgsize[opsize],false);
+        if (left.location.loc=LOC_FLAGS) then
+          location_force_reg(exprasmlist,left.location,opsize,false);
+        if (right.location.loc=LOC_FLAGS) then
+          location_force_reg(exprasmlist,right.location,opsize,false);
         left_must_be_reg(OpSize,false);
         left_must_be_reg(OpSize,false);
-        if not cmpOp
-        then
+        if not cmpOp then
           emit_generic_code(op,opsize,unsigned,extra_not,mboverflow)
           emit_generic_code(op,opsize,unsigned,extra_not,mboverflow)
         else
         else
           emit_compare(unsigned);
           emit_compare(unsigned);
         location_freetemp(exprasmlist,right.location);
         location_freetemp(exprasmlist,right.location);
         location_release(exprasmlist,right.location);
         location_release(exprasmlist,right.location);
-        if cmpop and(left.location.loc<>LOC_CREGISTER)
-        then
+        if cmpop and (left.location.loc<>LOC_CREGISTER) then
           begin
           begin
             location_freetemp(exprasmlist,left.location);
             location_freetemp(exprasmlist,left.location);
             location_release(exprasmlist,left.location);
             location_release(exprasmlist,left.location);
@@ -1176,12 +1161,18 @@ procedure TSparcAddNode.pass_left_and_right;
         left.location.register := tmpreg;
         left.location.register := tmpreg;
       end;
       end;
   end;
   end;
+
 begin
 begin
   cAddNode:=TSparcAddNode;
   cAddNode:=TSparcAddNode;
 end.
 end.
 {
 {
     $Log$
     $Log$
-    Revision 1.13  2003-05-07 15:05:37  mazen
+    Revision 1.14  2003-05-30 23:57:08  peter
+      * more sparc cleanup
+      * accumulator removed, splitted in function_return_reg (called) and
+        function_result_reg (caller)
+
+    Revision 1.13  2003/05/07 15:05:37  mazen
     * fixed generated code for compare instructions
     * fixed generated code for compare instructions
 
 
     Revision 1.12  2003/05/06 21:37:58  mazen
     Revision 1.12  2003/05/06 21:37:58  mazen

+ 7 - 2
compiler/sparc/ncpumat.pas

@@ -150,7 +150,7 @@ implementation
              rg.UnGetRegisterInt(exprasmlist,divider);
              rg.UnGetRegisterInt(exprasmlist,divider);
            end;
            end;
        { free used registers }
        { free used registers }
-        if numerator.enum <> resultreg.enum then
+        if numerator.number <> resultreg.number then
           rg.ungetregisterint(exprasmlist,numerator);
           rg.ungetregisterint(exprasmlist,numerator);
         { set result location }
         { set result location }
         location.loc:=LOC_REGISTER;
         location.loc:=LOC_REGISTER;
@@ -479,7 +479,12 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.7  2003-03-15 22:51:58  mazen
+  Revision 1.8  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.7  2003/03/15 22:51:58  mazen
   * remaking sparc rtl compile
   * remaking sparc rtl compile
 
 
   Revision 1.6  2003/03/10 21:59:54  mazen
   Revision 1.6  2003/03/10 21:59:54  mazen

+ 7 - 2
compiler/x86/aasmcpu.pas

@@ -85,7 +85,7 @@ interface
       OT_FPU0      = $01000800;  { FPU stack register zero  }
       OT_FPU0      = $01000800;  { FPU stack register zero  }
       OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
       OT_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
                                  { a mask for the following  }
                                  { a mask for the following  }
-      OT_REG_ACCUM = $00211000;  { accumulator: AL, AX or EAX  }
+      OT_REG_ACCUM = $00211000;  { FUNCTION_RETURN_REG: AL, AX or EAX  }
       OT_REG_AL    = $00211001;    { REG_ACCUM | BITSxx  }
       OT_REG_AL    = $00211001;    { REG_ACCUM | BITSxx  }
       OT_REG_AX    = $00211002;    { ditto  }
       OT_REG_AX    = $00211002;    { ditto  }
       OT_REG_EAX   = $00211004;    { and again  }
       OT_REG_EAX   = $00211004;    { and again  }
@@ -2024,7 +2024,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2003-05-22 21:33:31  peter
+  Revision 1.4  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.3  2003/05/22 21:33:31  peter
     * removed some unit dependencies
     * removed some unit dependencies
 
 
   Revision 1.2  2002/04/25 16:12:09  florian
   Revision 1.2  2002/04/25 16:12:09  florian

+ 13 - 3
compiler/x86/cgx86.pas

@@ -309,9 +309,14 @@ unit cgx86;
 
 
     class function tcgx86.reg_cgsize(const reg: tregister): tcgsize;
     class function tcgx86.reg_cgsize(const reg: tregister): tcgsize;
       const
       const
-        regsize_2_cgsize: array[S_B..S_L] of tcgsize = (OS_8,OS_16,OS_32);
+        opsize_2_cgsize: array[topsize] of tcgsize = (OS_NO,
+          OS_8,OS_16,OS_32,OS_NO,OS_NO,OS_NO,
+          OS_32,OS_64,OS_64,
+          OS_F32,OS_F64,OS_F80,OS_F32,OS_F64,OS_NO,OS_NO,
+          OS_NO,OS_NO,OS_NO
+        );
       begin
       begin
-        result := regsize_2_cgsize[reg2opsize(reg)];
+        result := opsize_2_cgsize[reg2opsize(reg)];
       end;
       end;
 
 
 
 
@@ -1941,7 +1946,12 @@ unit cgx86;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.47  2003-05-22 21:33:31  peter
+  Revision 1.48  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.47  2003/05/22 21:33:31  peter
     * removed some unit dependencies
     * removed some unit dependencies
 
 
   Revision 1.46  2003/05/16 14:33:31  peter
   Revision 1.46  2003/05/16 14:33:31  peter

+ 8 - 6
compiler/x86/cpubase.pas

@@ -487,9 +487,6 @@ uses
 
 
       max_operands = 3;
       max_operands = 3;
 
 
-      lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
-        LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
-
       {# Constant defining possibly all registers which might require saving }
       {# Constant defining possibly all registers which might require saving }
       ALL_REGISTERS = [firstreg..lastreg];
       ALL_REGISTERS = [firstreg..lastreg];
       ALL_INTREGISTERS = [1..255];
       ALL_INTREGISTERS = [1..255];
@@ -715,7 +712,12 @@ implementation
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.4  2003-04-30 20:53:32  florian
+  Revision 1.5  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.4  2003/04/30 20:53:32  florian
     * error when address of an abstract method is taken
     * error when address of an abstract method is taken
     * fixed some x86-64 problems
     * fixed some x86-64 problems
     * merged some more x86-64 and i386 code
     * merged some more x86-64 and i386 code
@@ -798,10 +800,10 @@ end.
     + very basic support for float128 type (x86-64 only)
     + very basic support for float128 type (x86-64 only)
 
 
   Revision 1.34  2002/11/17 18:26:16  mazen
   Revision 1.34  2002/11/17 18:26:16  mazen
-  * fixed a compilation bug accmulator-->accumulator, in definition of return_result_reg
+  * fixed a compilation bug accmulator-->FUNCTION_RETURN_REG, in definition of return_result_reg
 
 
   Revision 1.33  2002/11/17 17:49:08  mazen
   Revision 1.33  2002/11/17 17:49:08  mazen
-  + return_result_reg and function_result_reg are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
+  + return_result_reg and FUNCTION_RESULT_REG are now used, in all plateforms, to pass functions result between called function and its caller. See the explanation of each one
 
 
   Revision 1.32  2002/10/05 12:43:29  carl
   Revision 1.32  2002/10/05 12:43:29  carl
     * fixes for Delphi 6 compilation
     * fixes for Delphi 6 compilation

+ 58 - 33
compiler/x86/rax86.pas

@@ -42,11 +42,15 @@ Procedure FWaitWarning;
 
 
 type
 type
   T386Operand=class(TOperand)
   T386Operand=class(TOperand)
+    opsize  : topsize;
+    Procedure SetSize(_size:longint;force:boolean);override;
     Procedure SetCorrectSize(opcode:tasmop);override;
     Procedure SetCorrectSize(opcode:tasmop);override;
   end;
   end;
 
 
   T386Instruction=class(TInstruction)
   T386Instruction=class(TInstruction)
     OpOrder : TOperandOrder;
     OpOrder : TOperandOrder;
+    opsize  : topsize;
+    constructor Create;
     { Operand sizes }
     { Operand sizes }
     procedure AddReferenceSizes;
     procedure AddReferenceSizes;
     procedure SetInstructionOpsize;
     procedure SetInstructionOpsize;
@@ -85,7 +89,7 @@ implementation
 uses
 uses
   globtype,globals,systems,verbose,
   globtype,globals,systems,verbose,
   cpuinfo,
   cpuinfo,
-  itx86att;
+  itx86att,cgx86;
 
 
 {$define ATTOP}
 {$define ATTOP}
 {$define INTELOP}
 {$define INTELOP}
@@ -196,20 +200,27 @@ end;
                               T386Operand
                               T386Operand
 *****************************************************************************}
 *****************************************************************************}
 
 
+Procedure T386Operand.SetSize(_size:longint;force:boolean);
+begin
+  inherited SetSize(_size,force);
+  opsize:=TCGSize2Opsize[size];
+end;
+
+
 Procedure T386Operand.SetCorrectSize(opcode:tasmop);
 Procedure T386Operand.SetCorrectSize(opcode:tasmop);
 begin
 begin
   if gas_needsuffix[opcode]=attsufFPU then
   if gas_needsuffix[opcode]=attsufFPU then
     begin
     begin
-     case size of
-      S_L : size:=S_FS;
-      S_IQ : size:=S_FL;
+     case opsize of
+      S_L : opsize:=S_FS;
+      S_IQ : opsize:=S_FL;
      end;
      end;
     end
     end
   else if gas_needsuffix[opcode]=attsufFPUint then
   else if gas_needsuffix[opcode]=attsufFPUint then
     begin
     begin
-      case size of
-      S_W : size:=S_IS;
-      S_L : size:=S_IL;
+      case opsize of
+        S_W : opsize:=S_IS;
+        S_L : opsize:=S_IL;
       end;
       end;
     end;
     end;
 end;
 end;
@@ -219,6 +230,13 @@ end;
                               T386Instruction
                               T386Instruction
 *****************************************************************************}
 *****************************************************************************}
 
 
+constructor T386Instruction.Create;
+begin
+  inherited Create;
+  Opsize:=S_NO;
+end;
+
+
 procedure T386Instruction.SwapOperands;
 procedure T386Instruction.SwapOperands;
 begin
 begin
   Inherited SwapOperands;
   Inherited SwapOperands;
@@ -242,7 +260,7 @@ begin
   for i:=1to ops do
   for i:=1to ops do
    begin
    begin
    operands[i].SetCorrectSize(opcode);
    operands[i].SetCorrectSize(opcode);
-   if (operands[i].size=S_NO) then
+   if t386operand(operands[i]).opsize=S_NO then
     begin
     begin
       case operands[i].Opr.Typ of
       case operands[i].Opr.Typ of
         OPR_REFERENCE :
         OPR_REFERENCE :
@@ -265,19 +283,19 @@ begin
                   { if no register then take the opsize (which is available with ATT),
                   { if no register then take the opsize (which is available with ATT),
                     if not availble then give an error }
                     if not availble then give an error }
                   if opsize<>S_NO then
                   if opsize<>S_NO then
-                    operands[i].size:=opsize
+                    t386operand(operands[i]).opsize:=opsize
                   else
                   else
                    begin
                    begin
                      Message(asmr_e_unable_to_determine_reference_size);
                      Message(asmr_e_unable_to_determine_reference_size);
                      { recovery }
                      { recovery }
-                     operands[i].size:=S_L;
+                     t386operand(operands[i]).opsize:=S_L;
                    end;
                    end;
                 end;
                 end;
              end
              end
             else
             else
              begin
              begin
                if opsize<>S_NO then
                if opsize<>S_NO then
-                 operands[i].size:=opsize
+                 t386operand(operands[i]).opsize:=opsize
              end;
              end;
           end;
           end;
         OPR_SYMBOL :
         OPR_SYMBOL :
@@ -292,7 +310,7 @@ begin
                operands[i].opr.ref.symbol:=s;
                operands[i].opr.ref.symbol:=s;
                operands[i].opr.ref.offset:=so;
                operands[i].opr.ref.offset:=so;
              end;
              end;
-            operands[i].size:=S_L;
+            t386operand(operands[i]).opsize:=S_L;
           end;
           end;
       end;
       end;
     end;
     end;
@@ -319,20 +337,20 @@ begin
            (operands[1].opr.reg.number<=nlastsreg))) then
            (operands[1].opr.reg.number<=nlastsreg))) then
         opsize:=S_L
         opsize:=S_L
       else
       else
-        opsize:=operands[1].size;
+        opsize:=t386operand(operands[1]).opsize;
     2 :
     2 :
       begin
       begin
         case opcode of
         case opcode of
           A_MOVZX,A_MOVSX :
           A_MOVZX,A_MOVSX :
             begin
             begin
-              case operands[1].size of
+              case t386operand(operands[1]).opsize of
                 S_W :
                 S_W :
-                  case operands[2].size of
+                  case t386operand(operands[2]).opsize of
                     S_L :
                     S_L :
                       opsize:=S_WL;
                       opsize:=S_WL;
                   end;
                   end;
                 S_B :
                 S_B :
-                  case operands[2].size of
+                  case t386operand(operands[2]).opsize of
                     S_W :
                     S_W :
                       opsize:=S_BW;
                       opsize:=S_BW;
                     S_L :
                     S_L :
@@ -344,13 +362,13 @@ begin
                      32 bit register or memory, so no opsize is correct here PM }
                      32 bit register or memory, so no opsize is correct here PM }
             exit;
             exit;
           A_OUT :
           A_OUT :
-            opsize:=operands[1].size;
+            opsize:=t386operand(operands[1]).opsize;
           else
           else
-            opsize:=operands[2].size;
+            opsize:=t386operand(operands[2]).opsize;
         end;
         end;
       end;
       end;
     3 :
     3 :
-      opsize:=operands[3].size;
+      opsize:=t386operand(operands[3]).opsize;
   end;
   end;
 end;
 end;
 
 
@@ -391,11 +409,11 @@ begin
       begin
       begin
         case opsize of
         case opsize of
           S_BW :
           S_BW :
-            sizeerr:=(operands[1].size<>S_B) or (operands[2].size<>S_W);
+            sizeerr:=(t386operand(operands[1]).opsize<>S_B) or (t386operand(operands[2]).opsize<>S_W);
           S_BL :
           S_BL :
-            sizeerr:=(operands[1].size<>S_B) or (operands[2].size<>S_L);
+            sizeerr:=(t386operand(operands[1]).opsize<>S_B) or (t386operand(operands[2]).opsize<>S_L);
           S_WL :
           S_WL :
-            sizeerr:=(operands[1].size<>S_W) or (operands[2].size<>S_L);
+            sizeerr:=(t386operand(operands[1]).opsize<>S_W) or (t386operand(operands[2]).opsize<>S_L);
         end;
         end;
       end;
       end;
    end
    end
@@ -404,8 +422,8 @@ begin
      for i:=1 to ops do
      for i:=1 to ops do
       begin
       begin
         if (operands[i].opr.typ<>OPR_CONSTANT) and
         if (operands[i].opr.typ<>OPR_CONSTANT) and
-           (operands[i].size in [S_B,S_W,S_L]) and
-           (operands[i].size<>opsize) then
+           (t386operand(operands[i]).opsize in [S_B,S_W,S_L]) and
+           (t386operand(operands[i]).opsize<>opsize) then
          sizeerr:=true;
          sizeerr:=true;
       end;
       end;
    end;
    end;
@@ -483,19 +501,21 @@ begin
   else
   else
    begin
    begin
      if (Ops=2) and (operands[1].opr.typ=OPR_REGISTER) then
      if (Ops=2) and (operands[1].opr.typ=OPR_REGISTER) then
-      siz:=operands[1].size
+      siz:=t386operand(operands[1]).opsize
      else
      else
-      siz:=operands[Ops].size;
+      siz:=t386operand(operands[Ops]).opsize;
      { MOVD should be of size S_LQ or S_QL, but these do not exist PM }
      { MOVD should be of size S_LQ or S_QL, but these do not exist PM }
-     if (ops=2) and (operands[1].size<>S_NO) and
-        (operands[2].size<>S_NO) and (operands[1].size<>operands[2].size) then
+     if (ops=2) and
+        (t386operand(operands[1]).opsize<>S_NO) and
+        (t386operand(operands[2]).opsize<>S_NO) and
+        (t386operand(operands[1]).opsize<>t386operand(operands[2]).opsize) then
        siz:=S_NO;
        siz:=S_NO;
    end;
    end;
 
 
    if ((opcode=A_MOVD)or
    if ((opcode=A_MOVD)or
        (opcode=A_CVTSI2SS)) and
        (opcode=A_CVTSI2SS)) and
-      ((operands[1].size=S_NO) or
-       (operands[2].size=S_NO)) then
+      ((t386operand(operands[1]).opsize=S_NO) or
+       (t386operand(operands[2]).opsize=S_NO)) then
      siz:=S_NO;
      siz:=S_NO;
    { NASM does not support FADD without args
    { NASM does not support FADD without args
      as alias of FADDP
      as alias of FADDP
@@ -636,10 +656,10 @@ begin
        OPR_REFERENCE:
        OPR_REFERENCE:
          begin
          begin
            ai.loadref(i-1,operands[i].opr.ref);
            ai.loadref(i-1,operands[i].opr.ref);
-           if operands[i].size<>S_NO then
+           if t386operand(operands[i]).opsize<>S_NO then
              begin
              begin
                asize:=0;
                asize:=0;
-               case operands[i].size of
+               case t386operand(operands[i]).opsize of
                    S_B :
                    S_B :
                      asize:=OT_BITS8;
                      asize:=OT_BITS8;
                    S_W, S_IS :
                    S_W, S_IS :
@@ -684,7 +704,12 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2003-05-22 21:33:31  peter
+  Revision 1.3  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.2  2003/05/22 21:33:31  peter
     * removed some unit dependencies
     * removed some unit dependencies
 
 
   Revision 1.1  2003/04/30 15:45:35  florian
   Revision 1.1  2003/04/30 15:45:35  florian

+ 19 - 17
compiler/x86_64/cpubase.inc

@@ -163,29 +163,26 @@ const
 *****************************************************************************}
 *****************************************************************************}
 
 
       {# Stack pointer register }
       {# Stack pointer register }
-      stack_pointer_reg = R_RSP;
       NR_STACK_POINTER_REG = NR_RSP;
       NR_STACK_POINTER_REG = NR_RSP;
       {# Frame pointer register }
       {# Frame pointer register }
-      frame_pointer_reg = R_RBP;
       NR_FRAME_POINTER_REG = NR_RBP;
       NR_FRAME_POINTER_REG = NR_RBP;
       { Register for addressing absolute data in a position independant way,
       { Register for addressing absolute data in a position independant way,
         such as in PIC code. The exact meaning is ABI specific. For
         such as in PIC code. The exact meaning is ABI specific. For
         further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
         further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
       }
       }
-      pic_offset_reg = R_EBX;
-      accumulator = R_RAX;
-      RS_ACCUMULATOR = RS_RAX;
-      NR_ACCUMULATOR = NR_RAX;
-      { the return_result_reg, is used inside the called function to store its return
-        value when that is a scalar value otherwise a pointer to the address of the
-        result is placed inside it }
-      return_result_reg   = accumulator;
-      RS_RETURN_RESULT_REG = RS_ACCUMULATOR;
-      NR_RETURN_RESULT_REG = NR_ACCUMULATOR;
-
-      { the function_result_reg contains the function result after a call to a scalar
-        function othewise it contains a pointer to the returned result}
-      function_result_reg = accumulator;
+      NR_PIC_OFFSET_REG = NR_EBX;
+      { Results are returned in this register (32-bit values) }
+      NR_FUNCTION_RETURN_REG = NR_RAX;
+      RS_FUNCTION_RETURN_REG = RS_RAX;
+      { High part of 64bit return value }
+      NR_FUNCTION_RETURNHIGH_REG = NR_NONE;
+      RS_FUNCTION_RETURNHIGH_REG = RS_NONE;
+      { The value returned from a function is available in this register }
+      NR_FUNCTION_RESULT_REG = NR_FUNCTION_RETURN_REG;
+      RS_FUNCTION_RESULT_REG = RS_FUNCTION_RETURN_REG;
+      { The high part of 64bit value returned from a function is available in this register }
+      NR_FUNCTION_RESULTHIGH_REG = NR_FUNCTION_RETURNHIGH_REG;
+      RS_FUNCTION_RESULTHIGH_REG = RS_FUNCTION_RETURNHIGH_REG;
 
 
       fpu_result_reg = R_ST;
       fpu_result_reg = R_ST;
       mmresultreg = R_MM0;
       mmresultreg = R_MM0;
@@ -214,7 +211,12 @@ const
 
 
 {
 {
   $Log$
   $Log$
-  Revision 1.3  2003-04-30 15:45:35  florian
+  Revision 1.4  2003-05-30 23:57:08  peter
+    * more sparc cleanup
+    * accumulator removed, splitted in function_return_reg (called) and
+      function_result_reg (caller)
+
+  Revision 1.3  2003/04/30 15:45:35  florian
     * merged more x86-64/i386 code
     * merged more x86-64/i386 code
 
 
   Revision 1.2  2002/04/25 16:12:09  florian
   Revision 1.2  2002/04/25 16:12:09  florian

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików