* 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 -
This commit is contained in:
florian 2016-12-07 20:08:22 +00:00
parent 8173efff3e
commit 1e374df5b8
3 changed files with 17 additions and 4 deletions

View File

@ -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 : ;

View File

@ -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

View File

@ -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);