Browse Source

* correctly calculate the bit mask in thlcgobj.a_load_regconst_subsetreg_intern, resolves #31042
* convert immediates on x86 always to 32 (x86-64, i386) or 16 bit (i8086) signed values

git-svn-id: trunk@35082 -

florian 8 years ago
parent
commit
1e374df5b8
3 changed files with 17 additions and 4 deletions
  1. 8 1
      compiler/hlcgobj.pas
  2. 3 3
      compiler/x86/cgx86.pas
  3. 6 0
      compiler/x86/cpubase.pas

+ 8 - 1
compiler/hlcgobj.pas

@@ -2384,11 +2384,18 @@ implementation
            if (slopt<>SL_REGNOSRCMASK) then
             a_op_const_reg(list,OP_AND,subsetregdef,tcgint(not(bitmask)),tmpreg);
         end;
+
       if (slopt<>SL_SETMAX) and
       { the "and" is not needed if the whole register is modified (except for SL_SETZERO),
         because later on we do a move in this case instead of an or }
         ((sreg.bitlen<>AIntBits) or (slopt=SL_SETZERO)) then
-        a_op_const_reg(list,OP_AND,subsetregdef,tcgint(bitmask),sreg.subsetreg);
+          begin
+            { shl could wrap around in this case }
+            if subsetregdef.size=sizeof(aword) then
+              a_op_const_reg(list,OP_AND,subsetregdef,tcgint(bitmask),sreg.subsetreg)
+            else
+              a_op_const_reg(list,OP_AND,subsetregdef,tcgint(bitmask) and aword((aword(1) shl (subsetregdef.size*8))-1),sreg.subsetreg);
+          end;
 
       case slopt of
         SL_SETZERO : ;

+ 3 - 3
compiler/x86/cgx86.pas

@@ -1823,16 +1823,16 @@ unit cgx86;
                   list.concat(taicpu.op_reg(A_DEC,TCgSize2OpSize[size],reg))
               end
             else
-              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],aint(a),reg));
+              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],ImmInt(a),reg));
 
           OP_AND,OP_OR:
-            list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],aint(a),reg));
+            list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],ImmInt(a),reg));
 
           OP_XOR:
             if (aword(a)=high(aword)) then
               list.concat(taicpu.op_reg(A_NOT,TCgSize2OpSize[size],reg))
             else
-              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],aint(a),reg));
+              list.concat(taicpu.op_const_reg(TOpCG2AsmOp[op],TCgSize2OpSize[size],ImmInt(a),reg));
 
           OP_SHL,OP_SHR,OP_SAR,OP_ROL,OP_ROR:
             begin

+ 6 - 0
compiler/x86/cpubase.pas

@@ -56,6 +56,12 @@ uses
       { This should define the array of instructions as string }
         op2strtable=array[tasmop] of string[16];
 
+{$ifdef i8086}
+      ImmInt = ShortInt;
+{$else i8086}
+      ImmInt = Longint;
+{$endif i8086}
+
     const
       { First value of opcode enumeration }
       firstop = low(tasmop);