Browse Source

* x86 and SPARC: fixed handling 64-bit (qwordbool) values in tcgnotnode (partial fix for Mantis #25255).
* Moved handling LOC_JUMP locations to helper method of base class, it appears to be the same for all targets.

git-svn-id: trunk@26353 -

sergei 11 years ago
parent
commit
36d0c8a5a7
3 changed files with 67 additions and 46 deletions
  1. 29 1
      compiler/ncgmat.pas
  2. 6 23
      compiler/sparc/ncpumat.pas
  3. 32 22
      compiler/x86/nx86mat.pas

+ 29 - 1
compiler/ncgmat.pas

@@ -109,6 +109,7 @@ interface
 
 
       tcgnotnode = class(tnotnode)
       tcgnotnode = class(tnotnode)
       protected
       protected
+         function handle_locjump: boolean;
          procedure second_boolean;virtual;abstract;
          procedure second_boolean;virtual;abstract;
 {$ifdef SUPPORT_MMX}
 {$ifdef SUPPORT_MMX}
          procedure second_mmx;virtual;abstract;
          procedure second_mmx;virtual;abstract;
@@ -131,7 +132,7 @@ implementation
       parabase,
       parabase,
       pass_2,
       pass_2,
       ncon,
       ncon,
-      tgobj,ncgutil,cgobj,cgutils,paramgr,hlcgobj
+      tgobj,ncgutil,cgobj,cgutils,paramgr,hlcgobj,procinfo
 {$ifndef cpu64bitalu}
 {$ifndef cpu64bitalu}
       ,cg64f32
       ,cg64f32
 {$endif not cpu64bitalu}
 {$endif not cpu64bitalu}
@@ -557,6 +558,33 @@ implementation
       end;
       end;
 
 
 
 
+    function tcgnotnode.handle_locjump: boolean;
+      var
+        hl: tasmlabel;
+      begin
+        result:=(left.expectloc=LOC_JUMP);
+        if result then
+          begin
+            hl:=current_procinfo.CurrTrueLabel;
+            current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
+            current_procinfo.CurrFalseLabel:=hl;
+            secondpass(left);
+
+            if is_constboolnode(left) then
+              internalerror(2014010101);
+            if left.location.loc<>LOC_JUMP then
+              internalerror(2012081306);
+
+            { This does nothing for LOC_JUMP }
+            //maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
+            hl:=current_procinfo.CurrTrueLabel;
+            current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
+            current_procinfo.CurrFalseLabel:=hl;
+            location_reset(location,LOC_JUMP,OS_NO);
+          end;
+      end;
+
+
     procedure tcgnotnode.pass_generate_code;
     procedure tcgnotnode.pass_generate_code;
       begin
       begin
         if is_boolean(resultdef) then
         if is_boolean(resultdef) then

+ 6 - 23
compiler/sparc/ncpumat.pas

@@ -253,29 +253,8 @@ implementation
 *****************************************************************************}
 *****************************************************************************}
 
 
     procedure tsparcnotnode.second_boolean;
     procedure tsparcnotnode.second_boolean;
-      var
-        hl : tasmlabel;
       begin
       begin
-        { if the location is LOC_JUMP, we do the secondpass after the
-          labels are allocated
-        }
-        if left.expectloc=LOC_JUMP then
-          begin
-            hl:=current_procinfo.CurrTrueLabel;
-            current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
-            current_procinfo.CurrFalseLabel:=hl;
-            secondpass(left);
-
-            if left.location.loc<>LOC_JUMP then
-              internalerror(2012081306);
-
-            maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
-            hl:=current_procinfo.CurrTrueLabel;
-            current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
-            current_procinfo.CurrFalseLabel:=hl;
-            location.loc:=LOC_JUMP;
-          end
-        else
+        if not handle_locjump then
           begin
           begin
             secondpass(left);
             secondpass(left);
             case left.location.loc of
             case left.location.loc of
@@ -290,7 +269,11 @@ implementation
               LOC_SUBSETREF, LOC_CSUBSETREF:
               LOC_SUBSETREF, LOC_CSUBSETREF:
                 begin
                 begin
                   hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
                   hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,left.resultdef,true);
-                  current_asmdata.CurrAsmList.concat(taicpu.op_reg_const_reg(A_SUBcc,left.location.register,0,NR_G0));
+                  if is_64bit(left.resultdef) then
+                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_ORcc,
+                      left.location.register64.reglo,left.location.register64.reghi,NR_G0))
+                  else
+                    current_asmdata.CurrAsmList.concat(taicpu.op_reg_const_reg(A_SUBcc,left.location.register,0,NR_G0));
                   location_reset(location,LOC_FLAGS,OS_NO);
                   location_reset(location,LOC_FLAGS,OS_NO);
                   location.resflags:=F_E;
                   location.resflags:=F_E;
                end;
                end;

+ 32 - 22
compiler/x86/nx86mat.pas

@@ -221,28 +221,12 @@ interface
 
 
     procedure tx86notnode.second_boolean;
     procedure tx86notnode.second_boolean;
       var
       var
-         hl : tasmlabel;
          opsize : tcgsize;
          opsize : tcgsize;
+         hreg: tregister;
       begin
       begin
         opsize:=def_cgsize(resultdef);
         opsize:=def_cgsize(resultdef);
 
 
-        if left.expectloc=LOC_JUMP then
-         begin
-           location_reset(location,LOC_JUMP,OS_NO);
-           hl:=current_procinfo.CurrTrueLabel;
-           current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
-           current_procinfo.CurrFalseLabel:=hl;
-           secondpass(left);
-
-            if left.location.loc<>LOC_JUMP then
-              internalerror(2012081307);
-
-           maketojumpbool(current_asmdata.CurrAsmList,left,lr_load_regvars);
-           hl:=current_procinfo.CurrTrueLabel;
-           current_procinfo.CurrTrueLabel:=current_procinfo.CurrFalseLabel;
-           current_procinfo.CurrFalseLabel:=hl;
-         end
-        else
+        if not handle_locjump then
          begin
          begin
            { the second pass could change the location of left }
            { the second pass could change the location of left }
            { if it is a register variable, so we've to do      }
            { if it is a register variable, so we've to do      }
@@ -255,18 +239,44 @@ interface
                  location.resflags:=left.location.resflags;
                  location.resflags:=left.location.resflags;
                  inverse_flags(location.resflags);
                  inverse_flags(location.resflags);
                end;
                end;
+             LOC_CREFERENCE,
+             LOC_REFERENCE:
+               begin
+{$ifndef cpu64bitalu}
+                 if is_64bit(resultdef) then
+                   begin
+                     hreg:=cg.GetIntRegister(current_asmdata.CurrAsmList,OS_32);
+                     tcgx86(cg).make_simple_ref(current_asmdata.CurrAsmList,left.location.reference);
+                     cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hreg);
+                     inc(left.location.reference.offset,4);
+                     cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.reference,hreg);
+                   end
+                 else
+{$endif cpu64bitalu}
+                   emit_const_ref(A_CMP, TCGSize2Opsize[opsize], 0, left.location.reference);
+                 location_reset(location,LOC_FLAGS,OS_NO);
+                 location.resflags:=F_E;
+               end;
              LOC_CONSTANT,
              LOC_CONSTANT,
              LOC_REGISTER,
              LOC_REGISTER,
              LOC_CREGISTER,
              LOC_CREGISTER,
-             LOC_REFERENCE,
-             LOC_CREFERENCE,
              LOC_SUBSETREG,
              LOC_SUBSETREG,
              LOC_CSUBSETREG,
              LOC_CSUBSETREG,
              LOC_SUBSETREF,
              LOC_SUBSETREF,
              LOC_CSUBSETREF :
              LOC_CSUBSETREF :
                begin
                begin
-                 hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
-                 emit_reg_reg(A_TEST,TCGSize2Opsize[opsize],left.location.register,left.location.register);
+{$ifndef cpu64bitalu}
+                 if is_64bit(resultdef) then
+                   begin
+                     hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,false);
+                     emit_reg_reg(A_OR,S_L,left.location.register64.reghi,left.location.register64.reglo);
+                   end
+                 else
+{$endif cpu64bitalu}
+                   begin
+                     hlcg.location_force_reg(current_asmdata.CurrAsmList,left.location,left.resultdef,resultdef,true);
+                     emit_reg_reg(A_TEST,TCGSize2Opsize[opsize],left.location.register,left.location.register);
+                   end;
                  location_reset(location,LOC_FLAGS,OS_NO);
                  location_reset(location,LOC_FLAGS,OS_NO);
                  location.resflags:=F_E;
                  location.resflags:=F_E;
                end;
                end;