Преглед на файлове

* started to fix and clean up the sparc port

florian преди 22 години
родител
ревизия
a8eb2ab740
променени са 8 файла, в които са добавени 1530 реда и са изтрити 1498 реда
  1. 9 8
      compiler/powerpc/cgcpu.pas
  2. 16 47
      compiler/sparc/aasmcpu.pas
  3. 1232 1209
      compiler/sparc/cgcpu.pas
  4. 78 58
      compiler/sparc/cpubase.pas
  5. 174 164
      compiler/sparc/cpugas.pas
  6. 7 4
      compiler/systems.pas
  7. 5 3
      compiler/systems/i_bsd.pas
  8. 9 5
      compiler/x86/agx86att.pas

+ 9 - 8
compiler/powerpc/cgcpu.pas

@@ -154,14 +154,12 @@ const
     uses
     uses
        globtype,globals,verbose,systems,cutils,symconst,symdef,symsym,rgobj,tgobj,cpupi;
        globtype,globals,verbose,systems,cutils,symconst,symdef,symsym,rgobj,tgobj,cpupi;
 
 
-{ parameter passing... Still needs extra support from the processor }
-{ independent code generator                                        }
+    { parameter passing... Still needs extra support from the processor }
+    { independent code generator                                        }
 
 
     procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
     procedure tcgppc.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
-
       var
       var
         ref: treference;
         ref: treference;
-
       begin
       begin
         case locpara.loc of
         case locpara.loc of
           LOC_REGISTER,LOC_CREGISTER:
           LOC_REGISTER,LOC_CREGISTER:
@@ -249,9 +247,9 @@ const
       var
       var
         href : treference;
         href : treference;
       begin
       begin
-         {MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
-         if it is a cross-TOC call. If so, it also replaces the NOP
-         with some restore code.}
+         { MacOS: The linker on MacOS (PPCLink) inserts a call to glue code,
+           if it is a cross-TOC call. If so, it also replaces the NOP
+           with some restore code.}
          list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s)));
          list.concat(taicpu.op_sym(A_BL,objectlibrary.newasmsymbol(s)));
          if target_info.system=system_powerpc_macos then
          if target_info.system=system_powerpc_macos then
            list.concat(taicpu.op_none(A_NOP));
            list.concat(taicpu.op_none(A_NOP));
@@ -2442,7 +2440,10 @@ begin
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.96  2003-05-24 11:59:42  jonas
+  Revision 1.97  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.96  2003/05/24 11:59:42  jonas
     * fixed integer typeconversion problems
     * fixed integer typeconversion problems
 
 
   Revision 1.95  2003/05/23 18:51:26  jonas
   Revision 1.95  2003/05/23 18:51:26  jonas

+ 16 - 47
compiler/sparc/aasmcpu.pas

@@ -1,7 +1,7 @@
 {*****************************************************************************
 {*****************************************************************************
     $Id$
     $Id$
     Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
     Copyright (c) 1998-2000 by Florian Klaempfl and Peter Vreman
-    
+
     * This code was inspired by the NASM sources
     * This code was inspired by the NASM sources
       The Netwide Assembler is copyright (C) 1996 Simon Tatham and
       The Netwide Assembler is copyright (C) 1996 Simon Tatham and
       Julian Hall. All rights reserved.
       Julian Hall. All rights reserved.
@@ -10,7 +10,7 @@
     it under the terms of the GNU General Public License as published by
     it under the terms of the GNU General Public License as published by
     the Free Software Foundation; either version 2 of the License, or
     the Free Software Foundation; either version 2 of the License, or
     (at your option) any later version.
     (at your option) any later version.
-    
+
     This program is distributed in the hope that it will be useful,
     This program is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
@@ -50,6 +50,7 @@ type
     constructor op_ref_reg(Op:TAsmOp;const Ref:TReference;Reg: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_ref_ref(op:tasmop;_size:topsize;const _op1,_op2:treference);
     constructor op_reg_reg_reg(op:tasmop;_op1,_op2,_op3: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;SrcReg:TRegister;value:aWord;DstReg: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_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);
     constructor op_const_reg_ref(op:tasmop;_size:topsize;_op1:aword;_op2:tregister;const _op3:treference);
@@ -60,11 +61,7 @@ type
     constructor op_sym_ofs(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint);
     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_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);
     constructor op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1ofs:longint;const _op2:treference);
-    constructor op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
-    constructor op_raddr_reg(op:TAsmOp;rg1,rg2:TRegister;reg:TRegister);
     procedure changeopsize(siz:topsize);
     procedure changeopsize(siz:topsize);
-    procedure loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
-    procedure loadraddr(opidx:longint;rg1,rg2:TRegister);
   private
   private
     procedure init(_size:topsize);{this need to be called by all constructor}
     procedure init(_size:topsize);{this need to be called by all constructor}
   public
   public
@@ -195,6 +192,15 @@ constructor taicpu.op_reg_reg_reg(op:tasmop;_op1,_op2,_op3:tregister);
      loadreg(1,_op2);
      loadreg(1,_op2);
      loadreg(2,_op3);
      loadreg(2,_op3);
   end;
   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);
 constructor taicpu.op_reg_const_reg(op:TAsmOp;SrcReg:TRegister;Value:aWord;DstReg:TRegister);
   begin
   begin
     inherited Create(Op);
     inherited Create(Op);
@@ -263,22 +269,6 @@ constructor taicpu.op_sym_ofs_ref(op:tasmop;_size:topsize;_op1:tasmsymbol;_op1of
      loadref(1,_op2);
      loadref(1,_op2);
   end;
   end;
 
 
-constructor taicpu.op_caddr_reg(op:TAsmOp;rgb:TRegister;cnst:Integer;reg:TRegister);
-  begin
-    inherited create(op);
-    init(S_SW);
-    ops:=2;
-    loadcaddr(0,rgb,cnst);
-    loadreg(1,reg);
-  end;
-constructor taicpu.op_raddr_reg(op:TAsmOp;rg1,rg2,reg:TRegister);
-  begin
-    inherited create(op);
-    init(S_SW);
-    ops:=2;
-    loadraddr(0,rg1,rg2);
-    loadreg(1,reg);
-  end;
 procedure taicpu.Swatoperands;
 procedure taicpu.Swatoperands;
   var
   var
     p:TOper;
     p:TOper;
@@ -322,30 +312,6 @@ 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_N
       {$ENDIF EXTDEBUG}
       {$ENDIF EXTDEBUG}
       end;
       end;
   end;
   end;
-procedure taicpu.loadcaddr(opidx:longint;aReg:TRegister;cnst:Integer);
-  begin
-    if opidx>=ops
-    then
-      ops:=opidx+1;
-    with oper[opidx] do
-      begin
-        typ:=top_caddr;
-        regb:=aReg;
-        const13:=cnst;
-      end;
-  end;
-procedure taicpu.loadraddr(opidx:longint;rg1,rg2:TRegister);
-  begin
-    if opidx>=ops
-    then
-      ops:=opidx+1;
-    with oper[opidx] do
-      begin
-        typ:=top_caddr;
-        reg1:=rg1;
-        reg2:=rg2;
-      end;
-  end;
 procedure DoneAsm;
 procedure DoneAsm;
   begin
   begin
   end;
   end;
@@ -355,7 +321,10 @@ procedure InitAsm;
 end.
 end.
 {
 {
     $Log$
     $Log$
-    Revision 1.25  2003-05-07 11:45:02  mazen
+    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
     - removed unused code
 
 
     Revision 1.24  2003/05/07 11:28:26  mazen
     Revision 1.24  2003/05/07 11:28:26  mazen

+ 1232 - 1209
compiler/sparc/cgcpu.pas

@@ -106,44 +106,47 @@ CONST
   TOpCmp2AsmCond:ARRAY[topcmp]OF TAsmCond=(C_NONE,C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
   TOpCmp2AsmCond:ARRAY[topcmp]OF TAsmCond=(C_NONE,C_E,C_G,C_L,C_GE,C_LE,C_NE,C_BE,C_B,C_AE,C_A);
   TCGSize2OpSize:ARRAY[tcgsize]OF TOpSize=(S_NO,S_B,S_W,S_SW,S_SW,S_B,S_W,S_SW,S_SW,S_FS,S_FD,S_FQ,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
   TCGSize2OpSize:ARRAY[tcgsize]OF TOpSize=(S_NO,S_B,S_W,S_SW,S_SW,S_B,S_W,S_SW,S_SW,S_FS,S_FD,S_FQ,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO,S_NO);
 
 
-IMPLEMENTATION
-USES
-  globtype,globals,verbose,systems,cutils,
-  symdef,symsym,defutil,paramgr,
-  rgobj,tgobj,rgcpu,cpupi;
-procedure TCgSparc.a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);
-  var
-    r2:Tregister;
-  begin
-    r2.enum:=R_G0;
-    with list,LocPara do
-      case Loc of
-        LOC_REGISTER:
-          case Sz of
-            OS_8,OS_S8:
-              Concat(taicpu.op_Reg_Const_Reg(A_AND,r,$FF,Register));
-            OS_16,OS_S16:
-              begin
-                Concat(taicpu.op_Reg_Reg_Reg(A_AND,r,r2,Register));
-                {This will put 00...00111 in the hiest 22 bits of the reg}
-                Concat(taicpu.op_Reg_Const_Reg(A_SETHI,Register,$7,Register));
-              end;
-            OS_32,OS_S32:
-              if r.enum<>Register.enum
-              then
-                Concat(taicpu.op_Reg_Reg_Reg(A_OR,r,r2,Register));
-            else
-              InternalError(2002032212);
-          end;
-        else
-          InternalError(2002101002);
-      end;
-  end;
-procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aword;CONST LocPara:TParaLocation);
-  var
-    Ref:TReference;
-  begin
-    with List do
+implementation
+
+  uses
+    globtype,globals,verbose,systems,cutils,
+    symdef,symsym,defutil,paramgr,
+    rgobj,tgobj,rgcpu,cpupi;
+
+  procedure TCgSparc.a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);
+    var
+      r2:Tregister;
+    begin
+      r2.enum:=R_G0;
+      with list,LocPara do
+        case Loc of
+          LOC_REGISTER:
+            case Sz of
+              OS_8,OS_S8:
+                Concat(taicpu.op_Reg_Const_Reg(A_AND,r,$FF,Register));
+              OS_16,OS_S16:
+                begin
+                  Concat(taicpu.op_Reg_Reg_Reg(A_AND,r,r2,Register));
+                  {This will put 00...00111 in the hiest 22 bits of the reg}
+                  Concat(taicpu.op_Reg_Const_Reg(A_SETHI,Register,$7,Register));
+                end;
+              OS_32,OS_S32:
+                if r.enum<>Register.enum
+                then
+                  Concat(taicpu.op_Reg_Reg_Reg(A_OR,r,r2,Register));
+              else
+                InternalError(2002032212);
+            end;
+          else
+            InternalError(2002101002);
+        end;
+    end;
+
+
+  procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aword;const LocPara:TParaLocation);
+    var
+      Ref:TReference;
+    begin
       case locpara.loc of
       case locpara.loc of
         LOC_REGISTER,LOC_CREGISTER:
         LOC_REGISTER,LOC_CREGISTER:
           a_load_const_reg(list,size,a,locpara.register);
           a_load_const_reg(list,size,a,locpara.register);
@@ -157,216 +160,195 @@ procedure TCgSparc.a_param_const(list:TAasmOutput;size:tcgsize;a:aword;CONST Loc
         else
         else
           InternalError(2002122200);
           InternalError(2002122200);
       end;
       end;
-    if locpara.sp_fixup<>0
-    then
-      InternalError(2002122201);
-  end;
-procedure TCgSparc.a_param_ref(list:TAasmOutput;sz:TCgSize;const r:TReference;const LocPara:TParaLocation);
-  var
-    ref: treference;
-    tmpreg:TRegister;
-  begin
-    with LocPara do
+      if locpara.sp_fixup<>0
+      then
+        InternalError(2002122201);
+    end;
+
+
+  procedure TCgSparc.a_param_ref(list:TAasmOutput;sz:TCgSize;const r:TReference;const LocPara:TParaLocation);
+    var
+      ref: treference;
+      tmpreg:TRegister;
+    begin
+      with LocPara do
+        case locpara.loc of
+          LOC_REGISTER,LOC_CREGISTER:
+            a_load_ref_reg(list,sz,r,Register);
+          LOC_REFERENCE:
+            begin
+              { Code conventions need the parameters being allocated in %o6+92. See
+                comment on g_stack_frame }
+              if locpara.sp_fixup<92 then
+                InternalError(2002081104);
+              reference_reset(ref);
+              ref.base:=locpara.reference.index;
+              ref.offset:=locpara.reference.offset;
+              tmpreg := get_scratch_reg_int(list,sz);
+              a_load_ref_reg(list,sz,r,tmpreg);
+              a_load_reg_ref(list,sz,tmpreg,ref);
+              free_scratch_reg(list,tmpreg);
+            end;
+          LOC_FPUREGISTER,LOC_CFPUREGISTER:
+            case sz of
+              OS_32:
+                a_loadfpu_ref_reg(list,OS_F32,r,locpara.register);
+              OS_64:
+                a_loadfpu_ref_reg(list,OS_F64,r,locpara.register);
+            else
+              internalerror(2002072801);
+            end;
+          else
+            internalerror(2002081103);
+        end;
+    end;
+
+
+  procedure TCgSparc.a_paramaddr_ref(list:TAasmOutput;CONST r:TReference;CONST LocPara:TParaLocation);
+    var
+      Ref:TReference;
+      TmpReg:TRegister;
+    begin
       case locpara.loc of
       case locpara.loc of
         LOC_REGISTER,LOC_CREGISTER:
         LOC_REGISTER,LOC_CREGISTER:
-          a_load_ref_reg(list,sz,r,Register);
+          a_loadaddr_ref_reg(list,r,locpara.register);
         LOC_REFERENCE:
         LOC_REFERENCE:
           begin
           begin
-          {Code conventions need the parameters being allocated in %o6+92. See
-          comment on g_stack_frame}
-            if locpara.sp_fixup<92
-            then
-              InternalError(2002081104);
             reference_reset(ref);
             reference_reset(ref);
-            ref.base:=locpara.reference.index;
-            ref.offset:=locpara.reference.offset;
-            tmpreg := get_scratch_reg_int(list,sz);
-            a_load_ref_reg(list,sz,r,tmpreg);
-            a_load_reg_ref(list,sz,tmpreg,ref);
+            ref.base := locpara.reference.index;
+            ref.offset := locpara.reference.offset;
+            tmpreg := get_scratch_reg_address(list);
+            a_loadaddr_ref_reg(list,r,tmpreg);
+            a_load_reg_ref(list,OS_ADDR,tmpreg,ref);
             free_scratch_reg(list,tmpreg);
             free_scratch_reg(list,tmpreg);
           end;
           end;
-        LOC_FPUREGISTER,LOC_CFPUREGISTER:
-                case sz of
-                OS_32:
-                a_loadfpu_ref_reg(list,OS_F32,r,locpara.register);
-                  OS_64:
-                  a_loadfpu_ref_reg(list,OS_F64,r,locpara.register);
-            else
-            internalerror(2002072801);
-                end;
-                else
-                internalerror(2002081103);
-        end;
-  end;
-procedure TCgSparc.a_paramaddr_ref(list:TAasmOutput;CONST r:TReference;CONST LocPara:TParaLocation);
-  var
-    Ref:TReference;
-    TmpReg:TRegister;
-  begin
-    case locpara.loc of
-      LOC_REGISTER,LOC_CREGISTER:
-        a_loadaddr_ref_reg(list,r,locpara.register);
-      LOC_REFERENCE:
-        begin
-          reference_reset(ref);
-          ref.base := locpara.reference.index;
-          ref.offset := locpara.reference.offset;
-          tmpreg := get_scratch_reg_address(list);
-          a_loadaddr_ref_reg(list,r,tmpreg);
-          a_load_reg_ref(list,OS_ADDR,tmpreg,ref);
-          free_scratch_reg(list,tmpreg);
-        end;
-    else
-      internalerror(2002080701);
-    end;
-  end;
-procedure TCgSparc.a_call_name(list:TAasmOutput;CONST s:string);
-  BEGIN
-    WITH List,objectlibrary DO
-      BEGIN
-        concat(taicpu.op_sym(A_CALL,S_SW,newasmsymbol(s)));
-        concat(taicpu.op_none(A_NOP));
-      END;
-  END;
-procedure TCgSparc.a_call_ref(list:TAasmOutput;CONST ref:TReference);
-  begin
-    list.concat(taicpu.op_ref(A_CALL,ref));
-    list.concat(taicpu.op_none(A_NOP));
-  end;
-procedure TCgSparc.a_call_reg(list:TAasmOutput;Reg:TRegister);
-  var
-    RetAddrReg:TRegister;
-  begin
-    with RetAddrReg do
-      begin
-        enum:=R_INTREGISTER;
-        Number:=NR_O7;
+      else
+        internalerror(2002080701);
       end;
       end;
-    list.concat(taicpu.op_reg_reg(A_JMPL,reg,RetAddrReg));
-    if target_info.system=system_sparc_linux
-    then
+    end;
+
+
+  procedure TCgSparc.a_call_name(list:TAasmOutput;const s:string);
+    begin
+      list.concat(taicpu.op_sym(A_CALL,S_SW,objectlibrary.newasmsymbol(s)));
       list.concat(taicpu.op_none(A_NOP));
       list.concat(taicpu.op_none(A_NOP));
-    include(current_procinfo.flags,pi_do_call);
- end;
-{********************** branch instructions ********************}
-procedure TCgSparc.a_jmp_always(List:TAasmOutput;l:TAsmLabel);
-  begin
-    List.Concat(TAiCpu.op_sym(A_BA,S_NO,objectlibrary.newasmsymbol(l.name)));
-  end;
-{********************** load instructions ********************}
-procedure TCgSparc.a_load_const_reg(list:TAasmOutput;size:TCGSize;a:aword;reg:TRegister);
-  var
-    r:Tregister;
-  begin
-    r.enum:=R_G0;
-    with List do
-      if a=0
-      then{R_G0 is usually set to zero, so we use it}
-        Concat(taicpu.op_reg_reg_reg(A_OR,r,r,reg))
-      else{There is no A_MOV in sparc, that's why we use A_OR with help of R_G0}
+         include(current_procinfo.flags,pi_do_call);
+    end;
+
+
+  procedure TCgSparc.a_call_ref(list:TAasmOutput;const ref:TReference);
+    begin
+      list.concat(taicpu.op_ref(A_CALL,ref));
+      list.concat(taicpu.op_none(A_NOP));
+      include(current_procinfo.flags,pi_do_call);
+    end;
+
+
+  procedure TCgSparc.a_call_reg(list:TAasmOutput;Reg:TRegister);
+    var
+      RetAddrReg:TRegister;
+    begin
+      with RetAddrReg do
         begin
         begin
-          Concat(taicpu.op_reg_const_reg(A_OR,r,a and $00001FFF,reg));
-          a:=a and $FFFFE000;
-          if a<>0
-          then
-            Concat(taicpu.op_const_reg(A_SETHI,a,reg));
+          enum:=R_INTREGISTER;
+          Number:=NR_O7;
         end;
         end;
-  END;
-procedure TCgSparc.a_load_const_ref(list:TAasmOutput;size:tcgsize;a:aword;CONST ref:TReference);
+      list.concat(taicpu.op_reg_reg(A_JMPL,reg,RetAddrReg));
+      { why only on Sparc/Linux? Doesn't use other implementations use the delay slot? (FK) }
+      if target_info.system=system_sparc_linux then
+        list.concat(taicpu.op_none(A_NOP));
+      include(current_procinfo.flags,pi_do_call);
+   end;
 
 
-var r:Tregister;
 
 
-  BEGIN
-    r.enum:=R_G0;
-    WITH List DO
-      IF a=0
-      THEN
-        Concat(taicpu.op_reg_ref(A_ST,r,Ref))
-      ELSE
-        BEGIN
-          r.enum:=R_G1;
-          a_load_const_reg(list,size,a,r);
-          a_load_reg_ref(list,size,r,Ref);
-        END;
-  END;
-procedure TCgSparc.a_load_reg_ref(list:TAasmOutput;size:TCGSize;reg:tregister;const Ref:TReference);
-  var
-    op:tasmop;
-  begin
-    case size of
-      { signed integer registers }
-      OS_S8:
-        Op:=A_STB;{Store Signed Byte}
-      OS_S16:
-        Op:=A_STH;{Store Signed Halfword}
-      OS_S32:
-        Op:=A_ST;{Store Word}
-      OS_S64:
-        Op:=A_STD;{Store Double Word}
-      { unsigned integer registers }
-    //A_STSTUB;{Store-Store Unsigned Byte}
-      OS_8:
-        Op:=A_STB;{Store Unsigned Bye}
-      OS_16:
-        Op:=A_STH;{Store Unsigned Halfword}
-      OS_32:
-        Op:=A_ST;{Store Word}
-      OS_64:
-        Op:=A_STD;{Store Double Word}
-      { floating-point real registers }
-      OS_F32:
-        Op:=A_STF;{Store Floating-point word}
-    //A_STFSR
-      OS_F64:
-        Op:=A_STDF;{Store Double Floating-point word}
-      //A_STC;{Store Coprocessor}
-      //A_STCSR;
-      //A_STDC;{Store Double Coprocessor}
+  procedure TCgSparc.a_jmp_always(List:TAasmOutput;l:TAsmLabel);
+    begin
+      List.Concat(TAiCpu.op_sym(A_BA,S_NO,objectlibrary.newasmsymbol(l.name)));
+    end;
+
+
+  {********************** load instructions ********************}
+  procedure TCgSparc.a_load_const_reg(list : TAasmOutput;size : TCGSize;a : aword;reg : TRegister);
+    var
+      r:Tregister;
+    begin
+      r.enum:=R_INTREGISTER;
+      r.number:=NR_G0;
+      { we don't use the set instruction here because it could be evalutated to two
+        instructions which would cause problems with the delay slot (FK) }
+      { sethi allows to set the upper 22 bit, so we'll take full advantage of it }
+      if (a and $3ff)=0 then
+        list.concat(taicpu.op_const_reg(A_SETHI,(a and $fffffc00) shr 10,reg))
+      else if (a and $ffffe000)=0 then
+        list.concat(taicpu.op_reg_const_reg(A_OR,r,a,reg))
       else
       else
-        InternalError(2002122100);
+        begin
+          list.concat(taicpu.op_const_reg(A_SETHI,(a and $ffffe000) shr 13,reg));
+          list.concat(taicpu.op_reg_const_reg(A_OR,r,a and $1fff,reg));
+        end;
     end;
     end;
-    with list do
-      concat(taicpu.op_reg_ref(op,reg,ref));
-  end;
-procedure TCgSparc.a_load_ref_reg(list:TAasmOutput;size:TCgSize;const ref:TReference;reg:tregister);
-  var
-    op:tasmop;
-  begin
-    case size of
-      { signed integer registers }
-      OS_S8:
-        Op:=A_LDSB;{Load Signed Byte}
-      OS_S16:
-        Op:=A_LDSH;{Load Signed Halfword}
-      OS_S32:
-        Op:=A_LD;{Load Word}
-      OS_S64:
-        Op:=A_LDD;{Load Double Word}
-      { unsigned integer registers }
-    //A_LDSTUB;{Load-Store Unsigned Byte}
-      OS_8:
-        Op:=A_LDUB;{Load Unsigned Bye}
-      OS_16:
-        Op:=A_LDUH;{Load Unsigned Halfword}
-      OS_32:
-        Op:=A_LD;{Load Word}
-      OS_64:
-        Op:=A_LDD;{Load Double Word}
-      { floating-point real registers }
-      OS_F32:
-        Op:=A_LDF;{Load Floating-point word}
-    //A_LDFSR
-      OS_F64:
-        Op:=A_LDDF;{Load Double Floating-point word}
-      //A_LDC;{Load Coprocessor}
-      //A_LDCSR;
-      //A_LDDC;{Load Double Coprocessor}
+
+
+  procedure TCgSparc.a_load_const_ref(list : TAasmOutput;size : tcgsize;a : aword;const ref : TReference);
+    var
+      r:Tregister;
+    begin
+      inherited a_load_const_ref(list,size,a,ref);
+      r.enum:=R_INTREGISTER;
+      r.number:=NR_G0;
+      if a=0 then
+        a_load_reg_ref(list,size,r,ref)
       else
       else
-        InternalError(2002122100);
+        inherited a_load_const_ref(list,size,a,ref);
     end;
     end;
-    with list do
-      concat(taicpu.op_ref_reg(op,ref,reg));
-  end;
+
+
+  procedure TCgSparc.a_load_reg_ref(list:TAasmOutput;size:TCGSize;reg:tregister;const Ref:TReference);
+    var
+      op:tasmop;
+    begin
+      case size of
+        { signed integer registers }
+        OS_8,
+        OS_S8:
+          Op:=A_STB;
+        OS_16,
+        OS_S16:
+          Op:=A_STH;
+        OS_32,
+        OS_S32:
+          Op:=A_ST;
+        else
+          InternalError(2002122100);
+      end;
+      list.concat(taicpu.op_reg_ref(op,reg,ref));
+    end;
+
+
+  procedure TCgSparc.a_load_ref_reg(list:TAasmOutput;size:TCgSize;const ref:TReference;reg:tregister);
+    var
+      op:tasmop;
+    begin
+      case size of
+        { signed integer registers }
+        OS_S8:
+          Op:=A_LDSB;{Load Signed Byte}
+        OS_S16:
+          Op:=A_LDSH;{Load Signed Halfword}
+        OS_8:
+          Op:=A_LDUB;{Load Unsigned Bye}
+        OS_16:
+          Op:=A_LDUH;{Load Unsigned Halfword}
+        OS_S32,
+        OS_32:
+          Op:=A_LD;{Load Word}
+        else
+          InternalError(2002122100);
+      end;
+      list.concat(taicpu.op_ref_reg(op,ref,reg));
+    end;
+
+
 procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
 procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,reg2:tregister);
   var
   var
     op:tasmop;
     op:tasmop;
@@ -409,1081 +391,1122 @@ procedure TCgSparc.a_load_reg_reg(list:TAasmOutput;fromsize,tosize:tcgsize;reg1,
           else internalerror(2002090901);
           else internalerror(2002090901);
         end;
         end;
   end;
   end;
-    { all fpu load routines expect that R_ST[0-7] means an fpu regvar and }
-    { R_ST means "the current value at the top of the fpu stack" (JM)     }
-procedure TCgSparc.a_loadfpu_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
 
 
-       begin
-{         if NOT (reg1 IN [R_F0..R_F31]) then
-           begin
-             list.concat(taicpu.op_reg(A_NONE,S_NO,
-               trgcpu(rg).correct_fpuregister(reg1,trgcpu(rg).fpuvaroffset)));
-             inc(trgcpu(rg).fpuvaroffset);
-           end;
-         if NOT (reg2 IN [R_F0..R_F31]) then
-           begin
-             list.concat(taicpu.op_reg(A_JMPL,S_NO,
-                 trgcpu(rg).correct_fpuregister(reg2,trgcpu(rg).fpuvaroffset)));
-             dec(trgcpu(rg).fpuvaroffset);
-           end;}
-       end;
-
-
-    procedure TCgSparc.a_loadfpu_ref_reg(list:TAasmOutput;size:tcgsize;CONST ref:TReference;reg:tregister);
-
-       begin
-         floatload(list,size,ref);
-{         if (reg <> R_ST) then
-           a_loadfpu_reg_reg(list,R_ST,reg);}
-       end;
-
-
-    procedure TCgSparc.a_loadfpu_reg_ref(list:TAasmOutput;size:tcgsize;reg:tregister;const ref:TReference);
-       const
-         FpuStoreInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
-                            { indexed? updating?}
-                    (((A_STF,A_STF),(A_STF,A_STF)),
-                     ((A_STDF,A_STDF),(A_STDF,A_STDF)));
-       var
-         op: tasmop;
-         ref2: treference;
-         freereg: boolean;
-       begin
-         if not(size in [OS_F32,OS_F64])
-         then
-           internalerror(200201122);
-{         ref2:=ref;
-         freereg:=fixref(list,ref2);
-         op:=fpustoreinstr[size,ref2.index.enum <> R_NO,false];
-         a_load_store(list,op,reg,ref2);
-         if freereg
-         then
-           cg.free_scratch_reg(list,ref2.base);}
-       end;
-
-
-    procedure TCgSparc.a_loadmm_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
-
-       begin
-//         list.concat(taicpu.op_reg_reg(A_NONEQ,S_NO,reg1,reg2));
-       end;
-
-
-    procedure TCgSparc.a_loadmm_ref_reg(list:TAasmOutput;CONST ref:TReference;reg:tregister);
-
-       begin
-//         list.concat(taicpu.op_ref_reg(A_NONEQ,S_NO,ref,reg));
-       end;
-
-
-    procedure TCgSparc.a_loadmm_reg_ref(list:TAasmOutput;reg:tregister;CONST ref:TReference);
-
-       begin
-//         list.concat(taicpu.op_reg_ref(A_NONEQ,S_NO,reg,ref));
-       end;
-procedure TCgSparc.a_parammm_reg(list:TAasmOutput;reg:tregister);
-  VAR
-    href:TReference;
-  BEGIN
-//    list.concat(taicpu.op_const_reg(A_SUB,S_SW,8,R_RSP));
-//    reference_reset_base(href,R_ESP,0);
-//    list.concat(taicpu.op_reg_ref(A_NONEQ,S_NO,reg,href));
-  END;
-procedure TCgSparc.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegister);
+  procedure TCgSparc.a_loadfpu_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
 
 
-      var
-        opcode:tasmop;
-        power:LongInt;
+         begin
+  {         if NOT (reg1 IN [R_F0..R_F31]) then
+             begin
+               list.concat(taicpu.op_reg(A_NONE,S_NO,
+                 trgcpu(rg).correct_fpuregister(reg1,trgcpu(rg).fpuvaroffset)));
+               inc(trgcpu(rg).fpuvaroffset);
+             end;
+           if NOT (reg2 IN [R_F0..R_F31]) then
+             begin
+               list.concat(taicpu.op_reg(A_JMPL,S_NO,
+                   trgcpu(rg).correct_fpuregister(reg2,trgcpu(rg).fpuvaroffset)));
+               dec(trgcpu(rg).fpuvaroffset);
+             end;}
+         end;
 
 
-      begin
-(*       Case Op of
-          OP_DIV, OP_IDIV:
-            Begin
-              if ispowerof2(a,power) then
-                begin
-                  case op of
-                    OP_DIV:
-                      opcode := A_SHR;
-                    OP_IDIV:
-                      opcode := A_SAR;
-                  end;
-                  list.concat(taicpu.op_const_reg(opcode,S_SW,power,
-                    reg));
-                  exit;
-                end;
-              { the rest should be handled specifically in the code      }
-              { generator because of the silly register usage restraints }
-              internalerror(200109224);
-            End;
-          OP_MUL,OP_IMUL:
-            begin
-              if not(cs_check_overflow in aktlocalswitches) and
-                 ispowerof2(a,power) then
-                begin
-                  list.concat(taicpu.op_const_reg(A_SHL,S_SW,power,
-                    reg));
-                  exit;
-                end;
-              if op = OP_IMUL then
-                list.concat(taicpu.op_const_reg(A_IMUL,S_SW,
-                  a,reg))
-              else
-                { OP_MUL should be handled specifically in the code        }
-                { generator because of the silly register usage restraints }
-                internalerror(200109225);
-            end;
-          OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
-            if not(cs_check_overflow in aktlocalswitches) and
-               (a = 1) and
-               (op in [OP_ADD,OP_SUB]) then
-              if op = OP_ADD then
-                list.concat(taicpu.op_reg(A_INC,S_SW,reg))
-              else
-                list.concat(taicpu.op_reg(A_DEC,S_SW,reg))
-            else if (a = 0) then
-              if (op <> OP_AND) then
-                exit
-              else
-                list.concat(taicpu.op_const_reg(A_NONE,S_SW,0,reg))
-            else if (a = high(aword)) and
-                    (op in [OP_AND,OP_OR,OP_XOR]) then
-                   begin
-                     case op of
-                       OP_AND:
-                         exit;
-                       OP_OR:
-                         list.concat(taicpu.op_const_reg(A_NONE,S_SW,high(aword),reg));
-                       OP_XOR:
-                         list.concat(taicpu.op_reg(A_NOT,S_SW,reg));
-                     end
-                   end
-            else
-              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],S_SW,
-                a,reg));
-          OP_SHL,OP_SHR,OP_SAR:
-            begin
-              if (a and 31) <> 0 Then
-                list.concat(taicpu.op_const_reg(
-                  TOpCG2AsmOp[op],S_SW,a and 31,reg));
-              if (a shr 5) <> 0 Then
-                internalerror(68991);
-            end
-          else internalerror(68992);
-        end;*)
-      end;
 
 
+      procedure TCgSparc.a_loadfpu_ref_reg(list:TAasmOutput;size:tcgsize;CONST ref:TReference;reg:tregister);
 
 
-     procedure TCgSparc.a_op_const_ref(list:TAasmOutput;Op:TOpCG;size:TCGSize;a:AWord;CONST ref:TReference);
+         begin
+           floatload(list,size,ref);
+  {         if (reg <> R_ST) then
+             a_loadfpu_reg_reg(list,R_ST,reg);}
+         end;
 
 
-      var
-        opcode:tasmop;
-        power:LongInt;
 
 
-      begin
-(*        Case Op of
-          OP_DIV, OP_IDIV:
-            Begin
-              if ispowerof2(a,power) then
-                begin
-                  case op of
-                    OP_DIV:
-                      opcode := A_SHR;
-                    OP_IDIV:
-                      opcode := A_SAR;
-                  end;
-                  list.concat(taicpu.op_const_ref(opcode,
-                    TCgSize2OpSize[size],power,ref));
-                  exit;
-                end;
-              { the rest should be handled specifically in the code      }
-              { generator because of the silly register usage restraints }
-              internalerror(200109231);
-            End;
-          OP_MUL,OP_IMUL:
-            begin
-              if not(cs_check_overflow in aktlocalswitches) and
-                 ispowerof2(a,power) then
-                begin
-                  list.concat(taicpu.op_const_ref(A_SHL,TCgSize2OpSize[size],
-                    power,ref));
-                  exit;
-                end;
-              { can't multiply a memory location directly with a CONSTant }
-              if op = OP_IMUL then
-                inherited a_op_const_ref(list,op,size,a,ref)
-              else
-                { OP_MUL should be handled specifically in the code        }
-                { generator because of the silly register usage restraints }
-                internalerror(200109232);
-            end;
-          OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
-            if not(cs_check_overflow in aktlocalswitches) and
-               (a = 1) and
-               (op in [OP_ADD,OP_SUB]) then
-              if op = OP_ADD then
-                list.concat(taicpu.op_ref(A_INC,TCgSize2OpSize[size],ref))
-              else
-                list.concat(taicpu.op_ref(A_DEC,TCgSize2OpSize[size],ref))
-            else if (a = 0) then
-              if (op <> OP_AND) then
-                exit
-              else
-                a_load_const_ref(list,size,0,ref)
-            else if (a = high(aword)) and
-                    (op in [OP_AND,OP_OR,OP_XOR]) then
-                   begin
-                     case op of
-                       OP_AND:
-                         exit;
-                       OP_OR:
-                         list.concat(taicpu.op_const_ref(A_NONE,TCgSize2OpSize[size],high(aword),ref));
-                       OP_XOR:
-                         list.concat(taicpu.op_ref(A_NOT,TCgSize2OpSize[size],ref));
-                     end
-                   end
-            else
-              list.concat(taicpu.op_const_ref(TOpCG2AsmOp[op],
-                TCgSize2OpSize[size],a,ref));
-          OP_SHL,OP_SHR,OP_SAR:
-            begin
-              if (a and 31) <> 0 Then
-                list.concat(taicpu.op_const_ref(
-                  TOpCG2AsmOp[op],TCgSize2OpSize[size],a and 31,ref));
-              if (a shr 5) <> 0 Then
-                internalerror(68991);
-            end
-          else internalerror(68992);
-        end;*)
-      end;
+      procedure TCgSparc.a_loadfpu_reg_ref(list:TAasmOutput;size:tcgsize;reg:tregister;const ref:TReference);
+         const
+           FpuStoreInstr: Array[OS_F32..OS_F64,boolean, boolean] of TAsmOp =
+                              { indexed? updating?}
+                      (((A_STF,A_STF),(A_STF,A_STF)),
+                       ((A_STDF,A_STDF),(A_STDF,A_STDF)));
+         var
+           op: tasmop;
+           ref2: treference;
+           freereg: boolean;
+         begin
+           if not(size in [OS_F32,OS_F64])
+           then
+             internalerror(200201122);
+  {         ref2:=ref;
+           freereg:=fixref(list,ref2);
+           op:=fpustoreinstr[size,ref2.index.enum <> R_NO,false];
+           a_load_store(list,op,reg,ref2);
+           if freereg
+           then
+             cg.free_scratch_reg(list,ref2.base);}
+         end;
+
 
 
+      procedure TCgSparc.a_loadmm_reg_reg(list:TAasmOutput;reg1, reg2:tregister);
+
+         begin
+  //         list.concat(taicpu.op_reg_reg(A_NONEQ,S_NO,reg1,reg2));
+         end;
+
+
+      procedure TCgSparc.a_loadmm_ref_reg(list:TAasmOutput;CONST ref:TReference;reg:tregister);
+
+         begin
+  //         list.concat(taicpu.op_ref_reg(A_NONEQ,S_NO,ref,reg));
+         end;
 
 
-     procedure TCgSparc.a_op_reg_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;src, dst:TRegister);
+
+      procedure TCgSparc.a_loadmm_reg_ref(list:TAasmOutput;reg:tregister;CONST ref:TReference);
+
+         begin
+  //         list.concat(taicpu.op_reg_ref(A_NONEQ,S_NO,reg,ref));
+         end;
+  procedure TCgSparc.a_parammm_reg(list:TAasmOutput;reg:tregister);
+    VAR
+      href:TReference;
+    BEGIN
+  //    list.concat(taicpu.op_const_reg(A_SUB,S_SW,8,R_RSP));
+  //    reference_reset_base(href,R_ESP,0);
+  //    list.concat(taicpu.op_reg_ref(A_NONEQ,S_NO,reg,href));
+    END;
+  procedure TCgSparc.a_op_const_reg(list:TAasmOutput;Op:TOpCG;a:AWord;reg:TRegister);
 
 
         var
         var
-          regloadsize:tcgsize;
-          dstsize:topsize;
-          tmpreg:tregister;
-          popecx:boolean;
+          opcode:tasmop;
+          power:LongInt;
 
 
         begin
         begin
-(*          dstsize := S_Q{makeregsize(dst,size)};
-          case op of
-            OP_NEG,OP_NOT:
-              begin
-                if src <> R_NO then
-                  internalerror(200112291);
-                list.concat(taicpu.op_reg(TOpCG2AsmOp[op],dstsize,dst));
-              end;
-            OP_MUL,OP_DIV,OP_IDIV:
-              { special stuff, needs separate handling inside code }
-              { generator                                          }
-              internalerror(200109233);
-            OP_SHR,OP_SHL,OP_SAR:
-              begin
-                tmpreg := R_NO;
-                { we need cl to hold the shift count, so if the destination }
-                { is ecx, save it to a temp for now                         }
-                if dst in [R_ECX,R_CX,R_CL] then
+  (*       Case Op of
+            OP_DIV, OP_IDIV:
+              Begin
+                if ispowerof2(a,power) then
                   begin
                   begin
-                    case S_SW of
-                      S_B:regloadsize := OS_8;
-                      S_W:regloadsize := OS_16;
-                      else regloadsize := OS_32;
+                    case op of
+                      OP_DIV:
+                        opcode := A_SHR;
+                      OP_IDIV:
+                        opcode := A_SAR;
                     end;
                     end;
-                    tmpreg := get_scratch_reg(list);
-                    a_load_reg_reg(list,regloadsize,OS_32,src,tmpreg);
+                    list.concat(taicpu.op_const_reg(opcode,S_SW,power,
+                      reg));
+                    exit;
                   end;
                   end;
-                if not(src in [R_ECX,R_CX,R_CL]) then
-                  begin
-                    { is ecx still free (it's also free if it was allocated }
-                    { to dst, since we've moved dst somewhere else already) }
-                    if not((dst = R_ECX) or
-                           ((R_ECX in rg.unusedregsint) and
-                            { this will always be true, it's just here to }
-                            { allocate ecx                                }
-                            (rg.getexplicitregisterint(list,R_ECX) = R_ECX))) then
-                      begin
-                        list.concat(taicpu.op_reg(A_NONE,S_SW,R_ECX));
-                        popecx := true;
-                      end;
-                    a_load_reg_reg(list,OS_8,OS_8,(src),R_CL);
-                  end
-                else
-                  src := R_CL;
-                { do the shift }
-                if tmpreg = R_NO then
-                  list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
-                    R_CL,dst))
-                else
+                { the rest should be handled specifically in the code      }
+                { generator because of the silly register usage restraints }
+                internalerror(200109224);
+              End;
+            OP_MUL,OP_IMUL:
+              begin
+                if not(cs_check_overflow in aktlocalswitches) and
+                   ispowerof2(a,power) then
                   begin
                   begin
-                    list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],S_SW,
-                      R_CL,tmpreg));
-                    { move result back to the destination }
-                    a_load_reg_reg(list,OS_32,OS_32,tmpreg,R_ECX);
-                    free_scratch_reg(list,tmpreg);
+                    list.concat(taicpu.op_const_reg(A_SHL,S_SW,power,
+                      reg));
+                    exit;
                   end;
                   end;
-                if popecx then
-                  list.concat(taicpu.op_reg(A_POP,S_SW,R_ECX))
-                else if not (dst in [R_ECX,R_CX,R_CL]) then
-                  rg.ungetregisterint(list,R_ECX);
+                if op = OP_IMUL then
+                  list.concat(taicpu.op_const_reg(A_IMUL,S_SW,
+                    a,reg))
+                else
+                  { OP_MUL should be handled specifically in the code        }
+                  { generator because of the silly register usage restraints }
+                  internalerror(200109225);
               end;
               end;
-            else
+            OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
+              if not(cs_check_overflow in aktlocalswitches) and
+                 (a = 1) and
+                 (op in [OP_ADD,OP_SUB]) then
+                if op = OP_ADD then
+                  list.concat(taicpu.op_reg(A_INC,S_SW,reg))
+                else
+                  list.concat(taicpu.op_reg(A_DEC,S_SW,reg))
+              else if (a = 0) then
+                if (op <> OP_AND) then
+                  exit
+                else
+                  list.concat(taicpu.op_const_reg(A_NONE,S_SW,0,reg))
+              else if (a = high(aword)) and
+                      (op in [OP_AND,OP_OR,OP_XOR]) then
+                     begin
+                       case op of
+                         OP_AND:
+                           exit;
+                         OP_OR:
+                           list.concat(taicpu.op_const_reg(A_NONE,S_SW,high(aword),reg));
+                         OP_XOR:
+                           list.concat(taicpu.op_reg(A_NOT,S_SW,reg));
+                       end
+                     end
+              else
+                list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],S_SW,
+                  a,reg));
+            OP_SHL,OP_SHR,OP_SAR:
               begin
               begin
-                if S_SW <> dstsize then
-                  internalerror(200109226);
-                list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
-                  src,dst));
-              end;
+                if (a and 31) <> 0 Then
+                  list.concat(taicpu.op_const_reg(
+                    TOpCG2AsmOp[op],S_SW,a and 31,reg));
+                if (a shr 5) <> 0 Then
+                  internalerror(68991);
+              end
+            else internalerror(68992);
           end;*)
           end;*)
         end;
         end;
 
 
 
 
-     procedure TCgSparc.a_op_ref_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;CONST ref:TReference;reg:TRegister);
+       procedure TCgSparc.a_op_const_ref(list:TAasmOutput;Op:TOpCG;size:TCGSize;a:AWord;CONST ref:TReference);
 
 
-       var
-         opsize:topsize;
+        var
+          opcode:tasmop;
+          power:LongInt;
 
 
-       begin
-(*          case op of
-            OP_NEG,OP_NOT,OP_IMUL:
+        begin
+  (*        Case Op of
+            OP_DIV, OP_IDIV:
+              Begin
+                if ispowerof2(a,power) then
+                  begin
+                    case op of
+                      OP_DIV:
+                        opcode := A_SHR;
+                      OP_IDIV:
+                        opcode := A_SAR;
+                    end;
+                    list.concat(taicpu.op_const_ref(opcode,
+                      TCgSize2OpSize[size],power,ref));
+                    exit;
+                  end;
+                { the rest should be handled specifically in the code      }
+                { generator because of the silly register usage restraints }
+                internalerror(200109231);
+              End;
+            OP_MUL,OP_IMUL:
               begin
               begin
-                inherited a_op_ref_reg(list,op,size,ref,reg);
+                if not(cs_check_overflow in aktlocalswitches) and
+                   ispowerof2(a,power) then
+                  begin
+                    list.concat(taicpu.op_const_ref(A_SHL,TCgSize2OpSize[size],
+                      power,ref));
+                    exit;
+                  end;
+                { can't multiply a memory location directly with a CONSTant }
+                if op = OP_IMUL then
+                  inherited a_op_const_ref(list,op,size,a,ref)
+                else
+                  { OP_MUL should be handled specifically in the code        }
+                  { generator because of the silly register usage restraints }
+                  internalerror(200109232);
               end;
               end;
-            OP_MUL,OP_DIV,OP_IDIV:
-              { special stuff, needs separate handling inside code }
-              { generator                                          }
-              internalerror(200109239);
-            else
+            OP_ADD, OP_AND, OP_OR, OP_SUB, OP_XOR:
+              if not(cs_check_overflow in aktlocalswitches) and
+                 (a = 1) and
+                 (op in [OP_ADD,OP_SUB]) then
+                if op = OP_ADD then
+                  list.concat(taicpu.op_ref(A_INC,TCgSize2OpSize[size],ref))
+                else
+                  list.concat(taicpu.op_ref(A_DEC,TCgSize2OpSize[size],ref))
+              else if (a = 0) then
+                if (op <> OP_AND) then
+                  exit
+                else
+                  a_load_const_ref(list,size,0,ref)
+              else if (a = high(aword)) and
+                      (op in [OP_AND,OP_OR,OP_XOR]) then
+                     begin
+                       case op of
+                         OP_AND:
+                           exit;
+                         OP_OR:
+                           list.concat(taicpu.op_const_ref(A_NONE,TCgSize2OpSize[size],high(aword),ref));
+                         OP_XOR:
+                           list.concat(taicpu.op_ref(A_NOT,TCgSize2OpSize[size],ref));
+                       end
+                     end
+              else
+                list.concat(taicpu.op_const_ref(TOpCG2AsmOp[op],
+                  TCgSize2OpSize[size],a,ref));
+            OP_SHL,OP_SHR,OP_SAR:
               begin
               begin
-                opsize := S_Q{makeregsize(reg,size)};
-                list.concat(taicpu.op_ref_reg(TOpCG2AsmOp[op],opsize,ref,reg));
-              end;
+                if (a and 31) <> 0 Then
+                  list.concat(taicpu.op_const_ref(
+                    TOpCG2AsmOp[op],TCgSize2OpSize[size],a and 31,ref));
+                if (a shr 5) <> 0 Then
+                  internalerror(68991);
+              end
+            else internalerror(68992);
           end;*)
           end;*)
-       end;
+        end;
 
 
 
 
-     procedure TCgSparc.a_op_reg_ref(list:TAasmOutput;Op:TOpCG;size:TCGSize;reg:TRegister;CONST ref:TReference);
+       procedure TCgSparc.a_op_reg_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;src, dst:TRegister);
 
 
-       var
-         opsize:topsize;
+          var
+            regloadsize:tcgsize;
+            dstsize:topsize;
+            tmpreg:tregister;
+            popecx:boolean;
 
 
-       begin
-(*         case op of
-           OP_NEG,OP_NOT:
-             begin
-               if reg <> R_NO then
-                 internalerror(200109237);
-               list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],ref));
-             end;
-           OP_IMUL:
-             begin
-               { this one needs a load/imul/store, which is the default }
-               inherited a_op_ref_reg(list,op,size,ref,reg);
-             end;
-           OP_MUL,OP_DIV,OP_IDIV:
-             { special stuff, needs separate handling inside code }
-             { generator                                          }
-             internalerror(200109238);
-           else
-             begin
-               opsize := tcgsize2opsize[size];
-               list.concat(taicpu.op_reg_ref(TOpCG2AsmOp[op],opsize,reg,ref));
-             end;
-         end;*)
-       end;
-
-
-    procedure TCgSparc.a_op_const_reg_reg(list:TAasmOutput;op:TOpCg;
-        size:tcgsize;a:aword;src, dst:tregister);
-      var
-        tmpref:TReference;
-        power:LongInt;
-        opsize:topsize;
-      begin
-        opsize := S_SW;
-        if (opsize <> S_SW) or
-           not (size in [OS_32,OS_S32]) then
           begin
           begin
-            inherited a_op_const_reg_reg(list,op,size,a,src,dst);
-            exit;
+  (*          dstsize := S_Q{makeregsize(dst,size)};
+            case op of
+              OP_NEG,OP_NOT:
+                begin
+                  if src <> R_NO then
+                    internalerror(200112291);
+                  list.concat(taicpu.op_reg(TOpCG2AsmOp[op],dstsize,dst));
+                end;
+              OP_MUL,OP_DIV,OP_IDIV:
+                { special stuff, needs separate handling inside code }
+                { generator                                          }
+                internalerror(200109233);
+              OP_SHR,OP_SHL,OP_SAR:
+                begin
+                  tmpreg := R_NO;
+                  { we need cl to hold the shift count, so if the destination }
+                  { is ecx, save it to a temp for now                         }
+                  if dst in [R_ECX,R_CX,R_CL] then
+                    begin
+                      case S_SW of
+                        S_B:regloadsize := OS_8;
+                        S_W:regloadsize := OS_16;
+                        else regloadsize := OS_32;
+                      end;
+                      tmpreg := get_scratch_reg(list);
+                      a_load_reg_reg(list,regloadsize,OS_32,src,tmpreg);
+                    end;
+                  if not(src in [R_ECX,R_CX,R_CL]) then
+                    begin
+                      { is ecx still free (it's also free if it was allocated }
+                      { to dst, since we've moved dst somewhere else already) }
+                      if not((dst = R_ECX) or
+                             ((R_ECX in rg.unusedregsint) and
+                              { this will always be true, it's just here to }
+                              { allocate ecx                                }
+                              (rg.getexplicitregisterint(list,R_ECX) = R_ECX))) then
+                        begin
+                          list.concat(taicpu.op_reg(A_NONE,S_SW,R_ECX));
+                          popecx := true;
+                        end;
+                      a_load_reg_reg(list,OS_8,OS_8,(src),R_CL);
+                    end
+                  else
+                    src := R_CL;
+                  { do the shift }
+                  if tmpreg = R_NO then
+                    list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
+                      R_CL,dst))
+                  else
+                    begin
+                      list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],S_SW,
+                        R_CL,tmpreg));
+                      { move result back to the destination }
+                      a_load_reg_reg(list,OS_32,OS_32,tmpreg,R_ECX);
+                      free_scratch_reg(list,tmpreg);
+                    end;
+                  if popecx then
+                    list.concat(taicpu.op_reg(A_POP,S_SW,R_ECX))
+                  else if not (dst in [R_ECX,R_CX,R_CL]) then
+                    rg.ungetregisterint(list,R_ECX);
+                end;
+              else
+                begin
+                  if S_SW <> dstsize then
+                    internalerror(200109226);
+                  list.concat(taicpu.op_reg_reg(TOpCG2AsmOp[op],dstsize,
+                    src,dst));
+                end;
+            end;*)
           end;
           end;
-        { if we get here, we have to do a 32 bit calculation, guaranteed }
-        Case Op of
-          OP_DIV, OP_IDIV, OP_MUL, OP_AND, OP_OR, OP_XOR, OP_SHL, OP_SHR,
-          OP_SAR:
-            { can't do anything special for these }
-            inherited a_op_const_reg_reg(list,op,size,a,src,dst);
-          OP_IMUL:
-            begin
-              if not(cs_check_overflow in aktlocalswitches) and
-                 ispowerof2(a,power) then
-                { can be done with a shift }
-                inherited a_op_const_reg_reg(list,op,size,a,src,dst);
-              list.concat(taicpu.op_reg_const_reg(A_SMUL,src,a,dst));
-            end;
-          OP_ADD, OP_SUB:
-            if (a = 0) then
-              a_load_reg_reg(list,size,size,src,dst)
-            else
-              begin
-                reference_reset(tmpref);
-                tmpref.base := src;
-                tmpref.offset := LongInt(a);
-                if op = OP_SUB then
-                  tmpref.offset := -tmpref.offset;
-                list.concat(taicpu.op_ref_reg(A_NONE,tmpref,dst));
-              end
-          else internalerror(200112302);
-        end;
-      end;
 
 
-    procedure TCgSparc.a_op_reg_reg_reg(list:TAasmOutput;op:TOpCg;
-        size:tcgsize;src1, src2, dst:tregister);
-      var
-        tmpref:TReference;
-        opsize:topsize;
-      begin
-        opsize := S_SW;
-        if (opsize <> S_SW) or
-           (S_SW <> S_SW) or
-           not (size in [OS_32,OS_S32]) then
-          begin
-            inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
-            exit;
-          end;
-        { if we get here, we have to do a 32 bit calculation, guaranteed }
-        Case Op of
-          OP_DIV, OP_IDIV, OP_MUL, OP_AND, OP_OR, OP_XOR, OP_SHL, OP_SHR,
-          OP_SAR,OP_SUB,OP_NOT,OP_NEG:
-            { can't do anything special for these }
-            inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
-          OP_IMUL:
-            list.concat(taicpu.op_reg_reg_reg(A_SMUL,src1,src2,dst));
-          OP_ADD:
-            begin
-              reference_reset(tmpref);
-              tmpref.base := src1;
-              tmpref.index := src2;
-              tmpref.scalefactor := 1;
-              list.concat(taicpu.op_ref_reg(A_NONE,tmpref,dst));
-            end
-          else internalerror(200112303);
-        end;
-      end;
 
 
-{*************** compare instructructions ****************}
-procedure TCgSparc.a_cmp_const_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;a:aword;reg:tregister;l:tasmlabel);
-  begin
-    if(a=0)
-    then
-      list.concat(taicpu.op_reg_reg(A_CMP,reg,reg))
-    else
-      list.concat(taicpu.op_reg_const(A_CMP,reg,a));
-    a_jmp_cond(list,cmp_op,l);
-  end;
-procedure TCgSparc.a_cmp_const_ref_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;a:aword;const ref:TReference;l:tasmlabel);
-  var
-    cReg,rReg:TRegister;
-  begin
-    with cg do
-      begin
-        cReg:=get_scratch_reg_int(List,size);
-        rReg:=get_scratch_reg_int(List,size);
-        a_load_const_reg(List,OS_32,a,cReg);
-        a_load_ref_reg(List,OS_32,ref,rReg);
-        List.Concat(taicpu.op_reg_reg(A_CMP,rReg,cReg));
-        a_jmp_cond(list,cmp_op,l);
-        free_scratch_reg(List,cReg);
-        free_scratch_reg(List,rReg);
-      end;
-  end;
+       procedure TCgSparc.a_op_ref_reg(list:TAasmOutput;Op:TOpCG;size:TCGSize;CONST ref:TReference;reg:TRegister);
 
 
-      procedure TCgSparc.a_cmp_reg_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;
-        reg1,reg2:tregister;l:tasmlabel);
+         var
+           opsize:topsize;
 
 
-        begin
- {         if regsize(reg1) <> S_SW then
-            internalerror(200109226);
-          list.concat(taicpu.op_reg_reg(A_CMP,regsize(reg1),reg1,reg2));
-          a_jmp_cond(list,cmp_op,l);}
-        end;
-procedure TCgSparc.a_cmp_ref_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;CONST ref:TReference;reg:tregister;l:tasmlabel);
-  var
-    TempReg:TRegister;
-   begin
-     TempReg:=cg.get_scratch_reg_int(List,size);
-     a_load_ref_reg(list,OS_32,Ref,TempReg);
-     list.concat(taicpu.op_reg_reg_reg(A_SUBcc,TempReg,Reg,CpuReg[R_G0]));
-     a_jmp_cond(list,cmp_op,l);
-     cg.free_scratch_reg(exprasmlist,TempReg);
-   end;
-procedure TCgSparc.a_jmp_cond(list:TAasmOutput;cond:TOpCmp;l:TAsmLabel);
-  var
-    ai:TAiCpu;
-  begin
-    ai:=TAiCpu.Op_sym(A_BA,S_NO,l);
-    ai.SetCondition(TOpCmp2AsmCond[cond]);
-    with List do
-      begin
-        Concat(ai);
-        Concat(TAiCpu.Op_none(A_NOP));
-      end;
-  end;
-procedure TCgSparc.a_jmp_flags(list:TAasmOutput;CONST f:TResFlags;l:tasmlabel);
-  var
-    ai:taicpu;
-  begin
-    ai := Taicpu.op_sym(A_BA,S_NO,l);
-    ai.SetCondition(flags_to_cond(f));
-    with List do
-      begin
-        Concat(ai);
-        Concat(TAiCpu.Op_none(A_NOP));
-      end;
-  end;
-procedure TCgSparc.g_flags2reg(list:TAasmOutput;Size:TCgSize;CONST f:tresflags;reg:TRegister);
-  VAR
-    ai:taicpu;
-    r,hreg:tregister;
-
-  BEGIN
-    r.enum:=R_PSR;
-    hreg := rg.makeregsize(reg,OS_8);
-    ai:=Taicpu.Op_reg_reg(A_RDPSR,r,hreg);
-    ai.SetCondition(flags_to_cond(f));
-    with List do
-      begin
-        Concat(ai);
-        Concat(TAiCpu.Op_none(A_NOP));
-      end;
-    IF hreg.enum<>reg.enum
-    THEN
-      a_load_reg_reg(list,OS_32,OS_32,hreg,reg);
-  END;
-procedure TCgSparc.g_overflowCheck(List:TAasmOutput;const p:TNode);
-  var
-    hl:TAsmLabel;
-    r:Tregister;
-  begin
-    r.enum:=R_NONE;
-    if not(cs_check_overflow in aktlocalswitches)
-    then
-      exit;
-    objectlibrary.getlabel(hl);
-    if not((p.resulttype.def.deftype=pointerdef) or
-       ((p.resulttype.def.deftype=orddef) and
-        (torddef(p.resulttype.def).typ in [u64bit,u16bit,u32bit,u8bit,uchar,
-                                         bool8bit,bool16bit,bool32bit])))
-    then
-      begin
-        list.concat(taicpu.op_reg(A_NONE,r));
-        a_jmp_always(list,hl)
-      end
-    else
-      a_jmp_cond(list,OC_NONE,hl);
-      a_call_name(list,'FPC_OVERFLOW');
-      a_label(list,hl);
+         begin
+  (*          case op of
+              OP_NEG,OP_NOT,OP_IMUL:
+                begin
+                  inherited a_op_ref_reg(list,op,size,ref,reg);
+                end;
+              OP_MUL,OP_DIV,OP_IDIV:
+                { special stuff, needs separate handling inside code }
+                { generator                                          }
+                internalerror(200109239);
+              else
+                begin
+                  opsize := S_Q{makeregsize(reg,size)};
+                  list.concat(taicpu.op_ref_reg(TOpCG2AsmOp[op],opsize,ref,reg));
+                end;
+            end;*)
+         end;
+
+
+       procedure TCgSparc.a_op_reg_ref(list:TAasmOutput;Op:TOpCG;size:TCGSize;reg:TRegister;CONST ref:TReference);
+
+         var
+           opsize:topsize;
+
+         begin
+  (*         case op of
+             OP_NEG,OP_NOT:
+               begin
+                 if reg <> R_NO then
+                   internalerror(200109237);
+                 list.concat(taicpu.op_ref(TOpCG2AsmOp[op],tcgsize2opsize[size],ref));
+               end;
+             OP_IMUL:
+               begin
+                 { this one needs a load/imul/store, which is the default }
+                 inherited a_op_ref_reg(list,op,size,ref,reg);
+               end;
+             OP_MUL,OP_DIV,OP_IDIV:
+               { special stuff, needs separate handling inside code }
+               { generator                                          }
+               internalerror(200109238);
+             else
+               begin
+                 opsize := tcgsize2opsize[size];
+                 list.concat(taicpu.op_reg_ref(TOpCG2AsmOp[op],opsize,reg,ref));
+               end;
+           end;*)
+         end;
+
+
+      procedure TCgSparc.a_op_const_reg_reg(list:TAasmOutput;op:TOpCg;
+          size:tcgsize;a:aword;src, dst:tregister);
+        var
+          tmpref:TReference;
+          power:LongInt;
+          opsize:topsize;
+        begin
+          opsize := S_SW;
+          if (opsize <> S_SW) or
+             not (size in [OS_32,OS_S32]) then
+            begin
+              inherited a_op_const_reg_reg(list,op,size,a,src,dst);
+              exit;
+            end;
+          { if we get here, we have to do a 32 bit calculation, guaranteed }
+          Case Op of
+            OP_DIV, OP_IDIV, OP_MUL, OP_AND, OP_OR, OP_XOR, OP_SHL, OP_SHR,
+            OP_SAR:
+              { can't do anything special for these }
+              inherited a_op_const_reg_reg(list,op,size,a,src,dst);
+            OP_IMUL:
+              begin
+                if not(cs_check_overflow in aktlocalswitches) and
+                   ispowerof2(a,power) then
+                  { can be done with a shift }
+                  inherited a_op_const_reg_reg(list,op,size,a,src,dst);
+                list.concat(taicpu.op_reg_const_reg(A_SMUL,src,a,dst));
+              end;
+            OP_ADD, OP_SUB:
+              if (a = 0) then
+                a_load_reg_reg(list,size,size,src,dst)
+              else
+                begin
+                  reference_reset(tmpref);
+                  tmpref.base := src;
+                  tmpref.offset := LongInt(a);
+                  if op = OP_SUB then
+                    tmpref.offset := -tmpref.offset;
+                  list.concat(taicpu.op_ref_reg(A_NONE,tmpref,dst));
+                end
+            else internalerror(200112302);
+          end;
+        end;
+
+      procedure TCgSparc.a_op_reg_reg_reg(list:TAasmOutput;op:TOpCg;
+          size:tcgsize;src1, src2, dst:tregister);
+        var
+          tmpref:TReference;
+          opsize:topsize;
+        begin
+          opsize := S_SW;
+          if (opsize <> S_SW) or
+             (S_SW <> S_SW) or
+             not (size in [OS_32,OS_S32]) then
+            begin
+              inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+              exit;
+            end;
+          { if we get here, we have to do a 32 bit calculation, guaranteed }
+          Case Op of
+            OP_DIV, OP_IDIV, OP_MUL, OP_AND, OP_OR, OP_XOR, OP_SHL, OP_SHR,
+            OP_SAR,OP_SUB,OP_NOT,OP_NEG:
+              { can't do anything special for these }
+              inherited a_op_reg_reg_reg(list,op,size,src1,src2,dst);
+            OP_IMUL:
+              list.concat(taicpu.op_reg_reg_reg(A_SMUL,src1,src2,dst));
+            OP_ADD:
+              begin
+                reference_reset(tmpref);
+                tmpref.base := src1;
+                tmpref.index := src2;
+                list.concat(taicpu.op_ref_reg(A_NONE,tmpref,dst));
+              end
+            else internalerror(200112303);
+          end;
+        end;
+
+  {*************** compare instructructions ****************}
+  procedure TCgSparc.a_cmp_const_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;a:aword;reg:tregister;l:tasmlabel);
+    begin
+      if(a=0)
+      then
+        list.concat(taicpu.op_reg_reg(A_CMP,reg,reg))
+      else
+        list.concat(taicpu.op_reg_const(A_CMP,reg,a));
+      a_jmp_cond(list,cmp_op,l);
+    end;
+  procedure TCgSparc.a_cmp_const_ref_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;a:aword;const ref:TReference;l:tasmlabel);
+    var
+      cReg,rReg:TRegister;
+    begin
+      with cg do
+        begin
+          cReg:=get_scratch_reg_int(List,size);
+          rReg:=get_scratch_reg_int(List,size);
+          a_load_const_reg(List,OS_32,a,cReg);
+          a_load_ref_reg(List,OS_32,ref,rReg);
+          List.Concat(taicpu.op_reg_reg(A_CMP,rReg,cReg));
+          a_jmp_cond(list,cmp_op,l);
+          free_scratch_reg(List,cReg);
+          free_scratch_reg(List,rReg);
+        end;
     end;
     end;
 
 
-{ *********** entry/exit code and address loading ************ }
+        procedure TCgSparc.a_cmp_reg_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;
+          reg1,reg2:tregister;l:tasmlabel);
 
 
-procedure TCgSparc.g_stackframe_entry(list:TAasmOutput;LocalSize:LongInt);
-  var
-    r : tregister;
-  begin
-    { Althogh the SPARC architecture require only word alignment, software
-      convention and the operating system require every stack frame to be double word
-      aligned }
-    LocalSize:=align(LocalSize,8);
-    { Execute the SAVE instruction to get a new register window and create a new
-      stack frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state
-      before execution of the SAVE instrucion so it is the caller %i6, when the %i6
-      after execution of that instruction is the called function stack pointer}
-    r.enum:=R_INTREGISTER;
-    r.number:=NR_STACK_POINTER_REG;
-    list.concat(Taicpu.Op_reg_const_reg(A_SAVE,r,-LocalSize,r));
-  end;
+          begin
+   {         if regsize(reg1) <> S_SW then
+              internalerror(200109226);
+            list.concat(taicpu.op_reg_reg(A_CMP,regsize(reg1),reg1,reg2));
+            a_jmp_cond(list,cmp_op,l);}
+          end;
+  procedure TCgSparc.a_cmp_ref_reg_label(list:TAasmOutput;size:tcgsize;cmp_op:topcmp;CONST ref:TReference;reg:tregister;l:tasmlabel);
+    var
+      TempReg:TRegister;
+     begin
+       TempReg:=cg.get_scratch_reg_int(List,size);
+       a_load_ref_reg(list,OS_32,Ref,TempReg);
+       list.concat(taicpu.op_reg_reg_reg(A_SUBcc,TempReg,Reg,CpuReg[R_G0]));
+       a_jmp_cond(list,cmp_op,l);
+       cg.free_scratch_reg(exprasmlist,TempReg);
+     end;
+
+
+  procedure TCgSparc.a_jmp_cond(list:TAasmOutput;cond:TOpCmp;l:TAsmLabel);
+    var
+      ai:TAiCpu;
+    begin
+      ai:=TAiCpu.Op_sym(A_BA,S_NO,l);
+      ai.SetCondition(TOpCmp2AsmCond[cond]);
+      with List do
+        begin
+          Concat(ai);
+          Concat(TAiCpu.Op_none(A_NOP));
+        end;
+    end;
 
 
 
 
-procedure TCgSparc.g_restore_all_registers(list:TaasmOutput;accused,acchiused:boolean);
-  begin
-    { The sparc port uses the sparc standard calling convetions so this function has no used }
-  end;
+  procedure TCgSparc.a_jmp_flags(list:TAasmOutput;CONST f:TResFlags;l:tasmlabel);
+    var
+      ai:taicpu;
+    begin
+      ai := Taicpu.op_sym(A_BA,S_NO,l);
+      ai.SetCondition(flags_to_cond(f));
+      with List do
+        begin
+          Concat(ai);
+          Concat(TAiCpu.Op_none(A_NOP));
+        end;
+    end;
 
 
 
 
-procedure TCgSparc.g_restore_frame_pointer(list:TAasmOutput);
-  begin
-     { This function intontionally does nothing as frame pointer is restored in the
-       delay slot of the return instrucion done in g_return_from_proc}
-  end;
+  procedure TCgSparc.g_flags2reg(list:TAasmOutput;Size:TCgSize;CONST f:tresflags;reg:TRegister);
+    var
+      ai:taicpu;
+      r,hreg:tregister;
+    begin
+      r.enum:=R_PSR;
+      hreg := rg.makeregsize(reg,OS_8);
+      ai:=Taicpu.Op_reg_reg(A_RDPSR,r,hreg);
+      ai.SetCondition(flags_to_cond(f));
+      with List do
+        begin
+          Concat(ai);
+          Concat(TAiCpu.Op_none(A_NOP));
+        end;
+      if hreg.enum<>reg.enum then
+        a_load_reg_reg(list,OS_32,OS_32,hreg,reg);
+    end;
 
 
 
 
-procedure TCgSparc.g_restore_standard_registers(list:taasmoutput;usedinproc:Tsupregset);
-  begin
-    { The sparc port uses the sparc standard calling convetions so this function has no used }
-  end;
+  procedure TCgSparc.g_overflowCheck(List:TAasmOutput;const p:TNode);
+    var
+      hl:TAsmLabel;
+      r:Tregister;
+    begin
+      r.enum:=R_NONE;
+      if not(cs_check_overflow in aktlocalswitches) then
+        exit;
+      objectlibrary.getlabel(hl);
+      if not((p.resulttype.def.deftype=pointerdef) or
+         ((p.resulttype.def.deftype=orddef) and
+          (torddef(p.resulttype.def).typ in [u64bit,u16bit,u32bit,u8bit,uchar,
+                                           bool8bit,bool16bit,bool32bit])))
+      then
+        begin
+          list.concat(taicpu.op_reg(A_NONE,r));
+          a_jmp_always(list,hl)
+        end
+      else
+        a_jmp_cond(list,OC_NONE,hl);
+        a_call_name(list,'FPC_OVERFLOW');
+        a_label(list,hl);
+      end;
 
 
+  { *********** entry/exit code and address loading ************ }
+
+  procedure TCgSparc.g_stackframe_entry(list:TAasmOutput;LocalSize:LongInt);
+    var
+      r : tregister;
+    begin
+      { Althogh the SPARC architecture require only word alignment, software
+        convention and the operating system require every stack frame to be double word
+        aligned }
+      LocalSize:=align(LocalSize,8);
+      { Execute the SAVE instruction to get a new register window and create a new
+        stack frame. In the "SAVE %i6,size,%i6" the first %i6 is related to the state
+        before execution of the SAVE instrucion so it is the caller %i6, when the %i6
+        after execution of that instruction is the called function stack pointer}
+      r.enum:=R_INTREGISTER;
+      r.number:=NR_STACK_POINTER_REG;
+      list.concat(Taicpu.Op_reg_const_reg(A_SAVE,r,-LocalSize,r));
+    end;
 
 
-procedure TCgSparc.g_return_from_proc(list:TAasmOutput;parasize:aword);
-  var
-    r,r2:Tregister;
-  begin
-    { According to the SPARC ABI, the stack is cleared using the RESTORE instruction
-      which is genereted in the g_restore_frame_pointer. Notice that SPARC has no
-      RETURN instruction and that JMPL is used instead. The JMPL instrucion have one
-      delay slot, so an inversion is possible such as
-      JMPL  %i7+8,%g0
-      RESTORE  %g0,0,%g0
-      If no inversion we can use just
-      RESTORE  %g0,0,%g0
-      JMPL  %i7+8,%g0
-      NOP
-    }
-    with list do
-      begin
-        { Return address is computed by adding 8 to the CALL address saved onto %i6}
-        r.enum:=R_G0;
-        r2.enum:=R_I7;
-        concat(Taicpu.Op_caddr_reg(A_JMPL,r,8,r));
-        { We use trivial restore in the delay slot of the JMPL instruction, as we
-          already set result onto %i0 }
-        concat(Taicpu.Op_reg_const_reg(A_RESTORE,r,0,r));
-     end
-  end;
 
 
+  procedure TCgSparc.g_restore_all_registers(list:TaasmOutput;accused,acchiused:boolean);
+    begin
+      { The sparc port uses the sparc standard calling convetions so this function has no used }
+    end;
 
 
-procedure TCgSparc.g_save_all_registers(list : taasmoutput);
-  begin
-    { The sparc port uses the sparc standard calling convetions so this function has no used }
-  end;
 
 
+  procedure TCgSparc.g_restore_frame_pointer(list:TAasmOutput);
+    begin
+       { This function intontionally does nothing as frame pointer is restored in the
+         delay slot of the return instrucion done in g_return_from_proc}
+    end;
 
 
-procedure TCgSparc.g_save_standard_registers(list : taasmoutput; usedinproc:Tsupregset);
-  begin
-    { The sparc port uses the sparc standard calling convetions so this function has no used }
-  end;
 
 
+  procedure TCgSparc.g_restore_standard_registers(list:taasmoutput;usedinproc:Tsupregset);
+    begin
+      { The sparc port uses the sparc standard calling convetions so this function has no used }
+    end;
 
 
-procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tregister);
 
 
-       begin
-//         list.concat(taicpu.op_ref_reg(A_LEA,S_SW,ref,r));
-       end;
-{ ************* 64bit operations ************ }
-    procedure TCg64Sparc.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
-      begin
-        case op of
-          OP_ADD :
-            begin
-              op1:=A_ADD;
-              op2:=A_ADD;
-            end;
-          OP_SUB :
-            begin
-              op1:=A_SUB;
-              op2:=A_SUB;
-            end;
-          OP_XOR :
-            begin
-              op1:=A_XOR;
-              op2:=A_XOR;
-            end;
-          OP_OR :
-            begin
-              op1:=A_OR;
-              op2:=A_OR;
-            end;
-          OP_AND :
-            begin
-              op1:=A_AND;
-              op2:=A_AND;
-            end;
-          else
-            internalerror(200203241);
-        end;
-      end;
+  procedure TCgSparc.g_return_from_proc(list:TAasmOutput;parasize:aword);
+    var
+      r : tregister;
+      href : treference;
+    begin
+      { According to the SPARC ABI, the stack is cleared using the RESTORE instruction
+        which is genereted in the g_restore_frame_pointer. Notice that SPARC has no
+        RETURN instruction and that JMPL is used instead. The JMPL instrucion have one
+        delay slot, so an inversion is possible such as
+        JMPL  %i7+8,%g0
+        RESTORE  %g0,0,%g0
+        If no inversion we can use just
+        RESTORE  %g0,0,%g0
+        JMPL  %i7+8,%g0
+        NOP
+      }
+      { Return address is computed by adding 8 to the CALL address saved onto %i6}
+      r.enum:=R_INTREGISTER;
+      r.number:=NR_I7;
+      reference_reset_base(href,r,8);
+
+      r.enum:=R_INTREGISTER;
+      r.number:=NR_G0;
+      list.concat(Taicpu.op_ref_reg(A_JMPL,href,r));
+      { We use trivial restore in the delay slot of the JMPL instruction, as we
+        already set result onto %i0 }
+      list.concat(Taicpu.Op_reg_const_reg(A_RESTORE,r,0,r));
+    end;
 
 
 
 
-    procedure TCg64Sparc.a_op64_ref_reg(list:TAasmOutput;op:TOpCG;CONST ref:TReference;reg:TRegister64);
-      var
-        op1,op2:TAsmOp;
-        tempref:TReference;
-      begin
-        get_64bit_ops(op,op1,op2);
-        list.concat(taicpu.op_ref_reg(op1,ref,reg.reglo));
-        tempref:=ref;
-        inc(tempref.offset,4);
-        list.concat(taicpu.op_ref_reg(op2,tempref,reg.reghi));
-      end;
+  procedure TCgSparc.g_save_all_registers(list : taasmoutput);
+    begin
+      { The sparc port uses the sparc standard calling convetions so this function has no used }
+    end;
 
 
 
 
-    procedure TCg64Sparc.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);
-      var
-        op1,op2:TAsmOp;
-      begin
-        get_64bit_ops(op,op1,op2);
-        list.concat(taicpu.op_reg_reg(op1,regsrc.reglo,regdst.reglo));
-        list.concat(taicpu.op_reg_reg(op2,regsrc.reghi,regdst.reghi));
-      end;
+  procedure TCgSparc.g_save_standard_registers(list : taasmoutput; usedinproc:Tsupregset);
+    begin
+      { The sparc port uses the sparc standard calling convetions so this function has no used }
+    end;
+
+
+  procedure TCgSparc.a_loadaddr_ref_reg(list : TAasmOutput;const ref : TReference;r : tregister);
+    var
+       href : treference;
+       hreg : tregister;
+    begin
+      if (r.number=ref.index.number) or (r.number=ref.base.number) then
+        begin
+        {$ifdef newra}
+          hreg:=rg.getaddressregister(list);
+        {$else}
+          hreg := get_scratch_reg_address(list);
+        {$endif}
+        end
+      else
+        hreg:=r;
+      if assigned(ref.symbol) then
+        begin
+          reference_reset_symbol(href,ref.symbol,ref.offset);
+          href.symaddr:=refs_hi;
+          list.concat(taicpu.op_ref_reg(A_SETHI,href,hreg));
+          href.symaddr:=refs_hi;
+          list.concat(taicpu.op_reg_ref_reg(A_OR,hreg,href,hreg));
+          // if (ref.index<>R_NO)
+        end;
 
 
+      if hreg.number<>r.number then
+        begin
+           a_load_reg_reg(list,OS_ADDR,OS_ADDR,hreg,r);
+         {$ifdef newra}
+           rg.ungetregisterint(list,hreg);
+         {$else}
+           free_scratch_reg(list,hreg);
+         {$endif}
+        end;
+    end;
 
 
-    procedure TCg64Sparc.a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:qWord;regdst:TRegister64);
-      var
-        op1,op2:TAsmOp;
-      begin
-        case op of
-          OP_AND,OP_OR,OP_XOR:
-            WITH cg DO
+  { ************* 64bit operations ************ }
+      procedure TCg64Sparc.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
+        begin
+          case op of
+            OP_ADD :
               begin
               begin
-                a_op_const_reg(list,op,Lo(Value),regdst.reglo);
-                a_op_const_reg(list,op,Hi(Value),regdst.reghi);
+                op1:=A_ADD;
+                op2:=A_ADD;
               end;
               end;
-          OP_ADD, OP_SUB:
-            begin
-              {can't use a_op_const_ref because this may use dec/inc}
-              get_64bit_ops(op,op1,op2);
-              list.concat(taicpu.op_const_reg(op1,Lo(Value),regdst.reglo));
-              list.concat(taicpu.op_const_reg(op2,Hi(Value),regdst.reghi));
-            end;
-          else
-            internalerror(200204021);
+            OP_SUB :
+              begin
+                op1:=A_SUB;
+                op2:=A_SUB;
+              end;
+            OP_XOR :
+              begin
+                op1:=A_XOR;
+                op2:=A_XOR;
+              end;
+            OP_OR :
+              begin
+                op1:=A_OR;
+                op2:=A_OR;
+              end;
+            OP_AND :
+              begin
+                op1:=A_AND;
+                op2:=A_AND;
+              end;
+            else
+              internalerror(200203241);
+          end;
         end;
         end;
-      end;
 
 
 
 
-procedure TCg64Sparc.a_op64_const_ref(list:TAasmOutput;op:TOpCG;value:qWord;const ref:TReference);
-  var
-    op1,op2:TAsmOp;
-    tempref:TReference;
-  begin
-    case op of
-      OP_AND,OP_OR,OP_XOR:
-      with cg do
+      procedure TCg64Sparc.a_op64_ref_reg(list:TAasmOutput;op:TOpCG;CONST ref:TReference;reg:TRegister64);
+        var
+          op1,op2:TAsmOp;
+          tempref:TReference;
         begin
         begin
-          a_op_const_ref(list,op,OS_32,Lo(Value),ref);
+          get_64bit_ops(op,op1,op2);
+          list.concat(taicpu.op_ref_reg(op1,ref,reg.reglo));
           tempref:=ref;
           tempref:=ref;
           inc(tempref.offset,4);
           inc(tempref.offset,4);
-          a_op_const_ref(list,op,OS_32,Hi(Value),tempref);
+          list.concat(taicpu.op_ref_reg(op2,tempref,reg.reghi));
         end;
         end;
-      OP_ADD, OP_SUB:
-            begin
-              get_64bit_ops(op,op1,op2);
-              { can't use a_op_const_ref because this may use dec/inc}
-{              list.concat(taicpu.op_const_ref(op1,Lo(Value),ref));
-              tempref:=ref;
-              inc(tempref.offset,4);
-              list.concat(taicpu.op_const_ref(op2,S_SW,Hi(Value),tempref));}
-              InternalError(2002102101);
-            end;
-          else
-            internalerror(200204022);
+
+
+      procedure TCg64Sparc.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);
+        var
+          op1,op2:TAsmOp;
+        begin
+          get_64bit_ops(op,op1,op2);
+          list.concat(taicpu.op_reg_reg(op1,regsrc.reglo,regdst.reglo));
+          list.concat(taicpu.op_reg_reg(op2,regsrc.reghi,regdst.reghi));
         end;
         end;
-      end;
 
 
 
 
-{ ************* concatcopy ************ }
-procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aword;delsource,loadref:boolean);
-  var
-    countreg: TRegister;
-    src, dst: TReference;
-    lab: tasmlabel;
-    count, count2: aword;
-    orgsrc, orgdst: boolean;
-    r:Tregister;
-  begin
-{$ifdef extdebug}
-    if len > high(longint)
-    then
-      internalerror(2002072704);
-{$endif extdebug}
-   { make sure short loads are handled as optimally as possible }
-    if not loadref
-    then
-      if(len <= 8)and(byte(len) in [1,2,4,8])
-      then
+      procedure TCg64Sparc.a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:qWord;regdst:TRegister64);
+        var
+          op1,op2:TAsmOp;
         begin
         begin
-          if len < 8
-          then
-            begin
-              a_load_ref_ref(list,int_cgsize(len),source,dest);
+          case op of
+            OP_AND,OP_OR,OP_XOR:
+              WITH cg DO
+                begin
+                  a_op_const_reg(list,op,Lo(Value),regdst.reglo);
+                  a_op_const_reg(list,op,Hi(Value),regdst.reghi);
+                end;
+            OP_ADD, OP_SUB:
+              begin
+                {can't use a_op_const_ref because this may use dec/inc}
+                get_64bit_ops(op,op1,op2);
+                list.concat(taicpu.op_const_reg(op1,Lo(Value),regdst.reglo));
+                list.concat(taicpu.op_const_reg(op2,Hi(Value),regdst.reghi));
+              end;
+            else
+              internalerror(200204021);
+          end;
+        end;
+
+
+  procedure TCg64Sparc.a_op64_const_ref(list:TAasmOutput;op:TOpCG;value:qWord;const ref:TReference);
+    var
+      op1,op2:TAsmOp;
+      tempref:TReference;
+    begin
+      case op of
+        OP_AND,OP_OR,OP_XOR:
+        with cg do
+          begin
+            a_op_const_ref(list,op,OS_32,Lo(Value),ref);
+            tempref:=ref;
+            inc(tempref.offset,4);
+            a_op_const_ref(list,op,OS_32,Hi(Value),tempref);
+          end;
+        OP_ADD, OP_SUB:
+              begin
+                get_64bit_ops(op,op1,op2);
+                { can't use a_op_const_ref because this may use dec/inc}
+  {              list.concat(taicpu.op_const_ref(op1,Lo(Value),ref));
+                tempref:=ref;
+                inc(tempref.offset,4);
+                list.concat(taicpu.op_const_ref(op2,S_SW,Hi(Value),tempref));}
+                InternalError(2002102101);
+              end;
+            else
+              internalerror(200204022);
+          end;
+        end;
+
+
+  { ************* concatcopy ************ }
+  procedure TCgSparc.g_concatcopy(list:taasmoutput;const source,dest:treference;len:aword;delsource,loadref:boolean);
+    var
+      countreg: TRegister;
+      src, dst: TReference;
+      lab: tasmlabel;
+      count, count2: aword;
+      orgsrc, orgdst: boolean;
+      r:Tregister;
+    begin
+  {$ifdef extdebug}
+      if len > high(longint)
+      then
+        internalerror(2002072704);
+  {$endif extdebug}
+     { make sure short loads are handled as optimally as possible }
+      if not loadref
+      then
+        if(len <= 8)and(byte(len) in [1,2,4,8])
+        then
+          begin
+            if len < 8
+            then
+              begin
+                a_load_ref_ref(list,int_cgsize(len),source,dest);
+                if delsource
+                then
+                  reference_release(list,source);
+              end
+            else
+              begin
+                r.enum:=R_F0;
+                a_reg_alloc(list,r);
+                a_loadfpu_ref_reg(list,OS_F64,source,r);
               if delsource
               if delsource
               then
               then
                 reference_release(list,source);
                 reference_release(list,source);
-            end
-          else
+                a_loadfpu_reg_ref(list,OS_F64,r,dest);
+                a_reg_dealloc(list,r);
+              end;
+            exit;
+          end;
+        reference_reset(src);
+        reference_reset(dst);
+        { load the address of source into src.base }
+        if loadref
+        then
+          begin
+            src.base := get_scratch_reg_address(list);
+            a_load_ref_reg(list,OS_32,source,src.base);
+            orgsrc := false;
+          end
+        else if not issimpleref(source) or
+          ((source.index.enum<>R_NO)and
+          ((source.offset+longint(len))>high(smallint)))
+        then
+          begin
+            src.base := get_scratch_reg_address(list);
+            a_loadaddr_ref_reg(list,source,src.base);
+            orgsrc := false;
+          end
+        else
+          begin
+            src := source;
+            orgsrc := true;
+          end;
+        if not orgsrc and delsource
+        then
+          reference_release(list,source);
+          { load the address of dest into dst.base }
+        if not issimpleref(dest) or
+          ((dest.index.enum <> R_NO) and
+          ((dest.offset + longint(len)) > high(smallint)))
+        then
+          begin
+            dst.base := get_scratch_reg_address(list);
+            a_loadaddr_ref_reg(list,dest,dst.base);
+            orgdst := false;
+          end
+        else
+          begin
+            dst := dest;
+            orgdst := true;
+          end;
+        count:=len and 7;{count:=len div 8}
+        if count>4
+        then
+          { generate a loop }
+          begin
+            { the offsets are zero after the a_loadaddress_ref_reg and just }
+            { have to be set to 8. I put an Inc there so debugging may be   }
+            { easier (should offset be different from zero here, it will be }
+            { easy to notice in the generated assembler                     }
+            inc(dst.offset,8);
+            inc(src.offset,8);
+            list.concat(taicpu.op_reg_const_reg(A_SUB,src.base,8,src.base));
+            list.concat(taicpu.op_reg_const_reg(A_SUB,dst.base,8,dst.base));
+            countreg := get_scratch_reg_int(list,OS_32);
+            a_load_const_reg(list,OS_32,count,countreg);
+            { explicitely allocate R_O0 since it can be used safely here }
+            { (for holding date that's being copied)                    }
+            r.enum:=R_F0;
+            a_reg_alloc(list,r);
+            objectlibrary.getlabel(lab);
+            a_label(list, lab);
+            list.concat(taicpu.op_reg_const_reg(A_SUB,countreg,1,countreg));
+            list.concat(taicpu.op_ref_reg(A_LDF,src,r));
+            list.concat(taicpu.op_reg_ref(A_STD,r,dst));
+            //a_jmp(list,A_BC,C_NE,0,lab);
+            free_scratch_reg(list,countreg);
+            a_reg_dealloc(list,r);
+            len := len mod 8;
+          end;
+          count:=len and 7;
+          if count>0
+          then
+            { unrolled loop }
             begin
             begin
               r.enum:=R_F0;
               r.enum:=R_F0;
               a_reg_alloc(list,r);
               a_reg_alloc(list,r);
-              a_loadfpu_ref_reg(list,OS_F64,source,r);
-            if delsource
-            then
-              reference_release(list,source);
-              a_loadfpu_reg_ref(list,OS_F64,r,dest);
+              for count2 := 1 to count do
+                begin
+                  a_loadfpu_ref_reg(list,OS_F64,src,r);
+                  a_loadfpu_reg_ref(list,OS_F64,r,dst);
+                  inc(src.offset,8);
+                  inc(dst.offset,8);
+                end;
               a_reg_dealloc(list,r);
               a_reg_dealloc(list,r);
+              len := len mod 8;
             end;
             end;
-          exit;
+
+          if (len and 4) <> 0 then
+            begin
+              r.enum:=R_O0;
+              a_reg_alloc(list,r);
+              a_load_ref_reg(list,OS_32,src,r);
+              a_load_reg_ref(list,OS_32,r,dst);
+              inc(src.offset,4);
+              inc(dst.offset,4);
+              a_reg_dealloc(list,r);
+            end;
+         { copy the leftovers }
+         if (len and 2) <> 0 then
+           begin
+             r.enum:=R_O0;
+             a_reg_alloc(list,r);
+             a_load_ref_reg(list,OS_16,src,r);
+             a_load_reg_ref(list,OS_16,r,dst);
+             inc(src.offset,2);
+             inc(dst.offset,2);
+             a_reg_dealloc(list,r);
+           end;
+         if (len and 1) <> 0 then
+           begin
+             r.enum:=R_O0;
+             a_reg_alloc(list,r);
+             a_load_ref_reg(list,OS_8,src,r);
+             a_load_reg_ref(list,OS_8,r,dst);
+             a_reg_dealloc(list,r);
+           end;
+         if orgsrc then
+           begin
+             if delsource then
+               reference_release(list,source);
+           end
+         else
+           free_scratch_reg(list,src.base);
+         if not orgdst then
+           free_scratch_reg(list,dst.base);
         end;
         end;
-      reference_reset(src);
-      reference_reset(dst);
-      { load the address of source into src.base }
-      if loadref
+  function TCgSparc.reg_cgsize(CONST reg:tregister):tcgsize;
+    begin
+      result:=OS_32;
+    end;
+
+
+  {***************** This is private property, keep out! :) *****************}
+  function TCgSparc.IsSimpleRef(const ref:treference):boolean;
+    begin
+      if(ref.base.enum=R_NONE)and(ref.index.enum <> R_NO)
       then
       then
-        begin
-          src.base := get_scratch_reg_address(list);
-          a_load_ref_reg(list,OS_32,source,src.base);
-          orgsrc := false;
-        end
-      else if not issimpleref(source) or
-        ((source.index.enum<>R_NO)and
-        ((source.offset+longint(len))>high(smallint)))
+        InternalError(2002100804);
+      result :=not(assigned(ref.symbol))and
+                (((ref.index.enum = R_NO) and
+                 (ref.offset >= low(smallint)) and
+                  (ref.offset <= high(smallint))) or
+                ((ref.index.enum <> R_NO) and
+                (ref.offset = 0)));
+    end;
+  procedure TCgSparc.sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
+    begin
+      case s2 of
+        S_B:
+          if S1 in [OS_8,OS_S8]
+          then
+            s3 := S_B
+          else
+            internalerror(200109221);
+        S_W:
+          case s1 of
+            OS_8,OS_S8:
+              s3 := S_B;
+            OS_16,OS_S16:
+              s3 := S_H;
+          else
+            internalerror(200109222);
+          end;
+        S_SW:
+          case s1 of
+            OS_8,OS_S8:
+              s3 := S_B;
+            OS_16,OS_S16:
+              s3 := S_H;
+            OS_32,OS_S32:
+              s3 := S_W;
+            else
+              internalerror(200109223);
+          end;
+        else internalerror(200109227);
+      end;
+      if s3 in [S_B,S_W,S_SW]
       then
       then
-        begin
-          src.base := get_scratch_reg_address(list);
-          a_loadaddr_ref_reg(list,source,src.base);
-          orgsrc := false;
-        end
-      else
-        begin
-          src := source;
-          orgsrc := true;
-        end;
-      if not orgsrc and delsource
+        op := A_LD
+  {    else if s3=S_DW
       then
       then
-        reference_release(list,source);
-        { load the address of dest into dst.base }
-      if not issimpleref(dest) or
-        ((dest.index.enum <> R_NO) and
-        ((dest.offset + longint(len)) > high(smallint)))
+        op:=A_LDD
+      else if s3 in [OS_8,OS_16,OS_32]
       then
       then
-        begin
-          dst.base := get_scratch_reg_address(list);
-          a_loadaddr_ref_reg(list,dest,dst.base);
-          orgdst := false;
-        end
+        op := A_NONE}
       else
       else
-        begin
-          dst := dest;
-          orgdst := true;
-        end;
-      count:=len and 7;{count:=len div 8}
-      if count>4
-      then
-        { generate a loop }
-        begin
-          { the offsets are zero after the a_loadaddress_ref_reg and just }
-          { have to be set to 8. I put an Inc there so debugging may be   }
-          { easier (should offset be different from zero here, it will be }
-          { easy to notice in the generated assembler                     }
-          inc(dst.offset,8);
-          inc(src.offset,8);
-          list.concat(taicpu.op_reg_const_reg(A_SUB,src.base,8,src.base));
-          list.concat(taicpu.op_reg_const_reg(A_SUB,dst.base,8,dst.base));
-          countreg := get_scratch_reg_int(list,OS_32);
-          a_load_const_reg(list,OS_32,count,countreg);
-          { explicitely allocate R_O0 since it can be used safely here }
-          { (for holding date that's being copied)                    }
-          r.enum:=R_F0;
-          a_reg_alloc(list,r);
-          objectlibrary.getlabel(lab);
-          a_label(list, lab);
-          list.concat(taicpu.op_reg_const_reg(A_SUB,countreg,1,countreg));
-          list.concat(taicpu.op_ref_reg(A_LDF,src,r));
-          list.concat(taicpu.op_reg_ref(A_STD,r,dst));
-          //a_jmp(list,A_BC,C_NE,0,lab);
-          free_scratch_reg(list,countreg);
-          a_reg_dealloc(list,r);
-          len := len mod 8;
+        op := A_NONE;
+    end;
+  procedure TCgSparc.floatloadops(t:tcgsize;VAR op:tasmop;VAR s:topsize);
+    BEGIN
+  (*         case t of
+              OS_F32:begin
+                          op:=A_FLD;
+                          s:=S_FS;
+                       end;
+              OS_F64:begin
+                          op:=A_FLD;
+                          { ???? }
+                          s:=S_FL;
+                       end;
+              OS_F80:begin
+                          op:=A_FLD;
+                          s:=S_FX;
+                       end;
+              OS_C64:begin
+                          op:=A_FILD;
+                          s:=S_IQ;
+                       end;
+              else internalerror(17);
+           end;*)
+    END;
+  procedure TCgSparc.floatload(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
+    VAR
+      op:tasmop;
+      s:topsize;
+    BEGIN
+      floatloadops(t,op,s);
+      list.concat(Taicpu.Op_ref(op,ref));
+  {    inc(trgcpu(rg).fpuvaroffset);}
+    END;
+  procedure TCgSparc.floatstoreops(t:tcgsize;var op:tasmop;var s:topsize);
+    BEGIN
+  {         case t of
+              OS_F32:begin
+                          op:=A_FSTP;
+                          s:=S_FS;
+                       end;
+              OS_F64:begin
+                          op:=A_FSTP;
+                          s:=S_FL;
+                       end;
+              OS_F80:begin
+                          op:=A_FSTP;
+                          s:=S_FX;
+                       end;
+              OS_C64:begin
+                          op:=A_FISTP;
+                          s:=S_IQ;
+                       end;
+           else
+             internalerror(17);
+           end;}
         end;
         end;
-        count:=len and 7;
-        if count>0
-        then
-          { unrolled loop }
-          begin
-            r.enum:=R_F0;
-            a_reg_alloc(list,r);
-            for count2 := 1 to count do
-              begin
-                a_loadfpu_ref_reg(list,OS_F64,src,r);
-                a_loadfpu_reg_ref(list,OS_F64,r,dst);
-                inc(src.offset,8);
-                inc(dst.offset,8);
-              end;
-            a_reg_dealloc(list,r);
-            len := len mod 8;
-          end;
+  procedure TCgSparc.floatstore(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
+    VAR
+      op:tasmop;
+      s:topsize;
+    BEGIN
+      floatstoreops(t,op,s);
+      list.concat(Taicpu.Op_ref(op,ref));
+  {    dec(trgcpu(rg).fpuvaroffset);}
+    END;
 
 
-        if (len and 4) <> 0 then
-          begin
-            r.enum:=R_O0;
-            a_reg_alloc(list,r);
-            a_load_ref_reg(list,OS_32,src,r);
-            a_load_reg_ref(list,OS_32,r,dst);
-            inc(src.offset,4);
-            inc(dst.offset,4);
-            a_reg_dealloc(list,r);
-          end;
-       { copy the leftovers }
-       if (len and 2) <> 0 then
-         begin
-           r.enum:=R_O0;
-           a_reg_alloc(list,r);
-           a_load_ref_reg(list,OS_16,src,r);
-           a_load_reg_ref(list,OS_16,r,dst);
-           inc(src.offset,2);
-           inc(dst.offset,2);
-           a_reg_dealloc(list,r);
-         end;
-       if (len and 1) <> 0 then
-         begin
-           r.enum:=R_O0;
-           a_reg_alloc(list,r);
-           a_load_ref_reg(list,OS_8,src,r);
-           a_load_reg_ref(list,OS_8,r,dst);
-           a_reg_dealloc(list,r);
-         end;
-       if orgsrc then
-         begin
-           if delsource then
-             reference_release(list,source);
-         end
-       else
-         free_scratch_reg(list,src.base);
-       if not orgdst then
-         free_scratch_reg(list,dst.base);
-      end;
-function TCgSparc.reg_cgsize(CONST reg:tregister):tcgsize;
   begin
   begin
-    result:=OS_32;
-  end;
-
+    cg:=TCgSparc.Create;
+    cg64:=TCg64Sparc.Create;
+  end.
 
 
-{***************** This is private property, keep out! :) *****************}
-function TCgSparc.IsSimpleRef(const ref:treference):boolean;
-  begin
-    if(ref.base.enum=R_NONE)and(ref.index.enum <> R_NO)
-    then
-      InternalError(2002100804);
-    result :=not(assigned(ref.symbol))and
-              (((ref.index.enum = R_NO) and
-               (ref.offset >= low(smallint)) and
-                (ref.offset <= high(smallint))) or
-              ((ref.index.enum <> R_NO) and
-              (ref.offset = 0)));
-  end;
-procedure TCgSparc.sizes2load(s1:tcgsize;s2:topsize;var op:tasmop;var s3:topsize);
-  begin
-    case s2 of
-      S_B:
-        if S1 in [OS_8,OS_S8]
-        then
-          s3 := S_B
-        else
-          internalerror(200109221);
-      S_W:
-        case s1 of
-          OS_8,OS_S8:
-            s3 := S_B;
-          OS_16,OS_S16:
-            s3 := S_H;
-        else
-          internalerror(200109222);
-        end;
-      S_SW:
-        case s1 of
-          OS_8,OS_S8:
-            s3 := S_B;
-          OS_16,OS_S16:
-            s3 := S_H;
-          OS_32,OS_S32:
-            s3 := S_W;
-          else
-            internalerror(200109223);
-        end;
-      else internalerror(200109227);
-    end;
-    if s3 in [S_B,S_W,S_SW]
-    then
-      op := A_LD
-{    else if s3=S_DW
-    then
-      op:=A_LDD
-    else if s3 in [OS_8,OS_16,OS_32]
-    then
-      op := A_NONE}
-    else
-      op := A_NONE;
-  end;
-procedure TCgSparc.floatloadops(t:tcgsize;VAR op:tasmop;VAR s:topsize);
-  BEGIN
-(*         case t of
-            OS_F32:begin
-                        op:=A_FLD;
-                        s:=S_FS;
-                     end;
-            OS_F64:begin
-                        op:=A_FLD;
-                        { ???? }
-                        s:=S_FL;
-                     end;
-            OS_F80:begin
-                        op:=A_FLD;
-                        s:=S_FX;
-                     end;
-            OS_C64:begin
-                        op:=A_FILD;
-                        s:=S_IQ;
-                     end;
-            else internalerror(17);
-         end;*)
-  END;
-procedure TCgSparc.floatload(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
-  VAR
-    op:tasmop;
-    s:topsize;
-  BEGIN
-    floatloadops(t,op,s);
-    list.concat(Taicpu.Op_ref(op,ref));
-{    inc(trgcpu(rg).fpuvaroffset);}
-  END;
-procedure TCgSparc.floatstoreops(t:tcgsize;var op:tasmop;var s:topsize);
-  BEGIN
-{         case t of
-            OS_F32:begin
-                        op:=A_FSTP;
-                        s:=S_FS;
-                     end;
-            OS_F64:begin
-                        op:=A_FSTP;
-                        s:=S_FL;
-                     end;
-            OS_F80:begin
-                        op:=A_FSTP;
-                        s:=S_FX;
-                     end;
-            OS_C64:begin
-                        op:=A_FISTP;
-                        s:=S_IQ;
-                     end;
-         else
-           internalerror(17);
-         end;}
-      end;
-procedure TCgSparc.floatstore(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
-  VAR
-    op:tasmop;
-    s:topsize;
-  BEGIN
-    floatstoreops(t,op,s);
-    list.concat(Taicpu.Op_ref(op,ref));
-{    dec(trgcpu(rg).fpuvaroffset);}
-  END;
-BEGIN
-  cg:=TCgSparc.Create;
-  cg64:=TCg64Sparc.Create;
-END.
 {
 {
   $Log$
   $Log$
-  Revision 1.51  2003-05-26 22:04:57  mazen
+  Revision 1.52  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.51  2003/05/26 22:04:57  mazen
   * added 64 bit value support to fix a problem in RTL
   * added 64 bit value support to fix a problem in RTL
 
 
   Revision 1.50  2003/05/23 22:33:48  florian
   Revision 1.50  2003/05/23 22:33:48  florian

+ 78 - 58
compiler/sparc/cpubase.pas

@@ -19,9 +19,14 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  ****************************************************************************}
  ****************************************************************************}
 unit cpuBase;
 unit cpuBase;
-{$INCLUDE fpcdefs.inc}
+
+{$i fpcdefs.inc}
+
 interface
 interface
-uses globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
+
+  uses
+    globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
+
 const
 const
   {Size of the instruction table converted by nasmconv.pas}
   {Size of the instruction table converted by nasmconv.pas}
   maxinfolen=8;
   maxinfolen=8;
@@ -481,31 +486,36 @@ type
 type
 type
   TRefOptions=(ref_none,ref_parafixup,ref_localfixup,ref_selffixup);
   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 }
   { immediate/reference record }
   poperreference = ^treference;
   poperreference = ^treference;
   Preference=^Treference;
   Preference=^Treference;
   treference = packed record
   treference = packed record
-     segment,
      base,
      base,
      index       : tregister;
      index       : tregister;
-     scalefactor : byte;
      offset      : LongInt;
      offset      : LongInt;
      symbol      : tasmsymbol;
      symbol      : tasmsymbol;
+     symaddr     : trefsymaddr;
      offsetfixup : LongInt;
      offsetfixup : LongInt;
      options     : trefoptions;
      options     : trefoptions;
      alignment   : byte;
      alignment   : byte;
   end;
   end;
-      { reference record }
+
+  { reference record }
   PParaReference=^TParaReference;
   PParaReference=^TParaReference;
-  TParaReference=PACKED RECORD
-    Index:TRegister;
-    Offset:longint;
+  TParaReference = packed record
+    Index : TRegister;
+    Offset : longint;
   end;
   end;
+
 {*****************************************************************************
 {*****************************************************************************
                                 Operands
                                 Operands
 *****************************************************************************}
 *****************************************************************************}
   { Types of operand }
   { Types of operand }
-  toptype=(top_none,top_reg,top_ref,top_const,top_symbol,top_raddr,top_caddr);
+  toptype=(top_none,top_reg,top_ref,top_const,top_symbol);
   toper=record
   toper=record
     ot:LongInt;
     ot:LongInt;
     case typ:toptype of
     case typ:toptype of
@@ -514,8 +524,6 @@ type
       top_ref:(ref:poperreference);
       top_ref:(ref:poperreference);
       top_const:(val:aword);
       top_const:(val:aword);
       top_symbol:(sym:tasmsymbol;symofs:LongInt);
       top_symbol:(sym:tasmsymbol;symofs:LongInt);
-      top_raddr:(reg1,reg2:TRegister);
-      top_caddr:(regb:TRegister;const13:Integer);
   end;
   end;
 {*****************************************************************************
 {*****************************************************************************
                              Argument Classification
                              Argument Classification
@@ -536,10 +544,10 @@ type
                                Generic Location
                                Generic Location
 *****************************************************************************}
 *****************************************************************************}
 type
 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
+  { 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;
     Size:TCGSize;
     Loc:TCGLoc;
     Loc:TCGLoc;
     sp_fixup:LongInt;
     sp_fixup:LongInt;
@@ -555,10 +563,11 @@ used, because contains a lot of unnessary fields.}
           3 : (reg64 : tregister64);
           3 : (reg64 : tregister64);
           4 : (register64 : tregister64);
           4 : (register64 : tregister64);
         );
         );
-            { it's only for better handling }
+      { it's only for better handling }
       LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
       LOC_MMXREGISTER,LOC_CMMXREGISTER : (mmxreg : tregister);
     end;
     end;
-    TLocation=PACKED RECORD
+
+    TLocation=packed record
          loc  : TCGLoc;
          loc  : TCGLoc;
          size : TCGSize;
          size : TCGSize;
          case TCGLoc of
          case TCGLoc of
@@ -669,35 +678,40 @@ const
   accumulatorhigh = R_O1;
   accumulatorhigh = R_O1;
   NR_ACCUMULATORHIGH = NR_O1;
   NR_ACCUMULATORHIGH = NR_O1;
   RS_ACCUMULATORHIGH = RS_O1;
   RS_ACCUMULATORHIGH = RS_O1;
-  fpu_result_reg  =R_F0;
-  mmresultreg     =R_G0;
+  fpu_result_reg  = R_F0;
+  mmresultreg     = R_G0;
+
 {*****************************************************************************}
 {*****************************************************************************}
 {                        GCC /ABI linking information                         }
 {                        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=[RS_O6];
-{# 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.}
+  { 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;
   std_param_align=4;
-{# Registers which are defined as scratch and no need to save across routine
-calls or in assembler blocks.}
-  ScratchRegsCount=8;
-  scratch_regs:array[1..ScratchRegsCount] OF Tsuperregister=(RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7);
-{ low and high of the available maximum width integer general purpose }
-{ registers                                                           }
+
+  { 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;
   LoGPReg = R_G0;
   HiGPReg = R_I7;
   HiGPReg = R_I7;
 
 
-{ low and high of every possible width general purpose register (same as }
-{ above on most architctures apart from the 80x86)                       }
+  { low and high of every possible width general purpose register (same as
+    above on most architctures apart from the 80x86)                       }
   LoReg = R_G0;
   LoReg = R_G0;
   HiReg = R_I7;
   HiReg = R_I7;
 
 
@@ -705,7 +719,7 @@ calls or in assembler blocks.}
 
 
   { sizes }
   { sizes }
   pointersize   = 4;
   pointersize   = 4;
-  extended_size = 8;{SPARC architecture uses IEEE floating point numbers}
+  extended_size = 8;  { SPARC architecture uses IEEE floating point numbers}
   mmreg_size = 8;
   mmreg_size = 8;
   SizePostfix_pointer = S_SW;
   SizePostfix_pointer = S_SW;
 
 
@@ -734,12 +748,9 @@ VAR
                                   Helpers
                                   Helpers
 *****************************************************************************}
 *****************************************************************************}
 const
 const
-  maxvarregs=30;
+  maxvarregs=8;
   VarRegs:array[1..maxvarregs] of tnewregister = (
   VarRegs:array[1..maxvarregs] of tnewregister = (
-             RS_G0,RS_G1,RS_G2,RS_G3,RS_G4,RS_G5,RS_G6,RS_G7,
-             RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,{RS_R14=RS_SP}RS_O7,
-             RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7,
-             RS_I0,RS_I1,RS_I2,RS_I3,RS_I4,RS_I5,{RS_R30=RS_FP}RS_I7
+             RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7
         );
         );
   maxfpuvarregs = 8;
   maxfpuvarregs = 8;
   max_operands = 3;
   max_operands = 3;
@@ -752,19 +763,23 @@ function is_calljmp(o:tasmop):boolean;
 function flags_to_cond(CONST f:TResFlags):TAsmCond;
 function flags_to_cond(CONST f:TResFlags):TAsmCond;
 procedure convert_register_to_enum(var Reg:Tregister);
 procedure convert_register_to_enum(var Reg:Tregister);
 function cgsize2subreg(s:Tcgsize):Tsubregister;
 function cgsize2subreg(s:Tcgsize):Tsubregister;
+
 implementation
 implementation
-uses
-  verbose;
-const
-  CallJmpOp=[A_JMPL..A_CBccc];
-function is_calljmp(o:tasmop):boolean;
-  begin
-    if o in CallJmpOp
-    then
-      is_calljmp:=true
-    else
-      is_calljmp:=false;
-  end;
+
+  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;
 function flags_to_cond(const f:TResFlags):TAsmCond;
   CONST
   CONST
     flags_2_cond:array[TResFlags]OF TAsmCond=
     flags_2_cond:array[TResFlags]OF TAsmCond=
@@ -772,6 +787,7 @@ function flags_to_cond(const f:TResFlags):TAsmCond;
   BEGIN
   BEGIN
     result:=flags_2_cond[f];
     result:=flags_2_cond[f];
   end;
   end;
+
 procedure convert_register_to_enum(var Reg:Tregister);
 procedure convert_register_to_enum(var Reg:Tregister);
   begin
   begin
     with Reg do
     with Reg do
@@ -788,6 +804,7 @@ procedure convert_register_to_enum(var Reg:Tregister);
         else
         else
           internalerror(200301082);
           internalerror(200301082);
   end;
   end;
+
 function cgsize2subreg(s:Tcgsize):Tsubregister;
 function cgsize2subreg(s:Tcgsize):Tsubregister;
 begin
 begin
   cgsize2subreg:=R_SUBWHOLE;
   cgsize2subreg:=R_SUBWHOLE;
@@ -795,7 +812,10 @@ end;
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.33  2003-05-26 22:08:42  mazen
+  Revision 1.34  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.33  2003/05/26 22:08:42  mazen
   + RegEnum2Number to ease handling register pairs
   + RegEnum2Number to ease handling register pairs
   * changed convert_register_to_enum to use above
   * changed convert_register_to_enum to use above
     array
     array

+ 174 - 164
compiler/sparc/cpugas.pas

@@ -17,182 +17,192 @@
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
  ****************************************************************************}
  ****************************************************************************}
-unit CpuGas;
-{This unit implements an asmoutput class for SPARC AT&T syntax}
-{$MACRO ON}{$INCLUDE fpcdefs.inc}
-interface
-uses
-  cpubase,
-  aasmtai,aasmcpu,assemble,aggas;
-type
-  TGasSPARC=class(TGnuAssembler)
-    procedure WriteInstruction(hp:Tai);override;
-  end;
-implementation
-uses
-  cutils,systems,
-  verbose;
-{$DEFINE gas_reg2str:=std_reg2str}
-function GetReferenceString(var ref:TReference):string;
-  begin
-    GetReferenceString:='+';
-    with ref do
-      if assigned(symbol)
-      then
-        GetReferenceString:=symbol.name
-      else
-        begin
-          inc(offset,offsetfixup);
-          if base.enum<>R_NONE
-          then
-            GetReferenceString:=gas_reg2str[base.enum]+'+';
-          if index.enum<>R_NONE
-          then
-            begin
-              if ScaleFactor<>0
-              then
-                GetReferenceString:=GetReferenceString+ToStr(ScaleFactor)+'*';
-              GetReferenceString:=GetReferenceString+gas_reg2str[index.enum]+'+';
-            end;
-          if Offset=0
-          then
-            SetLength(GetReferenceString,Length(GetReferenceString)-1)
-          else if offset<0
-          then
-            begin
-              SetLength(GetReferenceString,Length(GetReferenceString)-1);
-              GetReferenceString:=GetReferenceString+tostr(offset);
-            end
-          else if offset>0
-          then
-            GetReferenceString:=GetReferenceString+tostr(offset);
-        end;
-  end;
-function getopstr(const Oper:TOper):string;
-  var
-    hs:string;
-  begin
-    with Oper do
-      case typ of
-        top_reg:
-          getopstr:=gas_reg2str[reg.enum];
-        top_ref:
-          getopstr:='['+getreferencestring(ref^)+']';
-        top_const:
-          getopstr:={'$'+}tostr(longint(val));
-        top_symbol:
+{
+  This unit implements an asmoutput class for SPARC AT&T syntax
+}
+unit cpugas;
+
+{$i fpcdefs.inc}
+
+  interface
+
+    uses
+      cpubase,
+      aasmtai,aasmcpu,assemble,aggas;
+
+    type
+      TGasSPARC=class(TGnuAssembler)
+        procedure WriteInstruction(hp:Tai);override;
+      end;
+
+  implementation
+
+    uses
+      cutils,systems,
+      verbose;
+
+    function GetReferenceString(var ref:TReference):string;
+      begin
+        GetReferenceString:='';
+        with ref do
           begin
           begin
-            if assigned(sym) then
-              hs:={'$'+}sym.name
-            else
-              hs:='$';
-            if symofs>0 then
-             hs:=hs+'+'+tostr(symofs)
-            else
-             if symofs<0 then
-              hs:=hs+tostr(symofs)
+            inc(offset,offsetfixup);
+            offsetfixup:=0;
+            if base.enum>lastreg then
+              internalerror(200301081);
+            if index.enum>lastreg then
+              internalerror(200301081);
+
+            if assigned(symbol) then
+              begin
+                 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
+                   GetReferenceString:='%lo('+GetReferenceString+')'
+                 else
+                   internalerror(2003052602);
+              end
             else
             else
-             if not(assigned(sym)) then
-               hs:=hs+'0';
-            getopstr:=hs;
+              begin
+                if base.enum<>R_NONE then
+                  GetReferenceString:=std_reg2str[base.enum]+'+';
+                if index.enum<>R_NONE then
+                  GetReferenceString:=GetReferenceString+std_reg2str[index.enum]+'+';
+                if Offset<>0 then
+                   internalerror(2003052603);
+              end;
           end;
           end;
-        top_raddr:
-          getopstr:=std_reg2str[reg1.enum]+'+'+std_reg2str[reg2.enum];
-        top_caddr:
-          getopstr:=std_reg2str[regb.enum]+'+'+ToStr(const13);
-        else
-          internalerror(10001);
       end;
       end;
-    end;
-(*
-function getopstr_jmp(const Oper:TOper):string;
-  var
-    hs:string;
-  begin
-    with Oper do
-      case typ of
-        top_reg:
-          getopstr_jmp:=gas_reg2str[reg]+'+';
-        top_ref:
-          getopstr_jmp:=GetReferenceString(ref^);
-        top_const:
-          getopstr_jmp:=tostr(longint(val));
-        top_symbol:
-          begin
-            hs:=sym.name;
-            if symofs>0 then
-             hs:=hs+'+'+tostr(symofs)
+
+
+    function getopstr(const Oper:TOper):string;
+      var
+        hs:string;
+      begin
+        with Oper do
+          case typ of
+            top_reg:
+              getopstr:=std_reg2str[reg.enum];
+            top_ref:
+              getopstr:=getreferencestring(ref^);
+            top_const:
+              getopstr:=tostr(longint(val));
+            top_symbol:
+              begin
+                if assigned(sym) then
+                  hs:={'$'+}sym.name
+                else
+                  hs:='$';
+                if symofs>0 then
+                 hs:=hs+'+'+tostr(symofs)
+                else
+                 if symofs<0 then
+                  hs:=hs+tostr(symofs)
+                else
+                 if not(assigned(sym)) then
+                   hs:=hs+'0';
+                getopstr:=hs;
+              end;
             else
             else
-             if symofs<0 then
-              hs:=hs+tostr(symofs);
-            getopstr_jmp:=hs;
+              internalerror(10001);
           end;
           end;
-        else
-          internalerror(10001);
-      end;
-    end;*)
-{****************************************************************************
-                            TSPARCATTASMOUTPUT
- ****************************************************************************}
-procedure TGasSPARC.WriteInstruction(hp:Tai);
-	var
-		Op:TAsmOp;
-		s:String;
-		i:Integer;
-	begin
-		if hp.typ<>ait_instruction
-		then
-			Exit;
-		op:=taicpu(hp).opcode;
-	 {call maybe not translated to call}
-		s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
-   {process operands}
-    s:=#9+std_op2str[op];
-    if taicpu(hp).ops>0
-    then
+        end;
+    (*
+    function getopstr_jmp(const Oper:TOper):string;
+      var
+        hs:string;
+      begin
+        with Oper do
+          case typ of
+            top_reg:
+              getopstr_jmp:=gas_reg2str[reg]+'+';
+            top_ref:
+              getopstr_jmp:=GetReferenceString(ref^);
+            top_const:
+              getopstr_jmp:=tostr(longint(val));
+            top_symbol:
+              begin
+                hs:=sym.name;
+                if symofs>0 then
+                 hs:=hs+'+'+tostr(symofs)
+                else
+                 if symofs<0 then
+                  hs:=hs+tostr(symofs);
+                getopstr_jmp:=hs;
+              end;
+            else
+              internalerror(10001);
+          end;
+        end;*)
+
+    procedure TGasSPARC.WriteInstruction(hp:Tai);
+    	var
+    		Op:TAsmOp;
+    		s:String;
+    		i:Integer;
       begin
       begin
-        s:=s+#9+getopstr(taicpu(hp).oper[0]);
-        for i:=1 to taicpu(hp).ops-1 do
-          s:=s+','+getopstr(taicpu(hp).oper[i]);
+        if hp.typ<>ait_instruction then
+          exit;
+        op:=taicpu(hp).opcode;
+        { call maybe not translated to call }
+        s:=#9+std_op2str[op]+cond2str[taicpu(hp).condition];
+        { process operands }
+        s:=#9+std_op2str[op];
+        if taicpu(hp).ops>0
+        then
+          begin
+            s:=s+#9+getopstr(taicpu(hp).oper[0]);
+            for i:=1 to taicpu(hp).ops-1 do
+              s:=s+','+getopstr(taicpu(hp).oper[i]);
+          end;
+        AsmWriteLn(s);
       end;
       end;
-    AsmWriteLn(s);
-  end;
-{*****************************************************************************
-                                  Initialize
-*****************************************************************************}
-const
-  as_SPARC_as_info:TAsmInfo=(
-    id:as_gas;
-    idtxt:'AS';
-    asmbin:'as';
-    asmcmd:'-o $OBJ $ASM';
-    supported_target:system_any;
-    outputbinary:false;
-    allowdirect:true;
-    needar:true;
-    labelprefix_only_inside_procedure:false;
-    labelprefix:'.L';
-    comment:';#';
-    secnames:({sec_none}'',           {no section}
-              {sec_code}'.text',      {executable code}
-              {sec_data}'.data',      {initialized R/W data}
-              {sec_bss}'.section ".bss"',        {uninitialized R/W data}
-              {sec_idata2}'.comment', {comments}
-              {sec_idata4}'.debug',   {debugging information}
-              {sec_idata5}'.rodata',  {RO data}
-              {sec_idata6}'.line',    {line numbers info for symbolic debug}
-              {sec_idata7}'.init',    {runtime intialization code}
-              {sec_edata}'.fini',     {runtime finalization code}
-              {sec_stab}'.stab',
-              {sec_stabstr} '.stabstr',
-              {sec_common}'.note')    {note info}
-  );
-initialization
+
+
+    const
+      as_SPARC_as_info:TAsmInfo=(
+        id:as_gas;
+        idtxt:'AS';
+        asmbin:'as';
+        asmcmd:'-o $OBJ $ASM';
+        supported_target:system_any;
+        outputbinary:false;
+        allowdirect:true;
+        needar:true;
+        labelprefix_only_inside_procedure:false;
+        labelprefix:'.L';
+        comment:';#';
+        secnames:({sec_none}'',           {no section}
+                  {sec_code}'.text',      {executable code}
+                  {sec_data}'.data',      {initialized R/W data}
+                  {sec_bss}'.section ".bss"',        {uninitialized R/W data}
+                  {sec_idata2}'.comment', {comments}
+                  {sec_idata4}'.debug',   {debugging information}
+                  {sec_idata5}'.rodata',  {RO data}
+                  {sec_idata6}'.line',    {line numbers info for symbolic debug}
+                  {sec_idata7}'.init',    {runtime intialization code}
+                  {sec_edata}'.fini',     {runtime finalization code}
+                  {sec_stab}'.stab',
+                  {sec_stabstr} '.stabstr',
+                  {sec_common}'.note')    {note info}
+      );
+
+begin
   RegisterAssembler(as_SPARC_as_info,TGasSPARC);
   RegisterAssembler(as_SPARC_as_info,TGasSPARC);
 end.
 end.
 {
 {
     $Log$
     $Log$
-    Revision 1.14  2003-05-07 11:55:34  mazen
+    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
     - unused units removed from uses clause
     - unused units removed from uses clause
     - unused variables removed from implemntation declarations
     - unused variables removed from implemntation declarations
 
 

+ 7 - 4
compiler/systems.pas

@@ -111,8 +111,8 @@ interface
              system_x86_64_linux,       { 26 }
              system_x86_64_linux,       { 26 }
              system_powerpc_darwin,     { 27 }
              system_powerpc_darwin,     { 27 }
              system_i386_EMX,           { 28 }
              system_i386_EMX,           { 28 }
-	     system_powerpc_netbsd,	{ 29 } 
-	     system_powerpc_openbsd	{ 30 } 
+	         system_powerpc_netbsd,	    { 29 }
+    	     system_powerpc_openbsd	    { 30 }
        );
        );
 
 
        tasm = (as_none
        tasm = (as_none
@@ -685,7 +685,10 @@ finalization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.63  2003-05-25 23:15:04  marco
+  Revision 1.64  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.63  2003/05/25 23:15:04  marco
    * NetBSD target support. OpenBSD reserved in the enum, for future use.
    * NetBSD target support. OpenBSD reserved in the enum, for future use.
 
 
   Revision 1.62  2003/05/20 23:54:00  florian
   Revision 1.62  2003/05/20 23:54:00  florian
@@ -782,4 +785,4 @@ end.
 
 
   Revision 1.38  2002/04/14 16:56:30  carl
   Revision 1.38  2002/04/14 16:56:30  carl
   - remove duplicate comment
   - remove duplicate comment
-}
+}

+ 5 - 3
compiler/systems/i_bsd.pas

@@ -377,12 +377,14 @@ initialization
   {$ifdef NetBSD}
   {$ifdef NetBSD}
      set_source_info(system_powerpc_netbsd_info);
      set_source_info(system_powerpc_netbsd_info);
   {$endif}
   {$endif}
-  
 {$endif cpu68}
 {$endif cpu68}
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2003-05-25 23:15:04  marco
+  Revision 1.3  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.2  2003/05/25 23:15:04  marco
    * NetBSD target support. OpenBSD reserved in the enum, for future use.
    * NetBSD target support. OpenBSD reserved in the enum, for future use.
 
 
   Revision 1.1  2003/05/20 23:54:00  florian
   Revision 1.1  2003/05/20 23:54:00  florian
@@ -409,4 +411,4 @@ end.
 
 
   Revision 1.1  2002/07/26 21:15:38  florian
   Revision 1.1  2002/07/26 21:15:38  florian
     * rewrote the system handling
     * rewrote the system handling
-}
+}

+ 9 - 5
compiler/x86/agx86att.pas

@@ -63,16 +63,17 @@ interface
          begin
          begin
            inc(offset,offsetfixup);
            inc(offset,offsetfixup);
            offsetfixup:=0;
            offsetfixup:=0;
-         { have we a segment prefix ? }
-         { These are probably not correctly handled under GAS }
-         { should be replaced by coding the segment override  }
-         { directly! - DJGPP FAQ                              }
            if segment.enum>lastreg then
            if segment.enum>lastreg then
              internalerror(200301081);
              internalerror(200301081);
            if base.enum>lastreg then
            if base.enum>lastreg then
              internalerror(200301081);
              internalerror(200301081);
            if index.enum>lastreg then
            if index.enum>lastreg then
              internalerror(200301081);
              internalerror(200301081);
+
+           { have we a segment prefix ? }
+           { These are probably not correctly handled under GAS }
+           { should be replaced by coding the segment override  }
+           { directly! - DJGPP FAQ                              }
            if segment.enum<>R_NO then
            if segment.enum<>R_NO then
             AsmWrite(gas_reg2str[segment.enum]+':');
             AsmWrite(gas_reg2str[segment.enum]+':');
            if assigned(symbol) then
            if assigned(symbol) then
@@ -347,7 +348,10 @@ initialization
 end.
 end.
 {
 {
   $Log$
   $Log$
-  Revision 1.2  2003-05-22 21:33:31  peter
+  Revision 1.3  2003-05-28 23:18:31  florian
+    * started to fix and clean up the sparc port
+
+  Revision 1.2  2003/05/22 21:33:31  peter
     * removed some unit dependencies
     * removed some unit dependencies
 
 
   Revision 1.1  2003/04/25 12:04:31  florian
   Revision 1.1  2003/04/25 12:04:31  florian