2
0
Эх сурвалжийг харах

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

peter 22 жил өмнө
parent
commit
414bd5fa22

+ 10 - 5
compiler/cgobj.pas

@@ -277,7 +277,7 @@ unit cgobj;
 
          {#
              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).
              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;
          {#
              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
              *NOT* be freed) or on the stack (the value should be popped).
 
@@ -1645,7 +1645,7 @@ unit cgobj;
 
      begin
        r.enum:=R_INTREGISTER;;
-       r.number:=NR_ACCUMULATOR;
+       r.number:=NR_FUNCTION_RETURN_REG;
        a_load_reg_ref(list, OS_S32, r, href);
      end;
 
@@ -1662,7 +1662,7 @@ unit cgobj;
 
      begin
        r.enum:=R_INTREGISTER;
-       r.number:=NR_ACCUMULATOR;
+       r.number:=NR_FUNCTION_RETURN_REG;
        a_load_ref_reg(list, OS_S32, href, r);
      end;
 
@@ -1691,7 +1691,12 @@ finalization
 end.
 {
   $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
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)

+ 21 - 22
compiler/i386/cpubase.inc

@@ -102,6 +102,7 @@
       max_scratch_regs = 1;
       scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
 {$endif}
+
 {*****************************************************************************
                                GDB Information
 *****************************************************************************}
@@ -145,34 +146,27 @@
 *****************************************************************************}
 
       {# Stack pointer register }
-      stack_pointer_reg = R_ESP;
       NR_STACK_POINTER_REG = NR_ESP;
       {# Frame pointer register }
-      frame_pointer_reg = R_EBP;
       NR_FRAME_POINTER_REG = NR_EBP;
       {# 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
       }
-      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 }
       { a_loadfpu* methods in rgcpu (JM)                                      }
       fpu_result_reg = R_ST;
@@ -202,7 +196,12 @@
 
 {
   $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
 
   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
           system_i386_win32 :
             begin
-              { Win32 returns small records in the accumulator }
+              { Win32 returns small records in the FUNCTION_RETURN_REG }
               case def.deftype of
                 recorddef :
                   begin
@@ -133,7 +133,12 @@ begin
 end.
 {
   $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
     * fixed ret_in_param for win32 cdecl array
 

+ 10 - 5
compiler/i386/csopt386.pas

@@ -363,9 +363,9 @@ Begin {CheckSequence}
   OrgRegResult := False;
   with startRegInfo do
     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;
     end;
 
@@ -1334,7 +1334,7 @@ begin
              (Taicpu(startmod).opcode = A_MOVSX) or
              (Taicpu(startmod).opcode = A_LEA)) 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
            findRegDealloc(reg,p))) then
         pTaiprop(startMod.optInfo)^.canBeRemoved := true;
@@ -1997,7 +1997,12 @@ End.
 
 {
   $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
 
   Revision 1.44  2003/04/27 11:21:35  peter

+ 7 - 2
compiler/i386/n386cal.pas

@@ -197,7 +197,12 @@ begin
 end.
 {
   $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
     * aktexit2label removed, fast exit removed
     + tcallnode.inlined_pass_2 added
@@ -294,7 +299,7 @@ end.
     * old logs removed and tabs fixed
 
   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
     * use a_call_reg

+ 9 - 2
compiler/i386/popt386.pas

@@ -1376,7 +1376,9 @@ Begin
                              Taicpu(hp2).opcode := A_MOV;
                              Taicpu(hp2).Loadoper(1,Taicpu(hp1).oper[0]);
                              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;
                              Taicpu(hp2).loadRef(0,tmpRef);
                              hp4 := hp1;
@@ -2058,7 +2060,12 @@ End.
 
 {
   $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
     * procinfo renamed to current_procinfo
     * procinfo will now be stored in current_module so it can be

+ 12 - 4
compiler/i386/ra386att.pas

@@ -49,7 +49,8 @@ Implementation
        { parser }
        scanner,
        itx86att,
-       rax86,rautils
+       rax86,rautils,
+       cginfo,cgobj
        ;
 
 type
@@ -1402,6 +1403,8 @@ var
     end; { end case }
   end;
 
+const
+  regsize_2_size: array[S_B..S_L] of longint = (1,2,4);
 var
   tempreg : tregister;
   hl      : tasmlabel;
@@ -1441,7 +1444,7 @@ Begin
          begin
            opr.typ:=OPR_REGISTER;
            opr.reg:=actasmregister;
-           size:=reg2opsize(actasmregister);
+           SetSize(regsize_2_size[reg2opsize(actasmregister)],true);
            Consume(AS_REGISTER);
          end
         else
@@ -1594,7 +1597,7 @@ Begin
              Message(asmr_e_invalid_operand_type);
            opr.typ:=OPR_REGISTER;
            opr.reg:=tempreg;
-           size:=reg2opsize(opr.reg);
+           SetSize(tcgsize2size[cg.reg_cgsize(opr.reg)],true);
          end
         else
          Message(asmr_e_syn_operand);
@@ -2134,7 +2137,12 @@ finalization
 end.
 {
   $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
 
   Revision 1.43  2003/04/30 15:45:35  florian

+ 15 - 10
compiler/i386/ra386int.pas

@@ -52,7 +52,7 @@ Implementation
        scanner,
        rautils,rax86,ag386int,
        { codegen }
-       cgbase
+       cginfo,cgbase,cgobj
        ;
 
 type
@@ -1565,7 +1565,7 @@ Begin
             Message(asmr_e_invalid_operand_type);
            opr.typ:=OPR_REGISTER;
            opr.reg:=tempreg;
-           size:=reg2opsize(opr.reg)
+           SetSize(tcgsize2size[cg.reg_cgsize(opr.reg)],true);
          end;
       end;
 
@@ -1620,7 +1620,7 @@ end;
 Procedure T386IntelInstruction.BuildOpCode;
 var
   PrefixOp,OverrideOp: tasmop;
-  size : topsize;
+  size : tcgsize;
   operandnum : longint;
 Begin
   PrefixOp:=A_None;
@@ -1706,9 +1706,9 @@ Begin
           { load the size in a temp variable, so it can be set when the
             operand is read }
           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
                           if (opcode=A_FCOM) or
                             (opcode=A_FCOMP) or
@@ -1721,11 +1721,11 @@ Begin
                             (opcode=A_FST) or
                             (opcode=A_FSTP) or
                             (opcode=A_FADD) then
-                            size:=S_FL
+                            size:=OS_F64
                           else
-                            size:=S_IQ;
+                            size:=OS_64;
                        end;
-            AS_TBYTE : size:=S_FX;
+            AS_TBYTE : size:=OS_F80;
           end;
           Consume(actasmtoken);
           if actasmtoken=AS_PTR then
@@ -1961,7 +1961,12 @@ finalization
 end.
 {
   $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
 
   Revision 1.46  2003/04/27 11:21:35  peter

+ 30 - 24
compiler/ncgcal.pas

@@ -426,7 +426,8 @@ implementation
           begin
             location_reset(location,LOC_CREFERENCE,OS_ADDR);
             location.reference:=refcountedtemp;
-            r.enum:=accumulator;
+            r.enum:=R_INTREGISTER;
+            r.number:=NR_FUNCTION_RETURN_REG;
             cg.a_reg_alloc(exprasmlist,r);
             cg.a_load_reg_ref(exprasmlist,OS_ADDR,r,location.reference);
             cg.a_reg_dealloc(exprasmlist,r);
@@ -440,10 +441,10 @@ implementation
                 location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
 {$ifdef cpufpemu}
                 if cs_fp_emulation in aktmoduleswitches then
-                  location.register.enum := accumulator
-               else
+                  location.register.enum := FUNCTION_RESULT_REG
+                else
 {$endif cpufpemu}
-                location.register.enum:=FPU_RESULT_REG;
+                  location.register.enum:=FPU_RESULT_REG;
 {$ifdef x86}
                 inc(trgcpu(rg).fpuvaroffset);
 {$else x86}
@@ -466,26 +467,26 @@ implementation
 {$ifndef cpu64bit}
                    if cgsize in [OS_64,OS_S64] then
                     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.number:=NR_ACCUMULATOR;
+                      r.number:=NR_FUNCTION_RESULT_REG;
                       hregister.enum:=R_INTREGISTER;
-                      hregister.number:=NR_ACCUMULATORHIGH;
+                      hregister.number:=NR_FUNCTION_RESULTHIGH_REG;
 {$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,hregister);
                       location.registerlow:=rg.getregisterint(exprasmlist,OS_INT);
                       location.registerhigh:=rg.getregisterint(exprasmlist,OS_INT);
 {$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
                         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
                         cg.a_reg_alloc(exprasmlist,hregister);
                       { do this after both low,high are allocated, else it is possible that
@@ -502,8 +503,8 @@ implementation
 {$endif cpu64bit}
                     begin
                       {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.number:=nr;
 {$ifdef newra}
@@ -512,7 +513,7 @@ implementation
                       location.register:=rg.getregisterint(exprasmlist,cgsize);
 {$else newra}
                       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)
                       else
                         location.register:=rg.getregisterint(exprasmlist,cgsize);
@@ -640,10 +641,10 @@ implementation
               if (not is_void(resulttype.def)) and
                  (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
                begin
-                 include(regs_to_push_int,RS_ACCUMULATOR);
+                 include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
 {$ifndef cpu64bit}
                  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}
                end;
               rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
@@ -1029,10 +1030,10 @@ implementation
          if (not is_void(resulttype.def)) and
             (not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption)) then
           begin
-            include(regs_to_push_int,RS_ACCUMULATOR);
+            include(regs_to_push_int,RS_FUNCTION_RESULT_REG);
 {$ifndef cpu64bit}
             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}
           end;
          rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
@@ -1232,11 +1233,16 @@ begin
 end.
 {
   $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
 
   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
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
       i386
@@ -1478,7 +1484,7 @@ end.
     * several powerpc related stuff fixed
 
   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
     * use a_call_reg

+ 11 - 6
compiler/ncgflw.pas

@@ -893,7 +893,7 @@ implementation
       begin
          cg.a_call_name(exprasmlist,'FPC_POPOBJECTSTACK');
          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_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
       end;
@@ -1021,7 +1021,7 @@ implementation
               cg.a_call_name(exprasmlist,'FPC_POPSECONDOBJECTSTACK');
 
               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_call_name(exprasmlist,'FPC_DESTROYEXCEPTION');
               { we don't need to restore esi here because reraise never }
@@ -1137,8 +1137,6 @@ implementation
       begin
          location_reset(location,LOC_VOID,OS_NO);
 
-         r.enum:=R_INTREGISTER;
-         r.number:=NR_ACCUMULATOR;
          oldflowcontrol:=flowcontrol;
          flowcontrol:=[];
          objectlibrary.getlabel(nextonlabel);
@@ -1149,6 +1147,8 @@ implementation
          cg.a_call_name(exprasmlist,'FPC_CATCHES');
 
          { 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);
          ref.symbol:=nil;
          tg.GetTemp(exprasmlist,pointer_size,tt_normal,ref);
@@ -1329,7 +1329,7 @@ implementation
          { the value should now be in the exception handler }
          cg.g_exception_reason_load(exprasmlist,href);
          r.enum:=R_INTREGISTER;
-         r.number:=NR_ACCUMULATOR;
+         r.number:=NR_FUNCTION_RESULT_REG;
          if implicitframe then
            begin
              cg.a_cmp_const_reg_label(exprasmlist,OS_S32,OC_EQ,0,r,endfinallylabel);
@@ -1421,7 +1421,12 @@ begin
 end.
 {
   $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
       works for ppc
 

+ 8 - 3
compiler/ncgld.pas

@@ -146,14 +146,14 @@ implementation
                        if hregister.enum<>R_INTREGISTER then
                          internalerror(200301171);
                        { 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);
                        cg.a_param_ref(exprasmlist,OS_ADDR,href,paramanager.getintparaloc(1));
                        { the called procedure isn't allowed to change }
                        { any register except EAX                    }
                        cg.a_call_reg(exprasmlist,hregister);
                        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);
                        rg.restoreusedintregisters(exprasmlist,pushed);
                        cg.a_label(exprasmlist,norelocatelab);
@@ -922,7 +922,12 @@ begin
 end.
 {
   $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
 
   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');
                   { result of value is always one full register }
                   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);
                   { release the allocated register  }
                   if not (left.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
@@ -1121,7 +1121,12 @@ begin
 end.
 {
   $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
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)

+ 29 - 23
compiler/ncgutil.pas

@@ -269,7 +269,7 @@ implementation
        cg.a_call_name(list,'FPC_PUSHEXCEPTADDR');
 
        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_call_name(list,'FPC_SETJMP');
 
@@ -290,7 +290,7 @@ implementation
           begin
             cg.g_exception_reason_load(list, href);
             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);
           end;
      end;
@@ -796,7 +796,8 @@ implementation
 {$endif GDB}
 
                   { 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
                    reference_reset_base(href,current_procinfo.framepointer,para_offset-pushedparasize)
                   else
@@ -1229,7 +1230,7 @@ implementation
       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
         href : treference;
         hreg,r,r2 : tregister;
@@ -1240,7 +1241,7 @@ implementation
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            { 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 }
            case current_procdef.rettype.def.deftype of
              orddef,
@@ -1248,14 +1249,14 @@ implementation
                begin
                  uses_acc:=true;
                  r.enum:=R_INTREGISTER;
-                 r.number:=NR_RETURN_RESULT_REG;
+                 r.number:=NR_FUNCTION_RETURN_REG;
                  cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
                  if cgsize in [OS_64,OS_S64] then
                   begin
                     uses_acchi:=true;
                     r2.enum:=R_INTREGISTER;
-                    r2.number:=NR_ACCUMULATORHIGH;
+                    r2.number:=NR_FUNCTION_RETURNHIGH_REG;
                     cg.a_reg_alloc(list,r2);
                     cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                   end
@@ -1263,7 +1264,7 @@ implementation
 {$endif cpu64bit}
                   begin
                     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);
                   end;
                end;
@@ -1272,10 +1273,10 @@ implementation
                  uses_fpu := true;
 {$ifdef cpufpemu}
                   if cs_fp_emulation in aktmoduleswitches then
-                    r.enum := accumulator
+                    r.enum := FUNCTION_RETURN_REG
                  else
 {$endif cpufpemu}
-                  r.enum:=fpu_result_reg;
+                  r.enum:=FPU_RESULT_REG;
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                end;
              else
@@ -1284,7 +1285,7 @@ implementation
                   begin
                     uses_acc:=true;
                     r.enum:=R_INTREGISTER;
-                    r.number:=NR_RETURN_RESULT_REG;
+                    r.number:=NR_FUNCTION_RETURN_REG;
                     cg.a_reg_alloc(list,r);
 {$ifndef cpu64bit}
                     { Win32 can return records in EAX:EDX }
@@ -1292,7 +1293,7 @@ implementation
                      begin
                        uses_acchi:=true;
                        r2.enum:=R_INTREGISTER;
-                       r2.number:=NR_ACCUMULATORHIGH;
+                       r2.number:=NR_FUNCTION_RETURNHIGH_REG;
                        cg.a_reg_alloc(list,r2);
                        cg64.a_load64_ref_reg(list,href,joinreg64(r,r2));
                      end
@@ -1300,7 +1301,7 @@ implementation
 {$endif cpu64bit}
                      begin
                        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);
                      end;
                    end
@@ -1629,7 +1630,7 @@ implementation
                 { Success exit }
                 cg.a_label(list,okexitlabel);
                 r.enum:=R_INTREGISTER;
-                r.number:=NR_ACCUMULATOR;
+                r.number:=NR_FUNCTION_RETURN_REG;
                 cg.a_reg_alloc(list,r);
                 { return the self pointer }
                 srsym:=tvarsym(current_procdef.parast.search('self'));
@@ -1641,7 +1642,7 @@ implementation
                 usesacc:=true;
               end
             else
-              handle_return_value(list,usesacc,usesacchi,usesfpu)
+              load_return_value(list,usesacc,usesacchi,usesfpu)
           end;
 
 {$ifdef GDB}
@@ -1782,7 +1783,7 @@ implementation
                                  Inlining
 ****************************************************************************}
 
-    procedure handle_inlined_return_value(list:TAAsmoutput);
+    procedure load_inlined_return_value(list:TAAsmoutput);
       var
         href : treference;
         r,r2 : tregister;
@@ -1793,7 +1794,7 @@ implementation
            reference_reset_base(href,current_procinfo.framepointer,current_procinfo.return_offset);
            cgsize:=def_cgsize(current_procdef.rettype.def);
            { 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 }
            case current_procdef.rettype.def.deftype of
              orddef,
@@ -1817,10 +1818,10 @@ implementation
                begin
 {$ifdef cpufpemu}
                   if cs_fp_emulation in aktmoduleswitches then
-                    r.enum := accumulator
+                    r.enum := FUNCTION_RETURN_REG
                  else
 {$endif cpufpemu}
-                  r.enum:=fpu_result_reg;
+                  r.enum:=FPU_RESULT_REG;
                  cg.a_loadfpu_ref_reg(list,cgsize,href,r);
                end;
              else
@@ -1898,8 +1899,8 @@ implementation
           begin
             if (current_procdef.proctypeoption=potype_constructor) then
              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;
 
         cleanup_regvars(list);
@@ -1908,7 +1909,12 @@ implementation
 end.
 {
   $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
       register (properly fixes what I worked around in revision 1.106 of
       ncgutil.pas)
@@ -2116,7 +2122,7 @@ end.
     * pass proccalloption to ret_in_xxx and push_xxx functions
 
   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
     * memory optimization (3-4%) : cleanup of tai fields,

+ 25 - 9
compiler/paramgr.pas

@@ -236,7 +236,8 @@ unit paramgr;
          result.loc:=LOC_REFERENCE;
          result.size:=OS_ADDR;
          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;
       end;
 
@@ -246,7 +247,8 @@ unit paramgr;
          result.loc:=LOC_REFERENCE;
          result.size:=OS_ADDR;
          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;
       end;
 
@@ -265,29 +267,38 @@ unit paramgr;
 {$ifndef cpu64bit}
                if result.size in [OS_64,OS_S64] then
                 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
                else
 {$endif cpu64bit}
-               result.register.enum:=accumulator;
+                begin
+                  result.register.enum:=R_INTREGISTER;
+                  result.register.number:=NR_FUNCTION_RETURN_REG;
+                end;
              end;
            floatdef :
              begin
                result.loc := LOC_FPUREGISTER;
 {$ifdef cpufpemu}
                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
 {$endif cpufpemu}
-                  result.register.enum := FPU_RESULT_REG;
+                 result.register.enum := FPU_RESULT_REG;
              end;
           else
              begin
                 if not ret_in_param(def,calloption) then
                   begin
                     result.loc := LOC_REGISTER;
-                    result.register.enum := accumulator;
+                    result.register.enum:=R_INTREGISTER;
+                    result.register.number:=NR_FUNCTION_RETURN_REG;
                   end
                 else
                    begin
@@ -388,7 +399,12 @@ end.
 
 {
    $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
      * fixed ret_in_param for win32 cdecl array
 

+ 114 - 123
compiler/powerpc/cpubase.pas

@@ -221,6 +221,7 @@ uses
       NR_RTOC = NR_R2;
 
     {Super registers:}
+      RS_NONE=$00;
       RS_R0 = $01; RS_R1 = $02; RS_R2 = $03;
       RS_R3 = $04; RS_R4 = $05; RS_R5 = $06;
       RS_R6 = $07; RS_R7 = $08; RS_R8 = $09;
@@ -380,7 +381,7 @@ uses
         case typ : toptype of
          top_none   : ();
          top_reg    : (reg:tregister);
-         top_ref    : (ref:^treference);
+         top_ref    : (ref:preference);
          top_const  : (val:aword);
          top_symbol : (sym:tasmsymbol;symofs:longint);
          top_bool  :  (b: boolean);
@@ -474,9 +475,6 @@ uses
     const
       max_operands = 5;
 
-      lvaluelocations = [LOC_REFERENCE, LOC_CREGISTER, LOC_CFPUREGISTER,
-                         LOC_CMMREGISTER];
-
       {# Constant defining possibly all registers which might require saving }
 {$warning FIX ME !!!!!!!!! }
       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_reg = R_1;
       NR_STACK_POINTER_REG = NR_R1;
       RS_STACK_POINTER_REG = RS_R1;
       {# Frame pointer register }
-      frame_pointer_reg = stack_pointer_reg;
       NR_FRAME_POINTER_REG = NR_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,
          such as in PIC code. The exact meaning is ABI specific. For
          further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -658,28 +649,23 @@ uses
          Taken from GCC rs6000.h
       }
 {$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 }
       { a_loadfpu* methods in rgcpu (JM)                                      }
-      fpu_result_reg = R_F1;
+      FPU_RESULT_REG = R_F1;
       mmresultreg = R_M0;
 
 {*****************************************************************************
@@ -731,6 +717,7 @@ uses
     procedure convert_register_to_enum(var r:Tregister);
     function cgsize2subreg(s:Tcgsize):Tsubregister;
 
+
 implementation
 
     uses
@@ -792,7 +779,6 @@ implementation
 
 
     procedure create_cond_norm(cond: TAsmCondFlag; cr: byte;var r : TasmCond);
-
       begin
         r.simple := true;
         r.cond := cond;
@@ -803,64 +789,69 @@ implementation
         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
-          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}
-          internalerror(200301082);
+            internalerror(200301082);
 {        end;}
-    end;
+      end;
 
-    function cgsize2subreg(s:Tcgsize):Tsubregister;
 
-    begin
-      cgsize2subreg:=R_SUBWHOLE;
-    end;
+    function cgsize2subreg(s:Tcgsize):Tsubregister;
+      begin
+        cgsize2subreg:=R_SUBWHOLE;
+      end;
 
 end.
 {
   $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
     * made sure the regvar registers don't overlap with the scratchregs
       anymore
@@ -924,10 +915,10 @@ end.
     + some comments describing the fields of treference
 
   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
-  + 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
     * 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;
          srsymtable : tsymtable;
          code : TAAsmoutput;
+         framereg : tregister;
          i,l : longint;
 
        procedure writeasmline;
@@ -104,6 +105,9 @@ interface
 
      begin
        ende:=false;
+       framereg.enum:=R_INTREGISTER;
+       framereg.number:=NR_STACK_POINTER_REG;
+       convert_register_to_enum(framereg);
        s:='';
        if assigned(current_procdef.funcretsym) and
           is_fpu(current_procdef.rettype.def) then
@@ -191,11 +195,11 @@ interface
                                                     if (tvarsym(sym).reg.enum<>R_NO) then
 // until new regallocator stuff settles down
 //                                                      hs:=gas_reg2str[procinfo.framepointer.enum]
-                                                      hs:=gas_reg2str[STACK_POINTER_REG]
+                                                      hs:=gas_reg2str[framereg.enum]
                                                     else
                                                       hs:=tostr(tvarsym(sym).address)+
 //                                                        '('+gas_reg2str[procinfo.framepointer.enum]+')';
-                                                        '('+gas_reg2str[STACK_POINTER_REG]+')';
+                                                        '('+gas_reg2str[framereg.enum]+')';
                                                  end;
                                             end
                                           else
@@ -217,7 +221,7 @@ interface
                                                     { set offset }
                                                     inc(l,current_procdef.parast.address_fixup);
 //                                                    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
                                                       tvarsym(sym).varstate:=vs_used;
                                                  end;
@@ -347,7 +351,12 @@ initialization
 end.
 {
   $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
     * procinfo renamed to current_procinfo
     * procinfo will now be stored in current_module so it can be

+ 7 - 2
compiler/psub.pas

@@ -1210,8 +1210,13 @@ begin
 end.
 {
   $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
     * ncgcal doesn't add used registers to usedby/inproc anymore, except for
       i386

+ 21 - 17
compiler/rautils.pas

@@ -28,7 +28,7 @@ Interface
 
 Uses
   cutils,cclasses,
-  globtype,aasmbase,aasmtai,cpubase,cpuinfo,
+  globtype,aasmbase,aasmtai,cpubase,cpuinfo,cginfo,
   symconst,symbase,symtype,symdef;
 
 Const
@@ -85,14 +85,14 @@ type
   end;
 
   TOperand = class
-    size   : topsize;
     hastype,          { if the operand has typecasted variable }
     hasvar : boolean; { if the operand is loaded with a variable }
+    size   : TCGSize;
     opr    : TOprRec;
     constructor create;
     destructor  destroy;override;
     Procedure BuildOperand;virtual;
-    Procedure SetSize(_size:longint;force:boolean);
+    Procedure SetSize(_size:longint;force:boolean);virtual;
     Procedure SetCorrectSize(opcode:tasmop);virtual;
     Function  SetupResult:boolean;virtual;
     Function  SetupSelf:boolean;
@@ -104,7 +104,6 @@ type
 
   TInstruction = class
     opcode    : tasmop;
-    opsize    : topsize;
     condition : tasmcond;
     ops       : byte;
     labeled   : boolean;
@@ -690,7 +689,7 @@ end;
 
 constructor TOperand.Create;
 begin
-  size:=S_NO;
+  size:=OS_NO;
   hastype:=false;
   hasvar:=false;
   FillChar(Opr,sizeof(Opr),0);
@@ -702,32 +701,33 @@ begin
 end;
 
 
-Procedure TOperand.SetCorrectSize(opcode:tasmop);
-begin
-end;
-
 Procedure TOperand.SetSize(_size:longint;force:boolean);
 begin
   if force or
-     ((size = S_NO) and (_size<=extended_size)) then
+     ((size = OS_NO) and (_size<=extended_size)) then
    Begin
      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
       begin
         { extended_size can also be 8, resulting in a
           duplicate label }
         if _size=extended_size then
-          size:=S_FX;
+          size:=OS_F80;
       end;
      end;
    end;
 end;
 
 
+Procedure TOperand.SetCorrectSize(opcode:tasmop);
+begin
+end;
+
+
 Function TOperand.SetupResult:boolean;
 Begin
   SetupResult:=false;
@@ -1016,7 +1016,6 @@ end;
 constructor TInstruction.create;
 Begin
   Opcode:=A_NONE;
-  Opsize:=S_NO;
   Condition:=C_NONE;
   Ops:=0;
   InitOperands;
@@ -1554,7 +1553,12 @@ end;
 end.
 {
   $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
 
   Revision 1.60  2003/05/15 18:58:53  peter

+ 223 - 350
compiler/sparc/aasmcpu.pas

@@ -1,10 +1,8 @@
-{*****************************************************************************
+{
     $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
     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
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- ****************************************************************************}
+
+ ****************************************************************************
+}
 unit aasmcpu;
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
+
 interface
+
 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
-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
-        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;
-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
 }

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 540 - 860
compiler/sparc/cgcpu.pas


+ 782 - 612
compiler/sparc/cpubase.pas

@@ -1,8 +1,8 @@
-{******************************************************************************
+{
     $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
     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
     along with this program; if not, write to the Free Software
     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}
 
 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.}
-  { 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}
   RegEnum2Number:array[TCpuRegister]of cardinal=(
     NR_NO,
@@ -410,121 +511,127 @@ const
     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
 *****************************************************************************}
-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
 *****************************************************************************}
-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
 *****************************************************************************}
@@ -539,310 +646,373 @@ type
      AC_FPUUP,
      AC_SSE,
      AC_SSEUP);
+{$endif dummy}
 
 {*****************************************************************************
                                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);
-              { overlay a registerlow }
+          { overlay a registerlow }
           2 : (registerlow : tregister);
-              { overlay a 64 Bit register type }
+          { overlay a 64 Bit register type }
           3 : (reg64 : 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;
-         case TCGLoc of
-            LOC_FLAGS : (resflags : tresflags);
+         loc : tcgloc;
+         case tcgloc of
+            LOC_CREFERENCE,LOC_REFERENCE : (reference : treference);
             LOC_CONSTANT : (
               case longint of
+{$ifdef FPC_BIG_ENDIAN}
+                1 : (_valuedummy,value : AWord);
+{$else FPC_BIG_ENDIAN}
                 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 }
                 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;
+
 {*****************************************************************************
                                  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
 *****************************************************************************}
-  {# 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
 *****************************************************************************}
-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
 
-  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
             inc(offset,offsetfixup);
             offsetfixup:=0;
-            if base.enum>lastreg then
+            if (base.enum<>R_INTREGISTER) or (index.enum<>R_INTREGISTER) then
               internalerror(200301081);
-            if index.enum>lastreg then
-              internalerror(200301081);
-
             if assigned(symbol) then
               begin
+                 if (base.number<>NR_NO) or (index.number<>NR_NO) then
+                   internalerror(2003052601);
                  GetReferenceString:=symbol.name;
                  if offset>0 then
                    GetReferenceString:=GetReferenceString+'+'+ToStr(offset)
                  else if offset<0 then
                    GetReferenceString:=GetReferenceString+ToStr(offset);
-                 if (base.enum<>R_NONE) or (index.enum<>R_NONE) then
-                   internalerror(2003052601);
                  if symaddr=refs_hi then
                    GetReferenceString:='%hi('+GetReferenceString+')'
                  else if symaddr=refs_lo then
@@ -71,9 +68,9 @@ unit cpugas;
               end
             else
               begin
-                if base.enum<>R_NONE then
+                if base.number<>NR_NO then
                   GetReferenceString:=std_reg2str[base.enum]+'+';
-                if index.enum<>R_NONE then
+                if index.number<>NR_NO then
                   GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
                 if Offset<>0 then
                    internalerror(2003052603);
@@ -199,7 +196,12 @@ begin
 end.
 {
     $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
 
     Revision 1.14  2003/05/07 11:55:34  mazen

+ 267 - 240
compiler/sparc/cpupara.pas

@@ -1,8 +1,8 @@
-{******************************************************************************
+{
     $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
     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.
  *****************************************************************************}
 unit cpupara;
-{SPARC specific calling conventions are handled by this unit}
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
+
 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
-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
-        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
-              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
-                  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
-                      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
-                    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;
-          LOC_FPUREGISTER:
-            begin
-              if hp.paratyp in [vs_var,vs_out]
-              then
+
+              LOC_FPUREGISTER:
                 begin
-                  if NextIntReg.enum<=R_O5
-                  then
+                  if hp.paratyp in [vs_var,vs_out] then
                     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
                   else
                     begin
                       {!!!!!!!}
                       hp.paraloc.size:=def_cgsize(hp.paratype.def);
-                      internalerror(2002071006);
+                      internalerror(2002071004);
                     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
-                  {!!!!!!!}
-                  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;
+
+              else
+                internalerror(2002071002);
             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;
-        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;
+
+
+    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
    ParaManager:=TSparcParaManager.create;
 end.
 {
   $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
 
   Revision 1.15  2003/04/23 12:35:35  florian

+ 7 - 2
compiler/sparc/cpupi.pas

@@ -101,7 +101,12 @@ begin
 end.
 {
   $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
     * some reformatting done
 
@@ -133,7 +138,7 @@ end.
   + added debug output on screen with -an command line option
 
   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
   * fixing return value variable address

+ 6 - 3
compiler/sparc/cputarg.pas

@@ -48,14 +48,17 @@ implementation
 **************************************}
 
       ,CpuGas
-      ,ogcoff
-      ,ogelf
       ;
 
 end.
 {
   $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
 
   Revision 1.2  2002/09/07 15:25:14  peter

+ 56 - 65
compiler/sparc/ncpuadd.pas

@@ -34,8 +34,8 @@ type
     procedure second_addfloat;
     function GetResFlags(unsigned:Boolean):TResFlags;
     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 Load_left_right(cmpop,load_constants:Boolean);
     procedure pass_left_and_right;
@@ -47,12 +47,11 @@ uses
   cutils,verbose,globals,
   symconst,symdef,SymType,paramgr,
   aasmbase,aasmtai,aasmcpu,defutil,htypechk,
-  cgbase,pass_2,regvars,
+  cpuinfo,cgbase,pass_2,regvars,
   cpupara,
   ncon,nset,
   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);
   begin
     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
                 exprasmlist.concat(taicpu.op_reg_reg(A_JMPL,left.location.register,right.location.register))
               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);
             end;
           else
@@ -280,7 +279,7 @@ function TSparcAddNode.GetResFlags(unsigned:Boolean):TResFlags;
             end;
     end;
   end;
-procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
+procedure TSparcAddNode.left_must_be_reg(OpSize:TcgSize;NoSwap:Boolean);
   begin
     if(left.location.loc=LOC_REGISTER)
     then
@@ -296,10 +295,10 @@ procedure TSparcAddNode.left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
       begin
 {maybe we can reuse a constant register when the operation is a comparison that
 doesn't change the value of the register}
-        location_force_reg(exprasmlist,left.location,opsize_2_cgsize[opsize],(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
+        location_force_reg(exprasmlist,left.location,opsize,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
       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
     power:LongInt;
     hl4:TAsmLabel;
@@ -398,12 +397,12 @@ procedure TSparcAddNode.emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extr
         IF cs_check_overflow IN aktlocalswitches
         THEN
           begin
-      //      getlabel(hl4);
+            objectlibrary.getlabel(hl4);
             IF unsigned
             THEN
-              exprasmList.concat(Taicpu.Op_sym(A_JMPL,S_NO,hl4))
+              exprasmList.concat(Taicpu.Op_sym(A_JMPL,hl4))
             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_label(exprasmlist,hl4);
           end;
@@ -425,7 +424,7 @@ procedure TSparcAddNode.emit_compare(unsigned:boolean);
     then
       begin
 {$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
           internalerror(2002080301);
 {$endif extdebug}
@@ -463,7 +462,7 @@ procedure TSparcAddNode.emit_compare(unsigned:boolean);
           if useconst
           then
             exprasmlist.concat(taicpu.op_reg_const(op,
-              left.location.register,longint(right.location.value)))
+              left.location.register,right.location.value))
           else
             begin
               exprasmlist.concat(taicpu.op_reg_reg(op,left.location.register,tmpreg));
@@ -495,7 +494,6 @@ procedure TSparcAddNode.second_add64bit;
   var
     op         : TOpCG;
     op1,op2    : TAsmOp;
-    hl4        : tasmlabel;
     cmpop,
     unsigned   : boolean;
     r          : Tregister;
@@ -600,6 +598,7 @@ procedure TSparcAddNode.second_add64bit;
 
     var
       tempreg64: tregister64;
+      zeroreg : tregister;
 
       begin
         firstcomplex(self);
@@ -681,7 +680,7 @@ procedure TSparcAddNode.second_add64bit;
                             tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist,OS_INT)
                           else
                             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)
                           else
                             tempreg64.reghi := left.location.registerhigh;
@@ -690,25 +689,25 @@ procedure TSparcAddNode.second_add64bit;
                       if (right.location.valueqword <> 0) then
                         { negative values can be handled using SUB, }
                         { 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,
-                            right.location.valueqword,
+                            lo(right.location.valueqword),
                             left.location.registerlow,tempreg64.reglo)
                         else
                           cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
-                            right.location.valueqword,
+                            lo(right.location.valueqword),
                             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,
-                            right.location.valueqword shr 32,
+                            hi(right.location.valueqword),
                             left.location.registerhigh,tempreg64.reghi)
                         else
                           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);
                     end
                   else
@@ -720,14 +719,14 @@ procedure TSparcAddNode.second_add64bit;
                          tempreg64);
                     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);
-                  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);
 
                   location_reset(location,LOC_FLAGS,OS_NO);
@@ -735,7 +734,7 @@ procedure TSparcAddNode.second_add64bit;
                 end;
               xorn,orn,andn,addn:
                 begin
-                  if (location.registerlow.enum = R_NO) then
+                  if (location.registerlow.number = NR_NO) then
                     begin
                       location.registerlow := 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
                     begin
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                          location.registerlow := rg.getregisterint(exprasmlist,OS_INT);
                          location.registerhigh := rg.getregisterint(exprasmlist,OS_INT);
@@ -775,7 +774,7 @@ procedure TSparcAddNode.second_add64bit;
                     end
                   else if ((left.location.valueqword shr 32) = 0) then
                     begin
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                          location.registerlow := 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
                     begin
                       // (const32 shl 32) - reg64
-                      if (location.registerlow.enum = R_NO) then
+                      if (location.registerlow.number = NR_NO) then
                         begin
                          location.registerlow := 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);
                       if (left.location.loc = LOC_REGISTER) then
                         location.register64 := left.location.register64
-                      else if (location.registerlow.enum = R_NO) then
+                      else if (location.registerlow.number = NR_NO) then
                         begin
                          location.registerlow := 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
       location_copy(location,left.location);
   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;
 {is also being used for "xor", and "mul", "sub", or and comparative operators}
   var
     popeax,popedx,pushedfpu,mboverflow,cmpop:Boolean;
     op:TAsmOp;
     power:LongInt;
-    OpSize:TOpSize;
+    OpSize:TcgSize;
     unsigned:Boolean;{true, if unsigned types are compared}
     extra_not:Boolean;
     cgop:TOpCg;
   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
       orddef:
         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];
     unsigned:=not(is_signed(left.resulttype.def))or
               not(is_signed(right.resulttype.def));
-    opsize:=def_opsize(left.resulttype.def);
+    opsize:=def_cgsize(left.resulttype.def);
     pass_left_and_right;
     { set result location }
     if not cmpop
@@ -1079,8 +1069,7 @@ procedures }
     else
       location_reset(location,LOC_FLAGS,OS_NO);
     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);
     if not(cs_check_overflow in aktlocalswitches)or cmpop or (nodetype in [orn,andn,xorn])
     then
@@ -1122,22 +1111,18 @@ procedures }
           CGMessage(type_e_mismatch);
         end;
    { 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);
-        if not cmpOp
-        then
+        if not cmpOp then
           emit_generic_code(op,opsize,unsigned,extra_not,mboverflow)
         else
           emit_compare(unsigned);
         location_freetemp(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
             location_freetemp(exprasmlist,left.location);
             location_release(exprasmlist,left.location);
@@ -1176,12 +1161,18 @@ procedure TSparcAddNode.pass_left_and_right;
         left.location.register := tmpreg;
       end;
   end;
+
 begin
   cAddNode:=TSparcAddNode;
 end.
 {
     $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
 
     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);
            end;
        { free used registers }
-        if numerator.enum <> resultreg.enum then
+        if numerator.number <> resultreg.number then
           rg.ungetregisterint(exprasmlist,numerator);
         { set result location }
         location.loc:=LOC_REGISTER;
@@ -479,7 +479,12 @@ begin
 end.
 {
   $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
 
   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_REG_SMASK = $00070000;  { special register operands: these may be treated differently  }
                                  { 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_AX    = $00211002;    { ditto  }
       OT_REG_EAX   = $00211004;    { and again  }
@@ -2024,7 +2024,12 @@ implementation
 end.
 {
   $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
 
   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;
       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
-        result := regsize_2_cgsize[reg2opsize(reg)];
+        result := opsize_2_cgsize[reg2opsize(reg)];
       end;
 
 
@@ -1941,7 +1946,12 @@ unit cgx86;
 end.
 {
   $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
 
   Revision 1.46  2003/05/16 14:33:31  peter

+ 8 - 6
compiler/x86/cpubase.pas

@@ -487,9 +487,6 @@ uses
 
       max_operands = 3;
 
-      lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
-        LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
-
       {# Constant defining possibly all registers which might require saving }
       ALL_REGISTERS = [firstreg..lastreg];
       ALL_INTREGISTERS = [1..255];
@@ -715,7 +712,12 @@ implementation
 end.
 {
   $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
     * fixed some x86-64 problems
     * merged some more x86-64 and i386 code
@@ -798,10 +800,10 @@ end.
     + very basic support for float128 type (x86-64 only)
 
   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
-  + 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
     * fixes for Delphi 6 compilation

+ 58 - 33
compiler/x86/rax86.pas

@@ -42,11 +42,15 @@ Procedure FWaitWarning;
 
 type
   T386Operand=class(TOperand)
+    opsize  : topsize;
+    Procedure SetSize(_size:longint;force:boolean);override;
     Procedure SetCorrectSize(opcode:tasmop);override;
   end;
 
   T386Instruction=class(TInstruction)
     OpOrder : TOperandOrder;
+    opsize  : topsize;
+    constructor Create;
     { Operand sizes }
     procedure AddReferenceSizes;
     procedure SetInstructionOpsize;
@@ -85,7 +89,7 @@ implementation
 uses
   globtype,globals,systems,verbose,
   cpuinfo,
-  itx86att;
+  itx86att,cgx86;
 
 {$define ATTOP}
 {$define INTELOP}
@@ -196,20 +200,27 @@ end;
                               T386Operand
 *****************************************************************************}
 
+Procedure T386Operand.SetSize(_size:longint;force:boolean);
+begin
+  inherited SetSize(_size,force);
+  opsize:=TCGSize2Opsize[size];
+end;
+
+
 Procedure T386Operand.SetCorrectSize(opcode:tasmop);
 begin
   if gas_needsuffix[opcode]=attsufFPU then
     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
   else if gas_needsuffix[opcode]=attsufFPUint then
     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;
@@ -219,6 +230,13 @@ end;
                               T386Instruction
 *****************************************************************************}
 
+constructor T386Instruction.Create;
+begin
+  inherited Create;
+  Opsize:=S_NO;
+end;
+
+
 procedure T386Instruction.SwapOperands;
 begin
   Inherited SwapOperands;
@@ -242,7 +260,7 @@ begin
   for i:=1to ops do
    begin
    operands[i].SetCorrectSize(opcode);
-   if (operands[i].size=S_NO) then
+   if t386operand(operands[i]).opsize=S_NO then
     begin
       case operands[i].Opr.Typ of
         OPR_REFERENCE :
@@ -265,19 +283,19 @@ begin
                   { if no register then take the opsize (which is available with ATT),
                     if not availble then give an error }
                   if opsize<>S_NO then
-                    operands[i].size:=opsize
+                    t386operand(operands[i]).opsize:=opsize
                   else
                    begin
                      Message(asmr_e_unable_to_determine_reference_size);
                      { recovery }
-                     operands[i].size:=S_L;
+                     t386operand(operands[i]).opsize:=S_L;
                    end;
                 end;
              end
             else
              begin
                if opsize<>S_NO then
-                 operands[i].size:=opsize
+                 t386operand(operands[i]).opsize:=opsize
              end;
           end;
         OPR_SYMBOL :
@@ -292,7 +310,7 @@ begin
                operands[i].opr.ref.symbol:=s;
                operands[i].opr.ref.offset:=so;
              end;
-            operands[i].size:=S_L;
+            t386operand(operands[i]).opsize:=S_L;
           end;
       end;
     end;
@@ -319,20 +337,20 @@ begin
            (operands[1].opr.reg.number<=nlastsreg))) then
         opsize:=S_L
       else
-        opsize:=operands[1].size;
+        opsize:=t386operand(operands[1]).opsize;
     2 :
       begin
         case opcode of
           A_MOVZX,A_MOVSX :
             begin
-              case operands[1].size of
+              case t386operand(operands[1]).opsize of
                 S_W :
-                  case operands[2].size of
+                  case t386operand(operands[2]).opsize of
                     S_L :
                       opsize:=S_WL;
                   end;
                 S_B :
-                  case operands[2].size of
+                  case t386operand(operands[2]).opsize of
                     S_W :
                       opsize:=S_BW;
                     S_L :
@@ -344,13 +362,13 @@ begin
                      32 bit register or memory, so no opsize is correct here PM }
             exit;
           A_OUT :
-            opsize:=operands[1].size;
+            opsize:=t386operand(operands[1]).opsize;
           else
-            opsize:=operands[2].size;
+            opsize:=t386operand(operands[2]).opsize;
         end;
       end;
     3 :
-      opsize:=operands[3].size;
+      opsize:=t386operand(operands[3]).opsize;
   end;
 end;
 
@@ -391,11 +409,11 @@ begin
       begin
         case opsize of
           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 :
-            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 :
-            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
@@ -404,8 +422,8 @@ begin
      for i:=1 to ops do
       begin
         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;
       end;
    end;
@@ -483,19 +501,21 @@ begin
   else
    begin
      if (Ops=2) and (operands[1].opr.typ=OPR_REGISTER) then
-      siz:=operands[1].size
+      siz:=t386operand(operands[1]).opsize
      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 }
-     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;
    end;
 
    if ((opcode=A_MOVD)or
        (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;
    { NASM does not support FADD without args
      as alias of FADDP
@@ -636,10 +656,10 @@ begin
        OPR_REFERENCE:
          begin
            ai.loadref(i-1,operands[i].opr.ref);
-           if operands[i].size<>S_NO then
+           if t386operand(operands[i]).opsize<>S_NO then
              begin
                asize:=0;
-               case operands[i].size of
+               case t386operand(operands[i]).opsize of
                    S_B :
                      asize:=OT_BITS8;
                    S_W, S_IS :
@@ -684,7 +704,12 @@ end;
 end.
 {
   $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
 
   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_reg = R_RSP;
       NR_STACK_POINTER_REG = NR_RSP;
       {# Frame pointer register }
-      frame_pointer_reg = R_RBP;
       NR_FRAME_POINTER_REG = NR_RBP;
       { 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
       }
-      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;
       mmresultreg = R_MM0;
@@ -214,7 +211,12 @@ const
 
 {
   $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
 
   Revision 1.2  2002/04/25 16:12:09  florian

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно