Explorar o código

* fixed several problems with packed set operand sizes
* added LOC_CONSTANT to the list of allowed locations for the left
hand side of an in-node, so it doesn't get forced into a register
anymore in that case

git-svn-id: trunk@7831 -

Jonas Maebe %!s(int64=18) %!d(string=hai) anos
pai
achega
8caad93eaf
Modificáronse 2 ficheiros con 20 adicións e 19 borrados
  1. 6 0
      compiler/x86/nx86add.pas
  2. 14 19
      compiler/x86/nx86set.pas

+ 6 - 0
compiler/x86/nx86add.pas

@@ -209,6 +209,12 @@ unit nx86add;
               location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,(nodetype in [ltn,lten,gtn,gten,equaln,unequaln]));
             end;
           end;
+        if (right.location.loc<>LOC_CONSTANT) and
+           (tcgsize2unsigned[right.location.size]<>opsize) then
+          location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,true);
+        if (left.location.loc<>LOC_CONSTANT) and
+           (tcgsize2unsigned[left.location.size]<>opsize) then
+          location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,false);
        end;
 
 

+ 14 - 19
compiler/x86/nx86set.pas

@@ -189,7 +189,7 @@ implementation
          if is_signed(left.resultdef) then
            opsize := tcgsize(ord(opsize)+(ord(OS_S8)-ord(OS_8)));
 
-         if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE]) then
+         if not(left.location.loc in [LOC_REGISTER,LOC_CREGISTER,LOC_REFERENCE,LOC_CREFERENCE,LOC_CONSTANT]) then
            location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
          if (right.location.loc in [LOC_SUBSETREG,LOC_CSUBSETREG]) then
            location_force_reg(current_asmdata.CurrAsmList,right.location,opsize,true);
@@ -283,20 +283,20 @@ implementation
               handle smallsets separate, because it allows faster checks }
             if use_small then
              begin
-               if left.nodetype=ordconstn then
+               if left.location.loc=LOC_CONSTANT then
                 begin
                   location.resflags:=F_NE;
                   case right.location.loc of
                     LOC_REGISTER,
                     LOC_CREGISTER:
                       begin
-                         emit_const_reg(A_TEST,S_L,
-                           1 shl (tordconstnode(left).value.svalue and 31),right.location.register);
+                         emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],
+                           1 shl (left.location.value and 31),right.location.register);
                       end;
                     LOC_REFERENCE,
                     LOC_CREFERENCE :
                       begin
-                        emit_const_ref(A_TEST,S_L,1 shl (tordconstnode(left).value.svalue and 31),
+                        emit_const_ref(A_TEST,TCGSize2OpSize[right.location.size],1 shl (left.location.value and 31),
                            right.location.reference);
                       end;
                     else
@@ -306,6 +306,9 @@ implementation
                else
                 begin
                   location_force_reg(current_asmdata.CurrAsmList,left.location,OS_32,true);
+                  if (tcgsize2size[right.location.size] < 4) or
+                     (right.location.loc = LOC_CONSTANT) then
+                    location_force_reg(current_asmdata.CurrAsmList,right.location,OS_32,true);
                   hreg:=left.location.register;
 
                   case right.location.loc of
@@ -314,14 +317,6 @@ implementation
                       begin
                         emit_reg_reg(A_BT,S_L,hreg,right.location.register);
                       end;
-                     LOC_CONSTANT :
-                       begin
-                         { We have to load the value into a register because
-                            btl does not accept values only refs or regs (PFV) }
-                         hreg2:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
-                         cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_32,right.location.value,hreg2);
-                         emit_reg_reg(A_BT,S_L,hreg,hreg2);
-                       end;
                      LOC_CREFERENCE,
                      LOC_REFERENCE :
                        begin
@@ -342,7 +337,7 @@ implementation
                   current_asmdata.getjumplabel(l2);
 
                   { load constants to a register }
-                  if left.nodetype=ordconstn then
+                  if left.location.loc=LOC_CONSTANT then
                     location_force_reg(current_asmdata.CurrAsmList,left.location,opsize,true);
 
                   case left.location.loc of
@@ -383,9 +378,9 @@ implementation
                 end { of right.location.loc=LOC_CONSTANT }
                { do search in a normal set which could have >32 elementsm
                  but also used if the left side contains values > 32 or < 0 }
-               else if left.nodetype=ordconstn then
+               else if left.location.loc=LOC_CONSTANT then
                 begin
-                  if (tordconstnode(left).value.svalue<0) or ((tordconstnode(left).value.svalue shr 3) >= right.resultdef.size) then
+                  if (left.location.value<0) or ((left.location.value shr 3) >= right.resultdef.size) then
                     {should be caught earlier }
                     internalerror(2007020201);
 
@@ -393,12 +388,12 @@ implementation
                   case right.location.loc of
                     LOC_REFERENCE,LOC_CREFERENCE:
                       begin
-                        inc(right.location.reference.offset,tordconstnode(left).value.svalue shr 3);
-                        emit_const_ref(A_TEST,S_B,1 shl (tordconstnode(left).value.svalue and 7),right.location.reference);
+                        inc(right.location.reference.offset,left.location.value shr 3);
+                        emit_const_ref(A_TEST,S_B,1 shl (left.location.value and 7),right.location.reference);
                       end;
                     LOC_REGISTER,LOC_CREGISTER:
                       begin
-                        emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],1 shl (tordconstnode(left).value.svalue),right.location.register);
+                        emit_const_reg(A_TEST,TCGSize2OpSize[right.location.size],1 shl (left.location.value),right.location.register);
                       end;
                     else
                       internalerror(2007051901);