Bläddra i källkod

+ support for the different flag registers of sparc
* fixing 64 bit cmp operations on sparc64

git-svn-id: trunk@36638 -

florian 8 år sedan
förälder
incheckning
28cfa838b5

+ 3 - 0
compiler/ncgcnv.pas

@@ -217,6 +217,9 @@ interface
         resflags.reg1:=NR_NO;
         resflags.reg2:=NR_NO;
         resflags.cond:=OC_NONE;
+{$elseif defined(sparcgen)}
+        { Load left node into flag F_NE/F_E }
+        resflags.Init(NR_ICC,F_NE);
 {$else}
         { Load left node into flag F_NE/F_E }
         resflags:=F_NE;

+ 36 - 12
compiler/sparcgen/cgsparc.pas

@@ -741,7 +741,7 @@ implementation
                   list.concat(taicpu.op_reg_reg(A_MOV,NR_Y,tmpreg1));
                   list.concat(taicpu.op_reg_reg(A_CMP,NR_G0,tmpreg1));
                   ovloc.loc:=LOC_FLAGS;
-                  ovloc.resflags:=F_NE;
+                  ovloc.resflags.Init(NR_ICC,F_NE);
                 end;
               OP_IMUL:
                 begin
@@ -751,7 +751,7 @@ implementation
                   list.concat(taicpu.op_reg_const_reg(A_SRA,dst,31,tmpreg2));
                   list.concat(taicpu.op_reg_reg(A_CMP,tmpreg1,tmpreg2));
                   ovloc.loc:=LOC_FLAGS;
-                  ovloc.resflags:=F_NE;
+                  ovloc.resflags.Init(NR_ICC,F_NE);
                 end;
             end;
           end
@@ -776,7 +776,7 @@ implementation
                   list.concat(taicpu.op_reg_reg(A_MOV,NR_Y,tmpreg1));
                   list.concat(taicpu.op_reg_reg(A_CMP,NR_G0,tmpreg1));
                   ovloc.loc:=LOC_FLAGS;
-                  ovloc.resflags:=F_NE;
+                  ovloc.resflags.Init(NR_ICC,F_NE);
                 end;
               OP_IMUL:
                 begin
@@ -786,7 +786,7 @@ implementation
                   list.concat(taicpu.op_reg_const_reg(A_SRL,dst,31,tmpreg2));
                   list.concat(taicpu.op_reg_reg(A_CMP,tmpreg1,tmpreg2));
                   ovloc.loc:=LOC_FLAGS;
-                  ovloc.resflags:=F_NE;
+                  ovloc.resflags.Init(NR_ICC,F_NE);
                 end;
             end;
           end
@@ -847,7 +847,18 @@ implementation
       var
         ai : taicpu;
       begin
-        ai:=Taicpu.op_sym(A_Bxx,l);
+        case f.FlagReg of
+{$ifdef SPARC64}
+          NR_XCC:
+            ai:=Taicpu.op_reg_sym(A_Bxx,f.FlagReg,l);
+{$endif SPARC64}
+          NR_ICC:
+            ai:=Taicpu.op_sym(A_Bxx,l);
+          NR_FCC0:
+            ai:=Taicpu.op_sym(A_FBxx,l);
+          NR_FCC1,NR_FCC2,NR_FCC3:
+            ai:=Taicpu.op_reg_sym(A_FBxx,f.FlagReg,l);
+        end;
         ai.SetCondition(flags_to_cond(f));
         list.Concat(ai);
         { Delay slot }
@@ -858,18 +869,31 @@ implementation
     procedure TCGSparcGen.g_flags2reg(list:TAsmList;Size:TCgSize;const f:tresflags;reg:TRegister);
       var
         hl : tasmlabel;
+        ai : taicpu;
       begin
-        if (f in [F_B]) then
+        if (f.FlagReg=NR_ICC) and (f.Flags in [F_B]) then
           list.concat(taicpu.op_reg_reg_reg(A_ADDX,NR_G0,NR_G0,reg))
-        else if (f in [F_AE]) then
+        else if (f.FlagReg=NR_ICC) and (f.Flags in [F_AE]) then
           list.concat(taicpu.op_reg_const_reg(A_SUBX,NR_G0,-1,reg))
         else
           begin
-            current_asmdata.getjumplabel(hl);
-            a_load_const_reg(list,size,1,reg);
-            a_jmp_flags(list,f,hl);
-            a_load_const_reg(list,size,0,reg);
-            a_label(list,hl);
+            if current_settings.cputype in [cpu_SPARC_V9] then
+              begin
+                ai:=Taicpu.op_reg_const_reg(A_MOVcc,f.FlagReg,0,reg);
+                ai.SetCondition(inverse_cond(flags_to_cond(f)));
+                list.Concat(ai);
+                ai:=Taicpu.op_reg_const_reg(A_MOVcc,f.FlagReg,1,reg);
+                ai.SetCondition(flags_to_cond(f));
+                list.Concat(ai);
+              end
+            else
+              begin
+                current_asmdata.getjumplabel(hl);
+                a_load_const_reg(list,size,1,reg);
+                a_jmp_flags(list,f,hl);
+                a_load_const_reg(list,size,0,reg);
+                a_label(list,hl);
+              end;
           end;
       end;
 

+ 41 - 26
compiler/sparcgen/cpubase.pas

@@ -23,6 +23,8 @@ unit cpubase;
 
 {$i fpcdefs.inc}
 
+{$ModeSwitch advancedrecords}
+
 interface
 
 uses
@@ -167,26 +169,32 @@ uses
 *****************************************************************************}
 
     type
-      TResFlags=(
-        { Integer results }
-        F_E,  {Equal}
-        F_NE, {Not Equal}
-        F_G,  {Greater}
-        F_L,  {Less}
-        F_GE, {Greater or Equal}
-        F_LE, {Less or Equal}
-        F_A,  {Above}
-        F_AE, {Above or Equal, synonym: Carry Clear}
-        F_B,  {Below, synonym: Carry Set}
-        F_BE, {Below or Equal}
-        { Floating point results }
-        F_FE,  {Equal}
-        F_FNE, {Not Equal}
-        F_FG,  {Greater}
-        F_FL,  {Less}
-        F_FGE, {Greater or Equal}
-        F_FLE  {Less or Equal}
-      );
+        TSparcFlags = (
+          { Integer results }
+          F_E,  {Equal}
+          F_NE, {Not Equal}
+          F_G,  {Greater}
+          F_L,  {Less}
+          F_GE, {Greater or Equal}
+          F_LE, {Less or Equal}
+          F_A,  {Above}
+          F_AE, {Above or Equal, synonym: Carry Clear}
+          F_B,  {Below, synonym: Carry Set}
+          F_BE, {Below or Equal}
+          { Floating point results }
+          F_FE,  {Equal}
+          F_FNE, {Not Equal}
+          F_FG,  {Greater}
+          F_FL,  {Less}
+          F_FGE, {Greater or Equal}
+          F_FLE  {Less or Equal}
+          );
+      TResFlags = record
+        { either icc or xcc (64 bit }
+        FlagReg : TRegister;
+        Flags : TSparcFlags;
+        procedure Init(r : TRegister;f : TSparcFlags);
+      end;
 
 {*****************************************************************************
                                 Operand Sizes
@@ -212,8 +220,6 @@ uses
       fpuvarregs : Array [1..maxfpuvarregs] of TsuperRegister =
                 (RS_F2);
 
-
-
 {*****************************************************************************
                           Default generic sizes
 *****************************************************************************}
@@ -395,21 +401,21 @@ implementation
 
     procedure inverse_flags(var f: TResFlags);
       const
-        inv_flags: array[TResFlags] of TResFlags =
+        inv_flags: array[TSparcFlags] of TSparcFlags =
           (F_NE,F_E,F_LE,F_GE,F_L,F_G,F_BE,F_B,F_AE,F_A,
            F_FNE,F_FE,F_FLE,F_FGE,F_FL,F_FG);
       begin
-        f:=inv_flags[f];
+        f.Flags:=inv_flags[f.Flags];
       end;
 
 
    function flags_to_cond(const f:TResFlags):TAsmCond;
       const
-        flags_2_cond:array[TResFlags] of TAsmCond=
+        flags_2_cond:array[TSparcFlags] of TAsmCond=
           (C_E,C_NE,C_G,C_L,C_GE,C_LE,C_A,C_AE,C_B,C_BE,
            C_FE,C_FNE,C_FG,C_FL,C_FGE,C_FLE);
       begin
-        result:=flags_2_cond[f];
+        result:=flags_2_cond[f.Flags];
       end;
 
 
@@ -516,11 +522,13 @@ implementation
         result := inverse[c];
       end;
 
+
     function conditions_equal(const c1, c2: TAsmCond): boolean; {$ifdef USEINLINE}inline;{$endif USEINLINE}
       begin
         result := c1 = c2;
       end;
 
+
     function dwarf_reg(r:tregister):shortint;
       begin
         result:=regdwarf_table[findreg_by_number(r)];
@@ -528,4 +536,11 @@ implementation
           internalerror(200603251);
       end;
 
+
+    procedure TResFlags.Init(r : TRegister; f : TSparcFlags);
+      begin
+        FlagReg:=r;
+        Flags:=f;
+      end;
+
 end.

+ 45 - 37
compiler/sparcgen/ncpuadd.pas

@@ -31,7 +31,7 @@ interface
     type
        tsparcaddnode = class(tcgaddnode)
        private
-          function  GetResFlags(unsigned:Boolean):TResFlags;
+          function  GetResFlags(unsigned,use64bit:Boolean):TResFlags;
           function  GetFPUResFlags:TResFlags;
        protected
           procedure second_addfloat;override;
@@ -63,39 +63,47 @@ interface
                                TSparcAddNode
 *****************************************************************************}
 
-    function TSparcAddNode.GetResFlags(unsigned:Boolean):TResFlags;
+    function TSparcAddNode.GetResFlags(unsigned,use64bit:Boolean):TResFlags;
+      var
+        flagreg : TRegister;
       begin
+{$ifdef SPARC64}
+        if use64bit then
+          flagreg:=NR_XCC
+        else
+{$endif SPARC64}
+          flagreg:=NR_ICC;
         case NodeType of
           equaln:
-            GetResFlags:=F_E;
+            GetResFlags.Init(flagreg,F_E);
           unequaln:
-            GetResFlags:=F_NE;
+            GetResFlags.Init(flagreg,F_NE);
           else
             if not(unsigned) then
               begin
                 if nf_swapped in flags then
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_G;
+                      GetResFlags.Init(flagreg,F_G);
                     lten:
-                      GetResFlags:=F_GE;
+                      GetResFlags.Init(flagreg,F_GE);
                     gtn:
-                      GetResFlags:=F_L;
+                      GetResFlags.Init(flagreg,F_L);
                     gten:
-                      GetResFlags:=F_LE;
+                      GetResFlags.Init(flagreg,F_LE);
                     else
                       internalerror(2014082010);
                   end
                 else
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_L;
+                      GetResFlags.Init(flagreg,F_L);
                     lten:
-                      GetResFlags:=F_LE;
+                      GetResFlags.Init(flagreg,F_LE);
                     gtn:
-                      GetResFlags:=F_G;
+                      GetResFlags.Init(flagreg,F_G);
                     gten:
-                      GetResFlags:=F_GE;
+                      GetResFlags.Init(flagreg,F_GE);
                     else
                       internalerror(2014082011);
                   end;
@@ -105,26 +113,26 @@ interface
                 if nf_swapped in Flags then
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_A;
+                      GetResFlags.Init(flagreg,F_A);
                     lten:
-                      GetResFlags:=F_AE;
+                      GetResFlags.Init(flagreg,F_AE);
                     gtn:
-                      GetResFlags:=F_B;
+                      GetResFlags.Init(flagreg,F_B);
                     gten:
-                      GetResFlags:=F_BE;
+                      GetResFlags.Init(flagreg,F_BE);
                     else
                       internalerror(2014082012);
                   end
                 else
                   case NodeType of
                     ltn:
-                      GetResFlags:=F_B;
+                      GetResFlags.Init(flagreg,F_B);
                     lten:
-                      GetResFlags:=F_BE;
+                      GetResFlags.Init(flagreg,F_BE);
                     gtn:
-                      GetResFlags:=F_A;
+                      GetResFlags.Init(flagreg,F_A);
                     gten:
-                      GetResFlags:=F_AE;
+                      GetResFlags.Init(flagreg,F_AE);
                     else
                       internalerror(2014082013);
                   end;
@@ -137,34 +145,34 @@ interface
       begin
         case NodeType of
           equaln:
-            result:=F_FE;
+            result.Init(NR_FCC0,F_FE);
           unequaln:
-            result:=F_FNE;
+            result.Init(NR_FCC0,F_FNE);
           else
             begin
               if nf_swapped in Flags then
                 case NodeType of
                   ltn:
-                    result:=F_FG;
+                    result.Init(NR_FCC0,F_FG);
                   lten:
-                    result:=F_FGE;
+                    result.Init(NR_FCC0,F_FGE);
                   gtn:
-                    result:=F_FL;
+                    result.Init(NR_FCC0,F_FL);
                   gten:
-                    result:=F_FLE;
+                    result.Init(NR_FCC0,F_FLE);
                   else
                     internalerror(2014082014);
                 end
               else
                 case NodeType of
                   ltn:
-                    result:=F_FL;
+                    result.Init(NR_FCC0,F_FL);
                   lten:
-                    result:=F_FLE;
+                    result.Init(NR_FCC0,F_FLE);
                   gtn:
-                    result:=F_FG;
+                    result.Init(NR_FCC0,F_FG);
                   gten:
-                    result:=F_FGE;
+                    result.Init(NR_FCC0,F_FGE);
                   else
                     internalerror(2014082015);
                 end;
@@ -268,7 +276,7 @@ interface
           current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SUBcc,left.location.register,right.location.register,NR_G0));
 
         location_reset(location,LOC_FLAGS,OS_NO);
-        location.resflags:=getresflags(true);
+        location.resflags:=getresflags(true,is_64bit(right.resultdef));
       end;
 
 
@@ -287,7 +295,7 @@ interface
           unequaln:
             begin
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SUBcc,left.location.register,right.location.register,NR_G0));
-              location.resflags:=getresflags(true);
+              location.resflags:=getresflags(true,is_64bit(right.resultdef));
             end;
           lten,
           gten:
@@ -300,7 +308,7 @@ interface
               tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,left.location.size);
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,left.location.register,right.location.register,tmpreg));
               current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SUBcc,tmpreg,right.location.register,NR_G0));
-              location.resflags:=F_E;
+              location.resflags.Init(NR_ICC,F_E);
             end;
           else
             internalerror(2012042701);
@@ -373,7 +381,7 @@ interface
 
         if (nodetype in [equaln,unequaln]) then
           begin
-            location.resflags:=getresflags(unsigned);
+            location.resflags:=getresflags(unsigned,false);
             if (right.location.loc=LOC_CONSTANT) then
               begin
                 if hi(right.location.value64)<>0 then
@@ -417,13 +425,13 @@ interface
             if (nodetype in [ltn,gten]) then
               begin
                 emit_compare(current_asmdata.CurrAsmList,left,right);
-                location.resflags:=getresflags(unsigned);
+                location.resflags:=getresflags(unsigned,false);
               end
             else if (nodetype in [lten,gtn]) then
               begin
                 emit_compare(current_asmdata.CurrAsmList,right,left);
                 toggleflag(nf_swapped);
-                location.resflags:=getresflags(unsigned);
+                location.resflags:=getresflags(unsigned,false);
                 toggleflag(nf_swapped);
               end
             else
@@ -449,7 +457,7 @@ interface
           current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_SUBcc,left.location.register,right.location.register,NR_G0));
 
         location_reset(location,LOC_FLAGS,OS_NO);
-        location.resflags:=getresflags(unsigned);
+        location.resflags:=getresflags(unsigned,is_64bit(right.resultdef));
       end;
 
     const

+ 3 - 1
compiler/sparcgen/ncpucnv.pas

@@ -142,6 +142,7 @@ implementation
         href : treference;
         hregister : tregister;
         l1,l2 : tasmlabel;
+        TempFlags : TResFlags;
 
       begin
         location_reset(location,LOC_FPUREGISTER,def_cgsize(resultdef));
@@ -167,7 +168,8 @@ implementation
             current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_FiTOd,location.register,location.register));
 
             current_asmdata.CurrAsmList.concat(Taicpu.op_reg_reg(A_CMP,hregister,NR_G0));
-            cg.a_jmp_flags(current_asmdata.CurrAsmList,F_GE,l2);
+            TempFlags.Init(NR_ICC,F_GE);
+            cg.a_jmp_flags(current_asmdata.CurrAsmList,TempFlags,l2);
 
             case tfloatdef(resultdef).floattype of
                { converting dword to s64real first and cut off at the end avoids precision loss }