Browse Source

* many stuff related to RTL fixed

mazen 22 năm trước cách đây
mục cha
commit
c3321868d5

+ 32 - 20
compiler/sparc/cgcpu.pas

@@ -34,7 +34,7 @@ specific processor ABI. It is overriden for each CPU target.
   Size    : is the size of the operand in the register
   r       : is the register source of the operand
   LocPara : is the location where the parameter will be stored}
-    procedure a_param_reg(list:TAasmOutput;size:tcgsize;r:tregister;const LocPara:TParaLocation);override;
+    procedure a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);override;
     {passes a parameter which is a constant to a function}
     procedure a_param_const(list:TAasmOutput;size:tcgsize;a:aword;CONST LocPara:TParaLocation);override;
     procedure a_param_ref(list:TAasmOutput;sz:tcgsize;CONST r:TReference;CONST LocPara:TParaLocation);override;
@@ -93,7 +93,7 @@ specific processor ABI. It is overriden for each CPU target.
     procedure floatloadops(t:tcgsize;var op:tasmop;var s:topsize);
     procedure floatstoreops(t:tcgsize;var op:tasmop;var s:topsize);
   END;
-  TCg64fSPARC=class(tcg64f32)
+  TCg64Sparc=class(tcg64f32)
     procedure a_op64_ref_reg(list:TAasmOutput;op:TOpCG;CONST ref:TReference;reg:TRegister64);override;
     procedure a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);override;
     procedure a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:qWord;regdst:TRegister64);override;
@@ -110,22 +110,30 @@ USES
   globtype,globals,verbose,systems,cutils,
   symdef,symsym,defutil,paramgr,
   rgobj,tgobj,rgcpu,cpupi;
-    { we implement the following routines because otherwise we can't }
-    { instantiate the class since it's abstract                      }
-procedure TCgSparc.a_param_reg(list:TAasmOutput;size:tcgsize;r:tregister;const LocPara:TParaLocation);
-
-var r2:Tregister;
-
+procedure TCgSparc.a_param_reg(list:TAasmOutput;sz:tcgsize;r:tregister;const LocPara:TParaLocation);
+  var
+    r2:Tregister;
   begin
     r2.enum:=R_G0;
-    if(Size<>OS_32)and(Size<>OS_S32)
-    then
-      InternalError(2002032212);
     with list,LocPara do
       case Loc of
         LOC_REGISTER:
-          if r.enum<>Register.enum then
-            Concat(taicpu.op_Reg_Reg_Reg(A_OR,r,r2,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;
@@ -1004,7 +1012,7 @@ procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
 //         list.concat(taicpu.op_ref_reg(A_LEA,S_SW,ref,r));
        end;
 { ************* 64bit operations ************ }
-    procedure TCg64fSPARC.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
+    procedure TCg64Sparc.get_64bit_ops(op:TOpCG;var op1,op2:TAsmOp);
       begin
         case op of
           OP_ADD :
@@ -1038,7 +1046,7 @@ procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
       end;
 
 
-    procedure TCg64fSPARC.a_op64_ref_reg(list:TAasmOutput;op:TOpCG;CONST ref:TReference;reg:TRegister64);
+    procedure TCg64Sparc.a_op64_ref_reg(list:TAasmOutput;op:TOpCG;CONST ref:TReference;reg:TRegister64);
       var
         op1,op2:TAsmOp;
         tempref:TReference;
@@ -1051,7 +1059,7 @@ procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
       end;
 
 
-    procedure TCg64fSPARC.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);
+    procedure TCg64Sparc.a_op64_reg_reg(list:TAasmOutput;op:TOpCG;regsrc,regdst:TRegister64);
       var
         op1,op2:TAsmOp;
       begin
@@ -1061,7 +1069,7 @@ procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
       end;
 
 
-    procedure TCg64fSPARC.a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:qWord;regdst:TRegister64);
+    procedure TCg64Sparc.a_op64_const_reg(list:TAasmOutput;op:TOpCG;value:qWord;regdst:TRegister64);
       var
         op1,op2:TAsmOp;
       begin
@@ -1085,7 +1093,7 @@ procedure TCgSparc.a_loadaddr_ref_reg(list:TAasmOutput;CONST ref:TReference;r:tr
       end;
 
 
-procedure TCg64fSPARC.a_op64_const_ref(list:TAasmOutput;op:TOpCG;value:qWord;const ref:TReference);
+procedure TCg64Sparc.a_op64_const_ref(list:TAasmOutput;op:TOpCG;value:qWord;const ref:TReference);
   var
     op1,op2:TAsmOp;
     tempref:TReference;
@@ -1405,11 +1413,15 @@ procedure TCgSparc.floatstore(list:TAasmOutput;t:tcgsize;CONST ref:TReference);
 {    dec(trgcpu(rg).fpuvaroffset);}
   END;
 BEGIN
-  cg:=TCgSparc.create;
+  cg:=TCgSparc.Create;
+  cg64:=TCg64Sparc.Create;
 END.
 {
   $Log$
-  Revision 1.34  2003-01-08 18:43:58  daniel
+  Revision 1.35  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.34  2003/01/08 18:43:58  daniel
    * Tregister changed into a record
 
   Revision 1.33  2003/01/07 22:03:40  mazen

+ 102 - 44
compiler/sparc/cpubase.pas

@@ -18,11 +18,11 @@
     along with this program; if not, write to the Free Software
     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  ****************************************************************************}
-UNIT cpuBase;
+unit cpuBase;
 {$INCLUDE fpcdefs.inc}
-INTERFACE
-USES globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
-CONST
+interface
+uses globals,cutils,cclasses,aasmbase,cpuinfo,cginfo;
+const
   {Size of the instruction table converted by nasmconv.pas}
   maxinfolen=8;
   {Defines the default address size for a processor}
@@ -32,9 +32,8 @@ CONST
   {the maximum float size for a processor}
   OS_FLOAT=OS_F64;
   {the size of a vector register for a processor}
-  OS_VECTOR=OS_M64;{$WARNING "OS_VECTOR" was set to "OS_M64" but not verified!}
-CONST
-{Operand types}
+  OS_VECTOR=OS_M64;
+  {Operand types}
   OT_NONE      = $00000000;
   OT_BITS8     = $00000001;  { size, and other attributes, of the operand  }
   OT_BITS16    = $00000002;
@@ -184,7 +183,7 @@ CONST
 CONST
   CondAsmOps=3;
   CondAsmOp:ARRAY[0..CondAsmOps-1] of TAsmOp=(A_FCMPd, A_JMPL, A_FCMPs);
-  CondAsmOpStr:ARRAY[0..CondAsmOps-1] of string[4]=('FCMPd','JMPL','FCMPs');
+  CondAsmOpStr:ARRAY[0..CondAsmOps-1] of string[7]=('FCMPd','JMPL','FCMPs');
 {*****************************************************************************}
 {                                 Registers                                   }
 {*****************************************************************************}
@@ -208,7 +207,7 @@ CONST
   lastreg  = high(R_ASR31);
   
 type
-  reg2strtable=ARRAY[firstreg..lastreg] OF STRING[6];
+  reg2strtable=ARRAY[firstreg..lastreg] OF STRING[7];
 
 const
   std_reg2str:reg2strtable=({$INCLUDE strregs.inc});
@@ -362,7 +361,7 @@ used, because contains a lot of unnessary fields.}
 
 const
   general_registers = [R_G0..R_I7];
-  { legEND:                                                                }
+  { legend:                                                                }
   { xxxregs = set of all possibly used registers of that type in the code  }
   {           generator                                                    }
   { usableregsxxx = set of all 32bit components of registers that can be   }
@@ -371,16 +370,16 @@ const
   {           passing on ABI's that define this)                           }
   { c_countusableregsxxx = amount of registers in the usableregsxxx set    }
   IntRegs=[R_G0..R_I7];
-  usableregsint=general_registers;
-  c_countusableregsint = 4;
+  usableregsint=[R_O0..R_I7];
+  c_countusableregsint = 24;
   fpuregs=[R_F0..R_F31];
-  usableregsfpu=[];
-  c_countusableregsfpu=0;
+  usableregsfpu=[R_F0..R_F31];
+  c_countusableregsfpu=32;
   mmregs=[];
   usableregsmm=[];
-  c_countusableregsmm=8;
+  c_countusableregsmm=0;
   
-  firstsaveintreg = R_I0;
+  firstsaveintreg = R_O0;
   lastsaveintreg = R_I7;
   firstsavefpureg = R_F0;
   lastsavefpureg = R_F31;
@@ -393,42 +392,29 @@ const
 
   lvaluelocations = [LOC_REFERENCE,LOC_CFPUREGISTER,
     LOC_CREGISTER,LOC_MMXREGISTER,LOC_CMMXREGISTER];
-{
-  registers_saved_on_cdecl = [R_ESI,R_EDI,R_EBX];}
-
 {*****************************************************************************
                                GDB Information
 *****************************************************************************}
-
-      {# Register indexes for stabs information, when some
-         parameters or variables are stored in registers.
-
-         Taken from rs6000.h (DBX_REGISTER_NUMBER)
-         from GCC 3.x source code. PowerPC has 1:1 mapping
-         according to the order of the registers defined
-         in GCC
-
-      }
-
+  {# Register indexes for stabs information, when some parameters or variables
+  are stored in registers.
+  Taken from rs6000.h (DBX_REGISTER_NUMBER) from GCC 3.x source code.}
   stab_regindex:ARRAY[firstreg..lastreg]OF ShortInt=({$INCLUDE stabregi.inc});
 {*************************** generic register names **************************}
 	stack_pointer_reg		=	R_O6;
   frame_pointer_reg		=	R_I6;
-
   {the return_result_reg, is used inside the called function to store its return
   value when that is a scalar value otherwise a pointer to the address of the
   result is placed inside it}
 	return_result_reg		=	R_I0;
-
   {the function_result_reg contains the function result after a call to a scalar
   function othewise it contains a pointer to the returned result}
 	function_result_reg	=	R_O0;
   self_pointer_reg  =R_G5;
-{There is no accumulator in the SPARC architecture. There are just families of
-registers. All registers belonging to the same family are identical except in
-the "global registers" family where GO is different from the others : G0 gives
-always 0 when it is red and thows away any value written to it.Nevertheless,
-scalar routine results are returned onto R_O0.}
+  {There is no accumulator in the SPARC architecture. There are just families
+  of registers. All registers belonging to the same family are identical except
+  in the "global registers" family where GO is different from the others :
+  G0 gives always 0 when it is red and thows away any value written to it.
+  Nevertheless, scalar routine results are returned onto R_O0.}
   accumulator     = R_O0;
   accumulatorhigh = R_O1;
   fpu_result_reg  =R_F0;
@@ -451,9 +437,8 @@ PARM_BOUNDARY / BITS_PER_UNIT in the GCC source.}
   std_param_align=4;
 {# Registers which are defined as scratch and no need to save across routine
 calls or in assembler blocks.}
-  ScratchRegsCount=3;
-  scratch_regs:ARRAY[1..ScratchRegsCount]OF ToldRegister=(R_O4,R_O5,R_I7);
-  {$WARNING FIXME : Scratch registers list has to be verified}
+  ScratchRegsCount=8;
+  scratch_regs:ARRAY[1..ScratchRegsCount]OF ToldRegister=(R_L0,R_L1,R_L2,R_L3,R_L4,R_L5,R_L6,R_L7);
 { low and high of the available maximum width integer general purpose }
 { registers                                                           }
   LoGPReg = R_G0;
@@ -536,10 +521,80 @@ function flags_to_cond(const f:TResFlags):TAsmCond;
   END;
 
 procedure convert_register_to_enum(var r:Tregister);
-
+const
+  NR_NO=$0000;
+  NR_G0=$0001;
+  NR_G1=$0002;
+  NR_G2=$0003;
+  NR_G3=$0004;
+  NR_G4=$0005;
+  NR_G5=$0006;
+  NR_G6=$0007;
+  NR_G7=$0008;
+  NR_O0=$0100;
+  NR_O1=$0200;
+  NR_O2=$0300;
+  NR_O3=$0400;
+  NR_O4=$0500;
+  NR_O5=$0600;
+  NR_O6=$0700;
+  NR_O7=$0800;
+  NR_L0=$0900;
+  NR_L1=$0A00;
+  NR_L2=$0B00;
+  NR_L3=$0C00;
+  NR_L4=$0D00;
+  NR_L5=$0E00;
+  NR_L6=$0F00;
+  NR_L7=$1000;
+  NR_I0=$1100;
+  NR_I1=$1200;
+  NR_I2=$1300;
+  NR_I3=$1400;
+  NR_I4=$1500;
+  NR_I5=$1600;
+  NR_I6=$1700;
+  NR_I7=$1800;
 begin
-    {$warning Convert_register_to_enum implementation is missing!}
-    internalerror(200301082);
+  if r.enum=R_INTREGISTER
+  then
+    case r.number of
+      NR_NO: r.enum:= R_NO;
+      NR_G0: r.enum:= R_G0;
+      NR_G1: r.enum:= R_G1;
+      NR_G2: r.enum:= R_G2;
+      NR_G3: r.enum:= R_G3;
+      NR_G4: r.enum:= R_G4;
+      NR_G5: r.enum:= R_G5;
+      NR_G6: r.enum:= R_G6;
+      NR_G7: r.enum:= R_G7;
+      NR_O0: r.enum:= R_O0;
+      NR_O1: r.enum:= R_O1;
+      NR_O2: r.enum:= R_O2;
+      NR_O3: r.enum:= R_O3;
+      NR_O4: r.enum:= R_O4;
+      NR_O5: r.enum:= R_O5;
+      NR_O6: r.enum:= R_O6;
+      NR_O7: r.enum:= R_O7;
+      NR_L0: r.enum:= R_L0;
+      NR_L1: r.enum:= R_L1;
+      NR_L2: r.enum:= R_L2;
+      NR_L3: r.enum:= R_L3;
+      NR_L4: r.enum:= R_L4;
+      NR_L5: r.enum:= R_L5;
+      NR_L6: r.enum:= R_L6;
+      NR_L7: r.enum:= R_L7;
+      NR_I0: r.enum:= R_I0;
+      NR_I1: r.enum:= R_I1;
+      NR_I2: r.enum:= R_I2;
+      NR_I3: r.enum:= R_I3;
+      NR_I4: r.enum:= R_I4;
+      NR_I5: r.enum:= R_I5;
+      NR_I6: r.enum:= R_I6;
+      NR_I7: r.enum:= R_I7;
+      else
+        internalerror(200301082);
+    end;
 end;
 
 END.
@@ -548,7 +603,10 @@ END.
 
 {
   $Log$
-  Revision 1.20  2003-01-09 20:41:00  daniel
+  Revision 1.21  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.20  2003/01/09 20:41:00  daniel
     * Converted some code in cgx86.pas to new register numbering
 
   Revision 1.19  2003/01/09 15:49:56  daniel

+ 473 - 3
compiler/sparc/ncpuadd.pas

@@ -29,6 +29,8 @@ type
     procedure pass_2;override;
   private
     procedure second_addboolean;
+    procedure second_add64bit;
+    procedure second_addfloat;
     function GetResFlags(unsigned:Boolean):TResFlags;
     procedure left_must_be_reg(OpSize:TOpSize;NoSwap:Boolean);
     procedure emit_generic_code(op:TAsmOp;OpSize:TOpSize;unsigned,extra_not,mboverflow:Boolean);
@@ -402,6 +404,468 @@ procedure TSparcAddNode.emit_op_right_left(op:TAsmOp);
           InternalError(200203232);
       end;
   end;
+procedure TSparcAddNode.second_add64bit;
+  var
+    op         : TOpCG;
+    op1,op2    : TAsmOp;
+    hl4        : tasmlabel;
+    cmpop,
+    unsigned   : boolean;
+    r          : Tregister;
+  procedure emit_cmp64_hi;
+    var
+      oldleft, oldright: tlocation;
+    begin
+      // put the high part of the location in the low part
+      location_copy(oldleft,left.location);
+      location_copy(oldright,right.location);
+      if left.location.loc = LOC_CONSTANT
+      then
+        left.location.valueqword := left.location.valueqword shr 32
+      else
+        left.location.registerlow := left.location.registerhigh;
+      if right.location.loc = LOC_CONSTANT
+      then
+        right.location.valueqword := right.location.valueqword shr 32
+      else
+        right.location.registerlow := right.location.registerhigh;
+      // and call the normal emit_compare
+      //emit_compare(unsigned);
+      location_copy(left.location,oldleft);
+      location_copy(right.location,oldright);
+    end;
+    procedure emit_cmp64_lo;
+      begin
+//        emit_compare(true);
+      end;
+    procedure firstjmp64bitcmp;
+      var
+        oldnodetype: tnodetype;
+      begin
+        load_all_regvars(exprasmlist);
+        { the jump the sequence is a little bit hairy }
+        case nodetype of
+          ltn,gtn:
+            begin
+              cg.a_jmp_flags(exprasmlist,getresflags(false),truelabel);
+              { cheat a little bit for the negative test }
+              toggleflag(nf_swaped);
+              cg.a_jmp_flags(exprasmlist,getresflags(false),falselabel);
+              toggleflag(nf_swaped);
+            end;
+          lten,gten:
+            begin
+              oldnodetype:=nodetype;
+                if nodetype=lten then
+                     nodetype:=ltn
+                   else
+                     nodetype:=gtn;
+                   cg.a_jmp_flags(exprasmlist,getresflags(false),truelabel);
+                   { cheat for the negative test }
+                   if nodetype=ltn then
+                     nodetype:=gtn
+                   else
+                     nodetype:=ltn;
+                   cg.a_jmp_flags(exprasmlist,getresflags(false),falselabel);
+                   nodetype:=oldnodetype;
+                end;
+              equaln:
+                begin
+                  nodetype := unequaln;
+                  cg.a_jmp_flags(exprasmlist,getresflags(true),falselabel);
+                  nodetype := equaln;
+                end;
+              unequaln:
+                begin
+                  cg.a_jmp_flags(exprasmlist,getresflags(true),truelabel);
+                end;
+           end;
+        end;
+
+
+      procedure secondjmp64bitcmp;
+
+        begin
+           { the jump the sequence is a little bit hairy }
+           case nodetype of
+              ltn,gtn,lten,gten:
+                begin
+                   { the comparison of the low dword always has }
+                   { to be always unsigned!                     }
+                   cg.a_jmp_flags(exprasmlist,getresflags(false),truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+              equaln:
+                begin
+                   nodetype := unequaln;
+                   cg.a_jmp_flags(exprasmlist,getresflags(true),falselabel);
+                   cg.a_jmp_always(exprasmlist,truelabel);
+                   nodetype := equaln;
+                end;
+              unequaln:
+                begin
+                   cg.a_jmp_flags(exprasmlist,getresflags(true),truelabel);
+                   cg.a_jmp_always(exprasmlist,falselabel);
+                end;
+           end;
+        end;
+
+
+    var
+      tempreg64: tregister64;
+
+      begin
+        firstcomplex(self);
+
+        pass_left_and_right;
+
+        cmpop:=false;
+        unsigned:=((left.resulttype.def.deftype=orddef) and
+                   (torddef(left.resulttype.def).typ=u64bit)) or
+                  ((right.resulttype.def.deftype=orddef) and
+                   (torddef(right.resulttype.def).typ=u64bit));
+        case nodetype of
+          addn :
+            begin
+              op:=OP_ADD;
+            end;
+          subn :
+            begin
+              op:=OP_SUB;
+            end;
+          ltn,lten,
+          gtn,gten,
+          equaln,unequaln:
+            begin
+              op:=OP_NONE;
+              cmpop:=true;
+            end;
+          xorn:
+            op:=OP_XOR;
+          orn:
+            op:=OP_OR;
+          andn:
+            op:=OP_AND;
+          muln:
+            begin
+              { should be handled in pass_1 (JM) }
+              internalerror(200109051);
+            end;
+          else
+            internalerror(2002072705);
+        end;
+
+        if not cmpop then
+          location_reset(location,LOC_REGISTER,def_cgsize(resulttype.def));
+
+        //load_left_right(cmpop,(cs_check_overflow in aktlocalswitches) and (nodetype in [addn,subn]));
+
+        if not(cs_check_overflow in aktlocalswitches) or
+           not(nodetype in [addn,subn]) then
+          begin
+            case nodetype of
+              ltn,lten,
+              gtn,gten:
+                begin
+                  emit_cmp64_hi;
+                  firstjmp64bitcmp;
+                  emit_cmp64_lo;
+                  secondjmp64bitcmp;
+                end;
+              equaln,unequaln:
+                begin
+                  // instead of doing a complicated compare, do
+                  // (left.hi xor right.hi) or (left.lo xor right.lo)
+                  // (somewhate optimized so that no superfluous 'mr's are
+                  //  generated)
+                  if (left.location.loc = LOC_CONSTANT) then
+                    swapleftright;
+                  if (right.location.loc = LOC_CONSTANT) then
+                    begin
+                      if left.location.loc = LOC_REGISTER then
+                        begin
+                          tempreg64.reglo := left.location.registerlow;
+                          tempreg64.reghi := left.location.registerhigh;
+                        end
+                      else
+                        begin
+                          if (right.location.valueqword <> 0)
+                          then
+                            tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist)
+                          else
+                            tempreg64.reglo := left.location.registerlow;
+                          if ((right.location.valueqword shr 32) <> 0) then
+                            tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist)
+                          else
+                            tempreg64.reghi := left.location.registerhigh;
+                        end;
+
+                      if (right.location.valueqword <> 0) then
+                        { negative values can be handled using SUB, }
+                        { positive values < 65535 using XOR.        }
+                        if (longint(right.location.valueqword) >= -32767) and
+                           (longint(right.location.valueqword) < 0) then
+                          cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
+                            right.location.valueqword,
+                            left.location.registerlow,tempreg64.reglo)
+                        else
+                          cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
+                            right.location.valueqword,
+                            left.location.registerlow,tempreg64.reglo);
+
+                      if ((right.location.valueqword shr 32) <> 0) then
+                        if (longint(right.location.valueqword shr 32) >= -32767) and
+                           (longint(right.location.valueqword shr 32) < 0) then
+                          cg.a_op_const_reg_reg(exprasmlist,OP_SUB,OS_INT,
+                            right.location.valueqword shr 32,
+                            left.location.registerhigh,tempreg64.reghi)
+                        else
+                          cg.a_op_const_reg_reg(exprasmlist,OP_XOR,OS_INT,
+                            right.location.valueqword shr 32,
+                            left.location.registerhigh,tempreg64.reghi);
+                    end
+                  else
+                    begin
+                       tempreg64.reglo := cg.get_scratch_reg_int(exprasmlist);
+                       tempreg64.reghi := cg.get_scratch_reg_int(exprasmlist);
+                       cg64.a_op64_reg_reg_reg(exprasmlist,OP_XOR,
+                         left.location.register64,right.location.register64,
+                         tempreg64);
+                    end;
+
+                  r.enum:=R_G0;
+                  cg.a_reg_alloc(exprasmlist,r);
+                  exprasmlist.concat(taicpu.op_reg_reg_reg(A_OR,r,
+                    tempreg64.reglo,tempreg64.reghi));
+                  cg.a_reg_dealloc(exprasmlist,r);
+                  if (tempreg64.reglo.enum <> left.location.registerlow.enum) then
+                    cg.free_scratch_reg(exprasmlist,tempreg64.reglo);
+                  if (tempreg64.reghi.enum <> left.location.registerhigh.enum) then
+                    cg.free_scratch_reg(exprasmlist,tempreg64.reghi);
+
+                  location_reset(location,LOC_FLAGS,OS_NO);
+                  location.resflags := getresflags(true);
+                end;
+              xorn,orn,andn,addn:
+                begin
+                  if (location.registerlow.enum = R_NO) then
+                    begin
+                      location.registerlow := rg.getregisterint(exprasmlist);
+                      location.registerhigh := rg.getregisterint(exprasmlist);
+                    end;
+
+                  if (left.location.loc = LOC_CONSTANT) then
+                    swapleftright;
+                  if (right.location.loc = LOC_CONSTANT) then
+                    cg64.a_op64_const_reg_reg(exprasmlist,op,right.location.valueqword,
+                      left.location.register64,location.register64)
+                  else
+                    cg64.a_op64_reg_reg_reg(exprasmlist,op,right.location.register64,
+                      left.location.register64,location.register64);
+                end;
+              subn:
+                begin
+                  if (nf_swaped in flags) then
+                    swapleftright;
+
+                  if left.location.loc <> LOC_CONSTANT then
+                    begin
+                      if (location.registerlow.enum = R_NO) then
+                        begin
+                         location.registerlow := rg.getregisterint(exprasmlist);
+                         location.registerhigh := rg.getregisterint(exprasmlist);
+                      end;
+                      if right.location.loc <> LOC_CONSTANT then
+                        // reg64 - reg64
+                        cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
+                          right.location.register64,left.location.register64,
+                          location.register64)
+                      else
+                        // reg64 - const64
+                        cg64.a_op64_const_reg_reg(exprasmlist,OP_SUB,
+                          right.location.valueqword,left.location.register64,
+                          location.register64)
+                    end
+                  else if ((left.location.valueqword shr 32) = 0) then
+                    begin
+                      if (location.registerlow.enum = R_NO) then
+                        begin
+                         location.registerlow := rg.getregisterint(exprasmlist);
+                         location.registerhigh := rg.getregisterint(exprasmlist);
+                      end;
+                      if (int64(left.location.valueqword) >= low(smallint)) and
+                         (int64(left.location.valueqword) <= high(smallint))
+                      then
+                        begin
+                          // consts16 - reg64
+                          exprasmlist.concat(taicpu.op_reg_const_Reg(A_SUBcc,location.registerlow,left.location.value,right.location.registerlow));
+                        end
+                      else
+                        begin
+                          // const32 - reg64
+                          cg.a_load_const_reg(exprasmlist,OS_32,
+                            left.location.valueqword,location.registerlow);
+                          exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBcc,
+                            location.registerlow,location.registerlow,
+                            right.location.registerlow));
+                        end;
+                      exprasmlist.concat(taicpu.op_reg_reg(A_SUBcc,
+                        location.registerhigh,right.location.registerhigh));
+                    end
+                  else if (left.location.valueqword = 0) then
+                    begin
+                      // (const32 shl 32) - reg64
+                      if (location.registerlow.enum = R_NO) then
+                        begin
+                         location.registerlow := rg.getregisterint(exprasmlist);
+                         location.registerhigh := rg.getregisterint(exprasmlist);
+                      end;
+                      exprasmlist.concat(taicpu.op_reg_Const_reg(A_SUBcc,location.registerlow,0,right.location.registerlow));
+                      cg.a_load_const_reg(exprasmlist,OS_INT,
+                        left.location.valueqword shr 32,location.registerhigh);
+                      exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUBcc,
+                        location.registerhigh,right.location.registerhigh,
+                        location.registerhigh));
+                    end
+                  else
+                    begin
+                      // const64 - reg64
+                      location_force_reg(exprasmlist,left.location,
+                        def_cgsize(left.resulttype.def),true);
+                      if (left.location.loc = LOC_REGISTER) then
+                        location.register64 := left.location.register64
+                      else if (location.registerlow.enum = R_NO) then
+                        begin
+                         location.registerlow := rg.getregisterint(exprasmlist);
+                         location.registerhigh := rg.getregisterint(exprasmlist);
+                        end;
+                      cg64.a_op64_reg_reg_reg(exprasmlist,OP_SUB,
+                        right.location.register64,left.location.register64,
+                        location.register64);
+                     end;
+                end;
+              else
+                internalerror(2002072803);
+            end;
+          end
+        else
+          begin
+            case nodetype of
+              addn:
+                begin
+                  op1 := A_ADDcc;
+                  op2 := A_ADDcc;
+                end;
+              subn:
+                begin
+                  op1 := A_SUBcc;
+                  op2 := A_SUBcc;
+                end;
+              else
+                internalerror(2002072806);
+            end;
+            exprasmlist.concat(taicpu.op_reg_reg_reg(op1,location.registerlow,
+              left.location.registerlow,right.location.registerlow));
+            exprasmlist.concat(taicpu.op_reg_reg_reg(op2,location.registerhigh,
+              right.location.registerhigh,left.location.registerhigh));
+            cg.g_overflowcheck(exprasmlist,self);
+          end;
+
+        { set result location }
+        { (emit_compare sets it to LOC_FLAGS for compares, so set the }
+        {  real location only now) (JM)                               }
+        if cmpop and
+           not(nodetype in [equaln,unequaln]) then
+          location_reset(location,LOC_JUMP,OS_NO);
+
+//        clear_left_right(cmpop);
+
+      end;
+procedure TSparcAddNode.second_addfloat;
+  var
+    reg   : tregister;
+    op    : TAsmOp;
+    cmpop : boolean;
+    r     : Tregister;
+
+      procedure location_force_fpureg(var l: tlocation);
+        begin
+          if not(l.loc in [LOC_FPUREGISTER,LOC_CFPUREGISTER]) then
+            begin
+              reg := rg.getregisterfpu(exprasmlist);
+              cg.a_loadfpu_loc_reg(exprasmlist,l,reg);
+              location_freetemp(exprasmlist,l);
+              location_release(exprasmlist,l);
+              location_reset(l,LOC_FPUREGISTER,l.size);
+              l.register := reg;
+            end;
+        end;
+
+  begin
+        pass_left_and_right;
+
+        cmpop:=false;
+        case nodetype of
+          addn :
+            op:=A_FADDs;
+          muln :
+            op:=A_FMULs;
+          subn :
+            op:=A_FSUBs;
+          slashn :
+            op:=A_FDIVs;
+          ltn,lten,gtn,gten,
+          equaln,unequaln :
+            begin
+              op:=A_FCMPs;
+              cmpop:=true;
+            end;
+          else
+            CGMessage(type_e_mismatch);
+        end;
+
+        // get the operands in the correct order, there are no special cases
+        // here, everything is register-based
+        if nf_swaped in flags then
+          swapleftright;
+
+        // put both operands in a register
+        location_force_fpureg(right.location);
+        location_force_fpureg(left.location);
+
+        // initialize de result
+        if not cmpop then
+          begin
+            location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+            if left.location.loc = LOC_FPUREGISTER then
+              location.register := left.location.register
+            else if right.location.loc = LOC_FPUREGISTER then
+              location.register := right.location.register
+            else
+              location.register := rg.getregisterfpu(exprasmlist);
+          end
+        else
+         begin
+           location_reset(location,LOC_FLAGS,OS_NO);
+           location.resflags := getresflags(true);
+         end;
+
+        // emit the actual operation
+        if not cmpop then
+          begin
+            exprasmlist.concat(taicpu.op_reg_reg_reg(op,
+              location.register,left.location.register,
+              right.location.register))
+          end
+        else
+          begin
+            r.enum:=R_PSR;
+            exprasmlist.concat(taicpu.op_reg_reg_reg(op,
+              r,left.location.register,right.location.register))
+          end;
+
+//        clear_left_right(cmpop);
+  end;
 procedure TSparcAddNode.set_result_location(cmpOp,unsigned:Boolean);
   begin
     IF cmpOp
@@ -444,7 +908,7 @@ procedures }
           second_addboolean
         else if is_64bitint(left.resulttype.def)
         then{64bit operations}
-            InternalError(20020726);//second_add64bit;
+          second_add64bit;
       stringdef:
         InternalError(20020726);//second_addstring;
       setdef:
@@ -457,7 +921,10 @@ procedures }
       arraydef :
         InternalError(2002110600);
       floatdef :
-        InternalError(20020726);//second_addfloat;
+        begin
+          second_addfloat;
+          exit;
+        end;
     end;
 {defaults}
     extra_not:=false;
@@ -573,7 +1040,10 @@ begin
 end.
 {
     $Log$
-    Revision 1.6  2003-01-08 18:43:58  daniel
+    Revision 1.7  2003-01-20 22:21:36  mazen
+    * many stuff related to RTL fixed
+
+    Revision 1.6  2003/01/08 18:43:58  daniel
      * Tregister changed into a record
 
     Revision 1.5  2003/01/07 22:03:40  mazen

+ 261 - 293
compiler/sparc/ncpucnv.pas

@@ -107,323 +107,291 @@ implementation
 {*****************************************************************************
                              SecondTypeConv
 *****************************************************************************}
-
-    procedure TSparctypeconvnode.second_int_to_int;
-      var
-        newsize : tcgsize;
-        size, leftsize : cardinal;
+procedure TSparctypeconvnode.second_int_to_int;
+  var
+    newsize:tcgsize;
+    size,leftsize:cardinal;
+  begin
+    newsize:=def_cgsize(resulttype.def);
+    { insert range check if not explicit conversion }
+    if not(nf_explizit in flags)
+    then
+      cg.g_rangecheck(exprasmlist,left,resulttype.def);
+    { is the result size smaller ? }
+    size := resulttype.def.size;
+    leftsize := left.resulttype.def.size;
+    if(size < leftsize)or
+      (((newsize in [OS_64,OS_S64])or
+      (left.location.loc <> LOC_REGISTER))and(size > leftsize))
+    then
       begin
-        newsize:=def_cgsize(resulttype.def);
-
-        { insert range check if not explicit conversion }
-        if not(nf_explizit in flags) then
-          cg.g_rangecheck(exprasmlist,left,resulttype.def);
-
-        { is the result size smaller ? }
-        size := resulttype.def.size;
-        leftsize := left.resulttype.def.size;
-        if (size < leftsize) or
-           (((newsize in [OS_64,OS_S64]) or
-             (left.location.loc <> LOC_REGISTER)) and
-            (size > leftsize)) then
-          begin
-            { reuse the left location by default }
-            location_copy(location,left.location);
-            location_force_reg(exprasmlist,location,newsize,false);
-          end
-        else
-          begin
-            { no special loading is required, reuse current location }
-            location_copy(location,left.location);
-            location.size:=newsize;
-          end;
+        { reuse the left location by default }
+        location_copy(location,left.location);
+        location_force_reg(exprasmlist,location,newsize,false);
+      end
+    else
+      begin
+        { no special loading is required, reuse current location }
+        location_copy(location,left.location);
+        location.size:=newsize;
       end;
-
-
-    procedure TSparctypeconvnode.second_int_to_real;
-
-      type
-        tdummyarray = packed array[0..7] of byte;
-
+  end;
+procedure TSparctypeconvnode.second_int_to_real;
+  type
+    tdummyarray = packed array[0..7] of byte;
 {$ifdef VER1_0}
-      var
-        dummy1, dummy2: int64;
+  var
+    dummy1, dummy2: int64;
 {$else VER1_0}
-      const
-         dummy1: int64 = $4330000080000000;
-         dummy2: int64 = $4330000000000000;
+  const
+    dummy1: int64 = $4330000080000000;
+    dummy2: int64 = $4330000000000000;
 {$endif VER1_0}
-
-      var
-        tempconst: trealconstnode;
-        ref: treference;
-        valuereg, tempreg, leftreg, tmpfpureg: tregister;
-        signed, valuereg_is_scratch: boolean;
-      begin
+  var
+    tempconst: trealconstnode;
+    ref: treference;
+    valuereg, tempreg, leftreg, tmpfpureg: tregister;
+    signed, valuereg_is_scratch: boolean;
+  begin
 {$ifdef VER1_0}
-        { the "and" is because 1.0.x will sign-extend the $80000000 to }
-        { $ffffffff80000000 when converting it to int64 (JM)           }
-        dummy1 := int64($80000000) and (int64($43300000) shl 32);
-        dummy2 := int64($43300000) shl 32;
+    { the "and" is because 1.0.x will sign-extend the $80000000 to }
+    { $ffffffff80000000 when converting it to int64 (JM)           }
+    dummy1 := int64($80000000) and (int64($43300000) shl 32);
+    dummy2 := int64($43300000) shl 32;
 {$endif VER1_0}
-
-        valuereg_is_scratch := false;
-        location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
-
-        { the code here comes from the PowerPC Compiler Writer's Guide }
-
-        { * longint to double                               }
-        { addis R0,R0,0x4330  # R0 = 0x43300000             }
-        { stw R0,disp(R1)     # store upper half            }
-        { xoris R3,R3,0x8000  # flip sign bit               }
-        { stw R3,disp+4(R1)   # store lower half            }
-        { lfd FR1,disp(R1)    # float load double of value  }
-        { fsub FR1,FR1,FR2    # subtract 0x4330000080000000 }
-
-        { * cardinal to double                              }
-        { addis R0,R0,0x4330  # R0 = 0x43300000             }
-        { stw R0,disp(R1)     # store upper half            }
-        { stw R3,disp+4(R1)   # store lower half            }
-        { lfd FR1,disp(R1)    # float load double of value  }
-        { fsub FR1,FR1,FR2    # subtract 0x4330000000000000 }
-        tg.Gettemp(exprasmlist,8,tt_normal,ref);
-
-        signed := is_signed(left.resulttype.def);
-
-        { we need a certain constant for the conversion, so create it here }
-        if signed then
-          tempconst :=
-            crealconstnode.create(double(dummy1),
-            pbestrealtype^)
-        else
-          tempconst :=
-            crealconstnode.create(double(dummy2),
-            pbestrealtype^);
-
-        resulttypepass(tempconst);
-        firstpass(tempconst);
-        secondpass(tempconst);
-        if (tempconst.location.loc <> LOC_CREFERENCE) or
-           { has to be handled by a helper }
-           is_64bitint(left.resulttype.def) then
-          internalerror(200110011);
-
-        case left.location.loc of
-          LOC_REGISTER:
+    valuereg_is_scratch := false;
+    location_reset(location,LOC_FPUREGISTER,def_cgsize(resulttype.def));
+    { the code here comes from the PowerPC Compiler Writer's Guide }
+    { * longint to double                               }
+    { addis R0,R0,0x4330  # R0 = 0x43300000             }
+    { stw R0,disp(R1)     # store upper half            }
+    { xoris R3,R3,0x8000  # flip sign bit               }
+    { stw R3,disp+4(R1)   # store lower half            }
+    { lfd FR1,disp(R1)    # float load double of value  }
+    { fsub FR1,FR1,FR2    # subtract 0x4330000080000000 }
+    { * cardinal to double                              }
+    { addis R0,R0,0x4330  # R0 = 0x43300000             }
+    { stw R0,disp(R1)     # store upper half            }
+    { stw R3,disp+4(R1)   # store lower half            }
+    { lfd FR1,disp(R1)    # float load double of value  }
+    { fsub FR1,FR1,FR2    # subtract 0x4330000000000000 }
+    tg.Gettemp(exprasmlist,8,tt_normal,ref);
+    signed := is_signed(left.resulttype.def);
+    { we need a certain constant for the conversion, so create it here }
+    if signed
+    then
+      tempconst:=crealconstnode.create(double(dummy1),pbestrealtype^)
+    else
+      tempconst:=crealconstnode.create(double(dummy2),pbestrealtype^);
+    resulttypepass(tempconst);
+    firstpass(tempconst);
+    secondpass(tempconst);
+    if (tempconst.location.loc <> LOC_CREFERENCE)or
+    { has to be handled by a helper }
+       is_64bitint(left.resulttype.def)
+    then
+      internalerror(200110011);
+    case left.location.loc of
+      LOC_REGISTER:
+        begin
+          leftreg := left.location.register;
+          valuereg := leftreg;
+        end;
+      LOC_CREGISTER:
+        begin
+          leftreg := left.location.register;
+          if signed
+          then
             begin
-              leftreg := left.location.register;
-              valuereg := leftreg;
-            end;
-          LOC_CREGISTER:
-            begin
-              leftreg := left.location.register;
-              if signed then
-                begin
-                  valuereg := cg.get_scratch_reg_int(exprasmlist);
-                  valuereg_is_scratch := true;
-                end
-              else
-                valuereg := leftreg;
-            end;
-          LOC_REFERENCE,LOC_CREFERENCE:
-            begin
-              leftreg := cg.get_scratch_reg_int(exprasmlist);
-              valuereg := leftreg;
+              valuereg := cg.get_scratch_reg_int(exprasmlist);
               valuereg_is_scratch := true;
-              cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
-                left.location.reference,leftreg);
             end
           else
-            internalerror(200110012);
-         end;
-         tempreg := cg.get_scratch_reg_int(exprasmlist);
-         {$WARNING FIXME what really should be done?}
-         exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,tempreg,$4330,tempreg));
-         cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
-         cg.free_scratch_reg(exprasmlist,tempreg);
-         if signed then
-         {$WARNING FIXME what really should be done?}
-           exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,leftreg,$8000,valuereg));
-         inc(ref.offset,4);
-         cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
-         dec(ref.offset,4);
-         if (valuereg_is_scratch) then
-           cg.free_scratch_reg(exprasmlist,valuereg);
-
-         if (left.location.loc = LOC_REGISTER) or
-            ((left.location.loc = LOC_CREGISTER) and
-             not signed) then
-           rg.ungetregister(exprasmlist,leftreg)
-         else
-           cg.free_scratch_reg(exprasmlist,valuereg);
-
-         tmpfpureg := rg.getregisterfpu(exprasmlist);
-         cg.a_loadfpu_ref_reg(exprasmlist,OS_F64,tempconst.location.reference,
-           tmpfpureg);
-         tempconst.free;
-
-         location.register := rg.getregisterfpu(exprasmlist);
-         {$WARNING FIXME what really should be done?}
-         exprasmlist.concat(taicpu.op_reg_ref(A_LD,location.register,ref));
-
-         tg.ungetiftemp(exprasmlist,ref);
-
-         exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,location.register,
-           location.register,tmpfpureg));
-         rg.ungetregisterfpu(exprasmlist,tmpfpureg);
-
-         { work around bug in some PowerPC processors }
-         if (tfloatdef(resulttype.def).typ = s32real) then
-         {$WARNING FIXME what really should be done?}
-           exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
-       end;
-
-
-     procedure TSparctypeconvnode.second_real_to_real;
-       begin
-          inherited second_real_to_real;
-          { work around bug in some powerpc processors where doubles aren't }
-          { properly converted to singles                                   }
-          if (tfloatdef(left.resulttype.def).typ = s64real) and
-             (tfloatdef(resulttype.def).typ = s32real) then
-         {$WARNING FIXME what really should be done?}
-            exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
-       end;
-
-
-
-
-    procedure TSparctypeconvnode.second_int_to_bool;
-      var
-        hreg1,
-        hreg2    : tregister;
-        resflags : tresflags;
-        opsize   : tcgsize;
+            valuereg := leftreg;
+        end;
+      LOC_REFERENCE,LOC_CREFERENCE:
+        begin
+          leftreg := cg.get_scratch_reg_int(exprasmlist);
+          valuereg := leftreg;
+          valuereg_is_scratch := true;
+          cg.a_load_ref_reg(exprasmlist,def_cgsize(left.resulttype.def),
+          left.location.reference,leftreg);
+        end
+      else
+        internalerror(200110012);
+    end;
+      tempreg := cg.get_scratch_reg_int(exprasmlist);
+      {$WARNING FIXME what really should be done?}
+      exprasmlist.concat(taicpu.op_reg_const_reg(A_OR,tempreg,$4330,tempreg));
+      cg.a_load_reg_ref(exprasmlist,OS_32,tempreg,ref);
+      cg.free_scratch_reg(exprasmlist,tempreg);
+      if signed
+      then
+        {$WARNING FIXME what really should be done?}
+        exprasmlist.concat(taicpu.op_reg_const_reg(A_XOR,leftreg,$8000,valuereg));
+      inc(ref.offset,4);
+      cg.a_load_reg_ref(exprasmlist,OS_32,valuereg,ref);
+      dec(ref.offset,4);
+      if (valuereg_is_scratch)
+      then
+        cg.free_scratch_reg(exprasmlist,valuereg);
+      if(left.location.loc = LOC_REGISTER) or
+        ((left.location.loc = LOC_CREGISTER) and not signed)
+      then
+        rg.ungetregister(exprasmlist,leftreg)
+      else
+        cg.free_scratch_reg(exprasmlist,valuereg);
+      tmpfpureg := rg.getregisterfpu(exprasmlist);
+      cg.a_loadfpu_ref_reg(exprasmlist,OS_F64,tempconst.location.reference,tmpfpureg);
+      tempconst.free;
+      location.register := rg.getregisterfpu(exprasmlist);
+      {$WARNING FIXME what really should be done?}
+      exprasmlist.concat(taicpu.op_reg_ref(A_LD,location.register,ref));
+      tg.ungetiftemp(exprasmlist,ref);
+      exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,location.register,location.register,tmpfpureg));
+      rg.ungetregisterfpu(exprasmlist,tmpfpureg);
+      { work around bug in some PowerPC processors }
+      if (tfloatdef(resulttype.def).typ = s32real)
+      then
+        {$WARNING FIXME what really should be done?}
+        exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
+  end;
+procedure TSparctypeconvnode.second_real_to_real;
+  begin
+    inherited second_real_to_real;
+    { work around bug in some powerpc processors where doubles aren't }
+    { properly converted to singles                                   }
+    if(tfloatdef(left.resulttype.def).typ = s64real)and
+      (tfloatdef(resulttype.def).typ = s32real)
+    then
+      {$WARNING FIXME what really should be done?}
+      exprasmlist.concat(taicpu.op_reg_reg(A_ADD,location.register,location.register));
+  end;
+procedure TSparctypeconvnode.second_int_to_bool;
+  var
+    hreg1,hreg2:tregister;
+    resflags : tresflags;
+    opsize   : tcgsize;
+  begin
+    { byte(boolean) or word(wordbool) or longint(longbool) must }
+    { be accepted for var parameters                            }
+    if(nf_explizit in flags)and
+      (left.resulttype.def.size=resulttype.def.size)and
+      (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER])
+    then
       begin
-         { byte(boolean) or word(wordbool) or longint(longbool) must }
-         { be accepted for var parameters                            }
-         if (nf_explizit in flags) and
-            (left.resulttype.def.size=resulttype.def.size) and
-            (left.location.loc in [LOC_REFERENCE,LOC_CREFERENCE,LOC_CREGISTER]) then
-           begin
-              location_copy(location,left.location);
-              exit;
-           end;
-         location_reset(location,LOC_REGISTER,def_cgsize(left.resulttype.def));
-         opsize := def_cgsize(left.resulttype.def);
-         case left.location.loc of
-            LOC_CREFERENCE,LOC_REFERENCE,LOC_REGISTER,LOC_CREGISTER :
-              begin
-                if left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE] then
-                  begin
-                    reference_release(exprasmlist,left.location.reference);
-                    hreg2:=rg.getregisterint(exprasmlist);
-                    cg.a_load_ref_reg(exprasmlist,opsize,
-                      left.location.reference,hreg2);
-                  end
-                else
-                  hreg2 := left.location.register;
-                hreg1 := rg.getregisterint(exprasmlist);
-                exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,hreg1,1,
-                  hreg2));
-                exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,hreg1,hreg1,hreg2));
-                rg.ungetregister(exprasmlist,hreg2);
-              end;
-            LOC_FLAGS :
-              begin
-                hreg1:=rg.getregisterint(exprasmlist);
-                resflags:=left.location.resflags;
-                cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1);
-              end;
-            else
-              internalerror(10062);
-         end;
-         location.register := hreg1;
+        location_copy(location,left.location);
+        exit;
       end;
-
-
-    procedure TSparctypeconvnode.second_call_helper(c : tconverttype);
-
-      const
-         secondconvert : array[tconverttype] of pointer = (
-           @second_nothing, {equal}
-           @second_nothing, {not_possible}
-           @second_nothing, {second_string_to_string, handled in resulttype pass }
-           @second_char_to_string,
-           @second_nothing, {char_to_charray}
-           @second_nothing, { pchar_to_string, handled in resulttype pass }
-           @second_nothing, {cchar_to_pchar}
-           @second_cstring_to_pchar,
-           @second_ansistring_to_pchar,
-           @second_string_to_chararray,
-           @second_nothing, { chararray_to_string, handled in resulttype pass }
-           @second_array_to_pointer,
-           @second_pointer_to_array,
-           @second_int_to_int,
-           @second_int_to_bool,
-           @second_bool_to_int, { bool_to_bool }
-           @second_bool_to_int,
-           @second_real_to_real,
-           @second_int_to_real,
-           @second_proc_to_procvar,
-           @second_nothing, { arrayconstructor_to_set }
-           @second_nothing, { second_load_smallset, handled in first pass }
-           @second_cord_to_pointer,
-           @second_nothing, { interface 2 string }
-           @second_nothing, { interface 2 guid   }
-           @second_class_to_intf,
-           @second_char_to_char,
-           @second_nothing,  { normal_2_smallset }
-           @second_nothing,   { dynarray_2_openarray }
-           @second_nothing,
-           {$ifdef fpc}@{$endif}second_nothing,  { variant_2_dynarray }
-           {$ifdef fpc}@{$endif}second_nothing   { dynarray_2_variant}
-         );
-      type
-         tprocedureofobject = procedure of object;
-
+    location_reset(location,LOC_REGISTER,def_cgsize(left.resulttype.def));
+    opsize := def_cgsize(left.resulttype.def);
+    case left.location.loc of
+      LOC_CREFERENCE,LOC_REFERENCE,LOC_REGISTER,LOC_CREGISTER:
+        begin
+          if left.location.loc in [LOC_CREFERENCE,LOC_REFERENCE]
+          then
+            begin
+              reference_release(exprasmlist,left.location.reference);
+              hreg2:=rg.getregisterint(exprasmlist);
+              cg.a_load_ref_reg(exprasmlist,opsize,left.location.reference,hreg2);
+            end
+          else
+            hreg2 := left.location.register;
+            hreg1 := rg.getregisterint(exprasmlist);
+            exprasmlist.concat(taicpu.op_reg_const_reg(A_SUB,hreg1,1,hreg2));
+            exprasmlist.concat(taicpu.op_reg_reg_reg(A_SUB,hreg1,hreg1,hreg2));
+            rg.ungetregister(exprasmlist,hreg2);
+        end;
+      LOC_FLAGS :
+        begin
+          hreg1:=rg.getregisterint(exprasmlist);
+          resflags:=left.location.resflags;
+          cg.g_flags2reg(exprasmlist,location.size,resflags,hreg1);
+        end;
+      else
+        internalerror(10062);
+    end;
+    location.register := hreg1;
+  end;
+procedure TSparctypeconvnode.second_call_helper(c : tconverttype);
+  const
+    secondconvert : array[tconverttype] of pointer = (
+      @second_nothing, {equal}
+      @second_nothing, {not_possible}
+      @second_nothing, {second_string_to_string, handled in resulttype pass }
+      @second_char_to_string,
+      @second_nothing, {char_to_charray}
+      @second_nothing, { pchar_to_string, handled in resulttype pass }
+      @second_nothing, {cchar_to_pchar}
+      @second_cstring_to_pchar,
+      @second_ansistring_to_pchar,
+      @second_string_to_chararray,
+      @second_nothing, { chararray_to_string, handled in resulttype pass }
+      @second_array_to_pointer,
+      @second_pointer_to_array,
+      @second_int_to_int,
+      @second_int_to_bool,
+      @second_bool_to_int, { bool_to_bool }
+      @second_bool_to_int,
+      @second_real_to_real,
+      @second_int_to_real,
+      @second_proc_to_procvar,
+      @second_nothing, { arrayconstructor_to_set }
+      @second_nothing, { second_load_smallset, handled in first pass }
+      @second_cord_to_pointer,
+      @second_nothing, { interface 2 string }
+      @second_nothing, { interface 2 guid   }
+      @second_class_to_intf,
+      @second_char_to_char,
+      @second_nothing,  { normal_2_smallset }
+      @second_nothing,   { dynarray_2_openarray }
+      @second_nothing,
+      {$ifdef fpc}@{$endif}second_nothing,  { variant_2_dynarray }
+      {$ifdef fpc}@{$endif}second_nothing   { dynarray_2_variant}
+    );
+    type
+      tprocedureofobject = procedure of object;
       var
-         r : packed record
-                proc : pointer;
-                obj : pointer;
-             end;
-
+        r:packed record
+            proc : pointer;
+            obj : pointer;
+          end;
       begin
-         { this is a little bit dirty but it works }
-         { and should be quite portable too        }
-         r.proc:=secondconvert[c];
-         r.obj:=self;
-         tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
+        { this is a little bit dirty but it works }
+        { and should be quite portable too        }
+        r.proc:=secondconvert[c];
+        r.obj:=self;
+        tprocedureofobject(r){$ifdef FPC}();{$endif FPC}
       end;
-
-
-    procedure TSparctypeconvnode.pass_2;
+procedure TSparctypeconvnode.pass_2;
 {$ifdef TESTOBJEXT2}
-      var
-         r : preference;
-         nillabel : plabel;
+  var
+    r : preference;
+    nillabel : plabel;
 {$endif TESTOBJEXT2}
+  begin
+    { this isn't good coding, I think tc_bool_2_int, shouldn't be }
+    { type conversion (FK)                                 }
+    if not(convtype in [tc_bool_2_int,tc_bool_2_bool])
+    then
       begin
-         { this isn't good coding, I think tc_bool_2_int, shouldn't be }
-         { type conversion (FK)                                 }
-
-         if not(convtype in [tc_bool_2_int,tc_bool_2_bool]) then
-           begin
-              secondpass(left);
-              location_copy(location,left.location);
-              if codegenerror then
-               exit;
-           end;
-         second_call_helper(convtype);
+        secondpass(left);
+        location_copy(location,left.location);
+        if codegenerror
+        then
+          exit;
       end;
-
-
+      second_call_helper(convtype);
+  end;
 begin
    ctypeconvnode:=TSparctypeconvnode;
 end.
 {
   $Log$
-  Revision 1.9  2002-12-05 14:28:03  florian
+  Revision 1.10  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.9  2002/12/05 14:28:03  florian
     * some variant <-> dyn. array stuff
 
   Revision 1.8  2002/11/25 17:43:28  peter
@@ -519,4 +487,4 @@ end.
   + generic constructor calls
   + start of tassembler / tmodulebase class cleanup
 
-}
+}

+ 6 - 1
compiler/sparc/registers.inc

@@ -51,9 +51,14 @@ implementation according to the Assembler Refernce Manual.(MN)}
 ,R_ASR8,R_ASR9,R_ASR10,R_ASR11,R_ASR12,R_ASR13,R_ASR14,R_ASR15
 ,R_ASR16,R_ASR17,R_ASR18,R_ASR19,R_ASR20,R_ASR21,R_ASR22,R_ASR23
 ,R_ASR24,R_ASR25,R_ASR26,R_ASR27,R_ASR28,R_ASR29,R_ASR30,R_ASR31
+{The following registers are just used with the new register allocator}
+,R_INTREGISTER,R_FLOATREGISTER,R_MMXREGISTER,R_KNIREGISTER
 {
   $Log$
-  Revision 1.2  2002-10-02 22:20:28  mazen
+  Revision 1.3  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.2  2002/10/02 22:20:28  mazen
   + out registers allocator for the first 6 scalar parameters which must be passed into %o0..%o5
 
 }

+ 4 - 2
compiler/sparc/stabregi.inc

@@ -46,5 +46,7 @@ thus, are not specified by the SPARC Reference Manual. I did choose the SUN's
 implementation according to the Assembler Refernce Manual.(MN)}
 ,105{R_ASR0},106{R_ASR1},107{R_ASR2},108{R_ASR3},109{R_ASR4},110{R_ASR5},111{R_ASR6},112{R_ASR7}
 ,113{R_ASR8},114{R_ASR9},115{R_ASR10},116{R_ASR11},117{R_ASR12},118{R_ASR13},119{R_ASR14},120{R_ASR15}
-,121{R_ASR16},122{R_ASR17},123{R_ASR18},124{R_ASR19},125{R_ASR20},126{R_ASR21},128{R_ASR22},129{R_ASR23}
-,130{R_ASR24},131{R_ASR25},132{R_ASR26},133{R_ASR27},134{R_ASR28},135{R_ASR29},136{R_ASR30},137{R_ASR31}
+,121{R_ASR16},122{R_ASR17},123{R_ASR18},124{R_ASR19},125{R_ASR20},126{R_ASR21},127{R_ASR22},127{R_ASR23}
+,127{R_ASR24},127{R_ASR25},127{R_ASR26},127{R_ASR27},127{R_ASR28},127{R_ASR29},127{R_ASR30},127{R_ASR31}
+{The following registers are just used with the new register allocator}
+,-1{R_INTREGISTER},-1{R_FLOATREGISTER},-1{R_MMXREGISTER},-1{R_KNIREGISTER}

+ 2 - 0
compiler/sparc/strregs.inc

@@ -40,3 +40,5 @@ $Id:
 '%asr8','%asr9','%asr10','%asr11','%asr12','%asr13','%asr14','%asr15',
 '%asr16','%asr17','%asr18','%asr19','%asr20','%asr21','%asr22','%asr23',
 '%asr24','%asr25','%asr26','%asr27','%asr28','%asr29','%asr30','%asr31'
+{The following registers are just used with the new register allocator}
+,'%INTREG','%FLTREG','%MMXREG','%KNIREG'

+ 1 - 31
docs/linuxex/ex21.pp

@@ -1,31 +1 @@
-Program Example21;
-
-{ Program to demonstrate the Link and UnLink functions. }
-
-Uses linux;
-
-Var F : Text;
-    S : String;
-begin
-  Assign (F,'test.txt');
-  Rewrite (F);
-  Writeln (F,'This is written to test.txt');
-  Close(f);
-  { new.txt and test.txt are now the same file }
-  if not Link ('test.txt','new.txt') then
-    writeln ('Error when linking !');
-  { Removing test.txt still leaves new.txt }
-  If not Unlink ('test.txt') then
-    Writeln ('Error when unlinking !');
-  Assign (f,'new.txt');
-  Reset (F);
-  While not EOF(f) do 
-    begin
-    Readln(F,S);
-    Writeln ('> ',s);
-    end;
- Close (f);
- { Remove new.txt also }
- If not Unlink ('new.txt') then
-   Writeln ('Error when unlinking !');
-end.
+:pserver:[email protected]:/FPC/CVS

+ 5 - 2
rtl/inc/generic.inc

@@ -965,7 +965,10 @@ end;
 
 {
   $Log$
-  Revision 1.48  2003-01-09 20:14:20  florian
+  Revision 1.49  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.48  2003/01/09 20:14:20  florian
     * fixed helper declarations
 
   Revision 1.47  2003/01/07 22:04:12  mazen
@@ -1065,4 +1068,4 @@ end;
       instead of direct comparisons of low/high values of orddefs because
       qword is a special case
 
-}
+}

+ 5 - 1
rtl/inc/mathh.inc

@@ -47,6 +47,7 @@
 {$ifdef SUPPORT_DOUBLE}
     function Real2Double(r : real48) : double;
     operator := (b:real48) d:double;
+    function fpc_int64_to_double(i: int64): double; compilerproc;
 {$endif}
 {$ifdef SUPPORT_EXTENDED}
     operator := (b:real48) e:extended;
@@ -54,7 +55,10 @@
 
 {
   $Log$
-  Revision 1.11  2003-01-15 00:40:18  peter
+  Revision 1.12  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.11  2003/01/15 00:40:18  peter
     * power returns int64
 
   Revision 1.10  2003/01/03 20:34:02  peter

+ 5 - 2
rtl/sparc/math.inc

@@ -138,7 +138,7 @@
                        Longint data type routines
  ****************************************************************************}
 
-   function power(bas,expo : longint) : longint;
+   function power(bas,expo : Int64) : Int64;
      begin
         if bas=0 then
           begin
@@ -284,7 +284,10 @@ end{ ['R0','R3','F0','F1','F2','F3']};
 
 {
   $Log$
-  Revision 1.1  2002-12-24 21:30:20  mazen
+  Revision 1.2  2003-01-20 22:21:36  mazen
+  * many stuff related to RTL fixed
+
+  Revision 1.1  2002/12/24 21:30:20  mazen
   - some writeln(s) removed in compiler
   + many files added to RTL
   * some errors fixed in RTL