Correctly identify SBYTE in the optimizer

Correctly identify SBYTE in the optimizer, *HOWEVER*, this change will
cause nuisance warnings to be issued; that will have to be fixed.
This commit is contained in:
H. Peter Anvin 2008-04-04 13:34:53 -07:00
parent 5a7976c925
commit 32cd4c2a62
5 changed files with 203 additions and 118 deletions

View file

@ -37,7 +37,7 @@
* is a signed byte rather than a word. Opcode byte follows.
* \150..\153 - an immediate dword or signed byte for operand 0..3
* \154..\157 - or 2 (s-field) into opcode byte if operand 0..3
* is a signed byte rather than a word. Opcode byte follows.
* is a signed byte rather than a dword. Opcode byte follows.
* \160..\163 - this instruction uses DREX rather than REX, with the
* OC0 field set to 0, and the dest field taken from
* operand 0..3.
@ -50,6 +50,9 @@
* \171 - placement of DREX suffix in the absence of an EA
* \2ab - a ModRM, calculated on EA in operand a, with the spare
* field equal to digit b.
* \250..\253 - same as \150..\153, except warn if the 64-bit operand
* is not equal to the truncated and sign-extended 32-bit
* operand; used for 32-bit immediates in 64-bit mode.
* \310 - indicates fixed 16-bit address size, i.e. optional 0x67.
* \311 - indicates fixed 32-bit address size, i.e. optional 0x67.
* \312 - (disassembler only) marker on LOOP, LOOPxx instructions.
@ -159,7 +162,8 @@ static void warn_overflow(int size, int64_t data)
int64_t lim = ((int64_t)1 << (size*8))-1;
if (data < ~lim || data > lim)
errfunc(ERR_WARNING | ERR_WARN_NOV, "%s data exceeds bounds", size_name(size));
errfunc(ERR_WARNING | ERR_WARN_NOV,
"%s data exceeds bounds", size_name(size));
}
}
/*
@ -756,25 +760,55 @@ int64_t insn_size(int32_t segment, int64_t offset, int bits, uint32_t cp,
return -1; /* didn't match any instruction */
}
/* check that opn[op] is a signed byte of size 16 or 32,
and return the signed value*/
static int is_sbyte(insn * ins, int op, int size)
static bool possible_sbyte(insn * ins, int op)
{
int32_t v;
int ret;
ret = !(ins->forw_ref && ins->oprs[op].opflags) && /* dead in the water on forward reference or External */
return !(ins->forw_ref && ins->oprs[op].opflags) &&
optimizing >= 0 &&
!(ins->oprs[op].type & STRICT) &&
ins->oprs[op].wrt == NO_SEG && ins->oprs[op].segment == NO_SEG;
v = ins->oprs[op].offset;
if (size == 16)
v = (int16_t)v; /* sign extend if 16 bits */
return ret && v >= -128L && v <= 127L;
}
/* check that opn[op] is a signed byte of size 16 or 32 */
static bool is_sbyte16(insn * ins, int op)
{
int16_t v;
if (!possible_sbyte(ins, op))
return false;
v = ins->oprs[op].offset;
return v >= -128 && v <= 127;
}
static bool is_sbyte32(insn * ins, int op)
{
int32_t v;
if (!possible_sbyte(ins, op))
return false;
v = ins->oprs[op].offset;
return v >= -128 && v <= 127;
}
/* check that opn[op] is a signed byte of size 32; warn if this is not
the original value when extended to 64 bits */
static bool is_sbyte64(insn * ins, int op)
{
int64_t v64;
int32_t v32;
/* dead in the water on forward reference or External */
if (!possible_sbyte(ins, op))
return false;
v64 = ins->oprs[op].offset;
v32 = (int32_t)v64;
warn_overflow(32, v64);
return v32 >= -128 && v32 <= 127;
}
static int64_t calcsize(int32_t segment, int64_t offset, int bits,
insn * ins, const char *codes)
{
@ -902,7 +936,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
case 0141:
case 0142:
case 0143:
length += is_sbyte(ins, c & 3, 16) ? 1 : 2;
length += is_sbyte16(ins, c & 3) ? 1 : 2;
break;
case 0144:
case 0145:
@ -915,7 +949,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
case 0151:
case 0152:
case 0153:
length += is_sbyte(ins, c & 3, 32) ? 1 : 4;
length += is_sbyte32(ins, c & 3) ? 1 : 4;
break;
case 0154:
case 0155:
@ -945,6 +979,12 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
break;
case 0171:
break;
case 0250:
case 0251:
case 0252:
case 0253:
length += is_sbyte64(ins, c & 3) ? 1 : 4;
break;
case 0300:
case 0301:
case 0302:
@ -1174,6 +1214,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
case 015:
case 016:
case 017:
/* XXX: warns for legitimate optimizer actions */
if (opx->offset < -128 || opx->offset > 127) {
errfunc(ERR_WARNING | ERR_WARN_NOV,
"signed byte value exceeds bounds");
@ -1383,7 +1424,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
case 0142:
case 0143:
data = opx->offset;
if (is_sbyte(ins, c & 3, 16)) {
if (is_sbyte16(ins, c & 3)) {
bytes[0] = data;
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
NO_SEG);
@ -1404,7 +1445,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
case 0147:
EMIT_REX();
bytes[0] = *codes++;
if (is_sbyte(ins, c & 3, 16))
if (is_sbyte16(ins, c & 3))
bytes[0] |= 2; /* s-bit */
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
offset++;
@ -1415,7 +1456,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
case 0152:
case 0153:
data = opx->offset;
if (is_sbyte(ins, c & 3, 32)) {
if (is_sbyte32(ins, c & 3)) {
bytes[0] = data;
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
NO_SEG);
@ -1433,7 +1474,7 @@ static void gencode(int32_t segment, int64_t offset, int bits,
case 0157:
EMIT_REX();
bytes[0] = *codes++;
if (is_sbyte(ins, c & 3, 32))
if (is_sbyte32(ins, c & 3))
bytes[0] |= 2; /* s-bit */
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
offset++;
@ -1466,6 +1507,24 @@ static void gencode(int32_t segment, int64_t offset, int bits,
offset++;
break;
case 0250:
case 0251:
case 0252:
case 0253:
data = opx->offset;
/* is_sbyte32() is right here, we have already warned */
if (is_sbyte32(ins, c & 3)) {
bytes[0] = data;
out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG,
NO_SEG);
offset++;
} else {
out(offset, segment, &data, OUT_ADDRESS, 4,
opx->segment, opx->wrt);
offset += 4;
}
break;
case 0300:
case 0301:
case 0302:
@ -1744,47 +1803,13 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
return 0;
/*
* Check that the operand flags all match up
*/
for (i = 0; i < itemp->operands; i++) {
if (itemp->opd[i] & SAME_AS) {
int j = itemp->opd[i] & ~SAME_AS;
if (instruction->oprs[i].type != instruction->oprs[j].type ||
instruction->oprs[i].basereg != instruction->oprs[j].basereg)
return 0;
} else if (itemp->opd[i] & ~instruction->oprs[i].type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ instruction->oprs[i].type) & SIZE_MASK))) {
if ((itemp->opd[i] & ~instruction->oprs[i].type & ~SIZE_MASK) ||
(instruction->oprs[i].type & SIZE_MASK))
return 0;
else
return 1;
}
}
/*
* Check operand sizes
* Process size flags
*/
if (itemp->flags & IF_ARMASK) {
memset(size, 0, sizeof size);
switch (itemp->flags & IF_ARMASK) {
case IF_AR0:
i = 0;
break;
case IF_AR1:
i = 1;
break;
case IF_AR2:
i = 2;
break;
case IF_AR3:
i = 3;
break;
default:
break; /* Shouldn't happen */
}
i = ((itemp->flags & IF_ARMASK) >> IF_ARSHFT) - 1;
switch (itemp->flags & IF_SMASK) {
case IF_SB:
size[i] = BITS8;
@ -1801,6 +1826,19 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
case IF_SO:
size[i] = BITS128;
break;
case IF_SZ:
switch (bits) {
case 16:
size[i] = BITS16;
break;
case 32:
size[i] = BITS32;
break;
case 64:
size[i] = BITS64;
break;
}
break;
default:
break;
}
@ -1809,23 +1847,31 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
switch (itemp->flags & IF_SMASK) {
case IF_SB:
asize = BITS8;
oprs = itemp->operands;
break;
case IF_SW:
asize = BITS16;
oprs = itemp->operands;
break;
case IF_SD:
asize = BITS32;
oprs = itemp->operands;
break;
case IF_SQ:
asize = BITS64;
oprs = itemp->operands;
break;
case IF_SO:
asize = BITS128;
oprs = itemp->operands;
break;
case IF_SZ:
switch (bits) {
case 16:
asize = BITS16;
break;
case 32:
asize = BITS32;
break;
case 64:
asize = BITS64;
break;
}
break;
default:
break;
@ -1834,6 +1880,33 @@ static int matches(const struct itemplate *itemp, insn * instruction, int bits)
size[i] = asize;
}
/*
* Check that the operand flags all match up
*/
for (i = 0; i < itemp->operands; i++) {
int32_t type = instruction->oprs[i].type;
if (!(type & SIZE_MASK))
type |= size[i];
if (itemp->opd[i] & SAME_AS) {
int j = itemp->opd[i] & ~SAME_AS;
if (type != instruction->oprs[j].type ||
instruction->oprs[i].basereg != instruction->oprs[j].basereg)
return 0;
} else if (itemp->opd[i] & ~type ||
((itemp->opd[i] & SIZE_MASK) &&
((itemp->opd[i] ^ type) & SIZE_MASK))) {
if ((itemp->opd[i] & ~type & ~SIZE_MASK) ||
(type & SIZE_MASK))
return 0;
else
return 1;
}
}
/*
* Check operand sizes
*/
if (itemp->flags & (IF_SM | IF_SM2)) {
oprs = (itemp->flags & IF_SM2 ? 2 : itemp->operands);
asize = 0;

View file

@ -59,16 +59,16 @@ ADC rm16,imm8 \320\1\x83\202\15 8086
ADC rm32,imm8 \321\1\x83\202\15 386
ADC rm64,imm8 \324\1\x83\202\15 X64
ADC reg_al,imm \1\x14\21 8086,SM
ADC reg_ax,sbyte \320\1\x83\202\15 8086,SM,ND
ADC reg_ax,sbyte16 \320\1\x83\202\15 8086,SM,ND
ADC reg_ax,imm \320\1\x15\31 8086,SM
ADC reg_eax,sbyte \321\1\x83\202\15 386,SM,ND
ADC reg_eax,sbyte32 \321\1\x83\202\15 386,SM,ND
ADC reg_eax,imm \321\1\x15\41 386,SM
ADC reg_rax,sbyte \324\1\x83\202\15 X64,SM,ND
ADC reg_rax,sbyte64 \324\1\x83\202\15 X64,SM,ND
ADC reg_rax,imm \324\1\x15\41 X64,SM
ADC rm8,imm \1\x80\202\21 8086,SM
ADC rm16,imm \320\145\x81\202\141 8086,SM
ADC rm32,imm \321\155\x81\202\151 386,SM
ADC rm64,imm \324\155\x81\202\151 X64,SM
ADC rm64,imm \324\155\x81\202\251 X64,SM
ADC mem,imm8 \1\x80\202\21 8086,SM
ADC mem,imm16 \320\145\x81\202\141 8086,SM
ADC mem,imm32 \321\155\x81\202\151 386,SM
@ -92,16 +92,16 @@ ADD rm16,imm8 \320\1\x83\200\15 8086
ADD rm32,imm8 \321\1\x83\200\15 386
ADD rm64,imm8 \324\1\x83\200\15 X64
ADD reg_al,imm \1\x04\21 8086,SM
ADD reg_ax,sbyte \320\1\x83\200\15 8086,SM,ND
ADD reg_ax,sbyte16 \320\1\x83\200\15 8086,SM,ND
ADD reg_ax,imm \320\1\x05\31 8086,SM
ADD reg_eax,sbyte \321\1\x83\200\15 386,SM,ND
ADD reg_eax,sbyte32 \321\1\x83\200\15 386,SM,ND
ADD reg_eax,imm \321\1\x05\41 386,SM
ADD reg_rax,sbyte \324\1\x83\200\15 X64,SM,ND
ADD reg_rax,sbyte64 \324\1\x83\200\15 X64,SM,ND
ADD reg_rax,imm \324\1\x05\41 X64,SM
ADD rm8,imm \1\x80\200\21 8086,SM
ADD rm16,imm \320\145\x81\200\141 8086,SM
ADD rm32,imm \321\155\x81\200\151 386,SM
ADD rm64,imm \324\155\x81\200\151 X64,SM
ADD rm64,imm \324\155\x81\200\251 X64,SM
ADD mem,imm8 \1\x80\200\21 8086,SM
ADD mem,imm16 \320\145\x81\200\141 8086,SM
ADD mem,imm32 \321\155\x81\200\151 386,SM
@ -125,16 +125,16 @@ AND rm16,imm8 \320\1\x83\204\15 8086
AND rm32,imm8 \321\1\x83\204\15 386
AND rm64,imm8 \324\1\x83\204\15 X64
AND reg_al,imm \1\x24\21 8086,SM
AND reg_ax,sbyte \320\1\x83\204\15 8086,SM,ND
AND reg_ax,sbyte16 \320\1\x83\204\15 8086,SM,ND
AND reg_ax,imm \320\1\x25\31 8086,SM
AND reg_eax,sbyte \321\1\x83\204\15 386,SM,ND
AND reg_eax,sbyte32 \321\1\x83\204\15 386,SM,ND
AND reg_eax,imm \321\1\x25\41 386,SM
AND reg_rax,sbyte \324\1\x83\204\15 X64,SM,ND
AND reg_rax,sbyte64 \324\1\x83\204\15 X64,SM,ND
AND reg_rax,imm \324\1\x25\41 X64,SM
AND rm8,imm \1\x80\204\21 8086,SM
AND rm16,imm \320\145\x81\204\141 8086,SM
AND rm32,imm \321\155\x81\204\151 386,SM
AND rm64,imm \324\155\x81\204\151 X64,SM
AND rm64,imm \324\155\x81\204\251 X64,SM
AND mem,imm8 \1\x80\204\21 8086,SM
AND mem,imm16 \320\145\x81\204\141 8086,SM
AND mem,imm32 \321\155\x81\204\151 386,SM
@ -251,16 +251,16 @@ CMP rm16,imm8 \320\1\x83\207\15 8086
CMP rm32,imm8 \321\1\x83\207\15 386
CMP rm64,imm8 \324\1\x83\207\15 X64
CMP reg_al,imm \1\x3C\21 8086,SM
CMP reg_ax,sbyte \320\1\x83\207\15 8086,SM,ND
CMP reg_ax,sbyte16 \320\1\x83\207\15 8086,SM,ND
CMP reg_ax,imm \320\1\x3D\31 8086,SM
CMP reg_eax,sbyte \321\1\x83\207\15 386,SM,ND
CMP reg_eax,sbyte32 \321\1\x83\207\15 386,SM,ND
CMP reg_eax,imm \321\1\x3D\41 386,SM
CMP reg_rax,sbyte \324\1\x83\207\15 X64,SM,ND
CMP reg_rax,sbyte64 \324\1\x83\207\15 X64,SM,ND
CMP reg_rax,imm \324\1\x3D\41 X64,SM
CMP rm8,imm \1\x80\207\21 8086,SM
CMP rm16,imm \320\145\x81\207\141 8086,SM
CMP rm32,imm \321\155\x81\207\151 386,SM
CMP rm64,imm \324\155\x81\207\151 X64,SM
CMP rm64,imm \324\155\x81\207\251 X64,SM
CMP mem,imm8 \1\x80\207\21 8086,SM
CMP mem,imm16 \320\145\x81\207\141 8086,SM
CMP mem,imm32 \321\155\x81\207\151 386,SM
@ -546,40 +546,40 @@ IMUL reg32,reg32 \321\2\x0F\xAF\110 386
IMUL reg64,mem \324\2\x0F\xAF\110 X64,SM
IMUL reg64,reg64 \324\2\x0F\xAF\110 X64
IMUL reg16,mem,imm8 \320\1\x6B\110\16 186,SM
IMUL reg16,mem,sbyte \320\1\x6B\110\16 186,SM,ND
IMUL reg16,mem,sbyte16 \320\1\x6B\110\16 186,SM,ND
IMUL reg16,mem,imm16 \320\1\x69\110\32 186,SM
IMUL reg16,mem,imm \320\146\x69\110\142 186,SM,ND
IMUL reg16,reg16,imm8 \320\1\x6B\110\16 186
IMUL reg16,reg16,sbyte \320\1\x6B\110\16 186,SM,ND
IMUL reg16,reg16,sbyte32 \320\1\x6B\110\16 186,SM,ND
IMUL reg16,reg16,imm16 \320\1\x69\110\32 186
IMUL reg16,reg16,imm \320\146\x69\110\142 186,SM,ND
IMUL reg32,mem,imm8 \321\1\x6B\110\16 386,SM
IMUL reg32,mem,sbyte \321\1\x6B\110\16 386,SM,ND
IMUL reg32,mem,sbyte64 \321\1\x6B\110\16 386,SM,ND
IMUL reg32,mem,imm32 \321\1\x69\110\42 386,SM
IMUL reg32,mem,imm \321\156\x69\110\152 386,SM,ND
IMUL reg32,reg32,imm8 \321\1\x6B\110\16 386
IMUL reg32,reg32,sbyte \321\1\x6B\110\16 386,SM,ND
IMUL reg32,reg32,sbyte16 \321\1\x6B\110\16 386,SM,ND
IMUL reg32,reg32,imm32 \321\1\x69\110\42 386
IMUL reg32,reg32,imm \321\156\x69\110\152 386,SM,ND
IMUL reg64,mem,imm8 \324\1\x6B\110\16 X64,SM
IMUL reg64,mem,sbyte \324\1\x6B\110\16 X64,SM,ND
IMUL reg64,mem,sbyte32 \324\1\x6B\110\16 X64,SM,ND
IMUL reg64,mem,imm32 \324\1\x69\110\42 X64,SM
IMUL reg64,mem,imm \324\156\x69\110\152 X64,SM,ND
IMUL reg64,mem,imm \324\156\x69\110\252 X64,SM,ND
IMUL reg64,reg64,imm8 \324\1\x6B\110\16 X64
IMUL reg64,reg64,sbyte \324\1\x6B\110\16 X64,SM,ND
IMUL reg64,reg64,sbyte64 \324\1\x6B\110\16 X64,SM,ND
IMUL reg64,reg64,imm32 \324\1\x69\110\42 X64
IMUL reg64,reg64,imm \324\156\x69\110\152 X64,SM,ND
IMUL reg64,reg64,imm \324\156\x69\110\252 X64,SM,ND
IMUL reg16,imm8 \320\1\x6B\100\15 186
IMUL reg16,sbyte \320\1\x6B\100\15 186,SM,ND
IMUL reg16,sbyte16 \320\1\x6B\100\15 186,SM,ND
IMUL reg16,imm16 \320\1\x69\100\31 186
IMUL reg16,imm \320\145\x69\100\141 186,SM,ND
IMUL reg32,imm8 \321\1\x6B\100\15 386
IMUL reg32,sbyte \321\1\x6B\100\15 386,SM,ND
IMUL reg32,sbyte32 \321\1\x6B\100\15 386,SM,ND
IMUL reg32,imm32 \321\1\x69\100\41 386
IMUL reg32,imm \321\155\x69\100\151 386,SM,ND
IMUL reg64,sbyte \324\1\x6B\100\15 X64,SM,ND
IMUL reg64,sbyte64 \324\1\x6B\100\15 X64,SM,ND
IMUL reg64,imm32 \324\1\x69\100\41 X64
IMUL reg64,imm \324\155\x69\100\151 X64,SM,ND
IMUL reg64,imm \324\155\x69\100\251 X64,SM,ND
IN reg_al,imm \1\xE4\25 8086,SB
IN reg_ax,imm \320\1\xE5\25 8086,SB
IN reg_eax,imm \321\1\xE5\25 386,SB
@ -849,16 +849,16 @@ OR rm16,imm8 \320\1\x83\201\15 8086
OR rm32,imm8 \321\1\x83\201\15 386
OR rm64,imm8 \324\1\x83\201\15 X64
OR reg_al,imm \1\x0C\21 8086,SM
OR reg_ax,sbyte \320\1\x83\201\15 8086,SM,ND
OR reg_ax,sbyte16 \320\1\x83\201\15 8086,SM,ND
OR reg_ax,imm \320\1\x0D\31 8086,SM
OR reg_eax,sbyte \321\1\x83\201\15 386,SM,ND
OR reg_eax,sbyte32 \321\1\x83\201\15 386,SM,ND
OR reg_eax,imm \321\1\x0D\41 386,SM
OR reg_rax,sbyte \324\1\x83\201\15 X64,SM,ND
OR reg_rax,sbyte64 \324\1\x83\201\15 X64,SM,ND
OR reg_rax,imm \324\1\x0D\41 X64,SM
OR rm8,imm \1\x80\201\21 8086,SM
OR rm16,imm \320\145\x81\201\141 8086,SM
OR rm32,imm \321\155\x81\201\151 386,SM
OR rm64,imm \324\155\x81\201\151 X64,SM
OR rm64,imm \324\155\x81\201\251 X64,SM
OR mem,imm8 \1\x80\201\21 8086,SM
OR mem,imm16 \320\145\x81\201\141 8086,SM
OR mem,imm32 \321\155\x81\201\151 386,SM
@ -982,11 +982,10 @@ PUSH reg_cs \6 8086,NOLONG
PUSH reg_dess \6 8086,NOLONG
PUSH reg_fsgs \1\x0F\7 386
PUSH imm8 \1\x6A\14 186
PUSH sbyte \1\x6A\14 186,ND
PUSH imm16 \320\144\x68\140 186
PUSH imm32 \321\154\x68\150 386,NOLONG
PUSH imm64 \321\154\x68\150 X64
PUSH imm \1\x68\34 186
PUSH imm16 \320\144\x68\140 186,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,AR0,SZ
PUSH imm32 \321\154\x68\150 386,NOLONG,SD
PUSH imm64 \323\154\x68\250 X64,AR0,SZ
PUSHA void \322\1\x60 186,NOLONG
PUSHAD void \321\1\x60 386,NOLONG
PUSHAW void \320\1\x60 186,NOLONG
@ -1105,16 +1104,16 @@ SBB rm16,imm8 \320\1\x83\203\15 8086
SBB rm32,imm8 \321\1\x83\203\15 386
SBB rm64,imm8 \324\1\x83\203\15 X64
SBB reg_al,imm \1\x1C\21 8086,SM
SBB reg_ax,sbyte \320\1\x83\203\15 8086,SM,ND
SBB reg_ax,sbyte16 \320\1\x83\203\15 8086,SM,ND
SBB reg_ax,imm \320\1\x1D\31 8086,SM
SBB reg_eax,sbyte \321\1\x83\203\15 386,SM,ND
SBB reg_eax,sbyte32 \321\1\x83\203\15 386,SM,ND
SBB reg_eax,imm \321\1\x1D\41 386,SM
SBB reg_rax,sbyte \324\1\x83\203\15 X64,SM,ND
SBB reg_rax,sbyte64 \324\1\x83\203\15 X64,SM,ND
SBB reg_rax,imm \324\1\x1D\41 X64,SM
SBB rm8,imm \1\x80\203\21 8086,SM
SBB rm16,imm \320\145\x81\203\141 8086,SM
SBB rm32,imm \321\155\x81\203\151 386,SM
SBB rm64,imm \324\155\x81\203\151 X64,SM
SBB rm64,imm \324\155\x81\203\251 X64,SM
SBB mem,imm8 \1\x80\203\21 8086,SM
SBB mem,imm16 \320\145\x81\203\141 8086,SM
SBB mem,imm32 \321\155\x81\203\151 386,SM
@ -1219,16 +1218,16 @@ SUB rm16,imm8 \320\1\x83\205\15 8086
SUB rm32,imm8 \321\1\x83\205\15 386
SUB rm64,imm8 \324\1\x83\205\15 X64
SUB reg_al,imm \1\x2C\21 8086,SM
SUB reg_ax,sbyte \320\1\x83\205\15 8086,SM,ND
SUB reg_ax,sbyte16 \320\1\x83\205\15 8086,SM,ND
SUB reg_ax,imm \320\1\x2D\31 8086,SM
SUB reg_eax,sbyte \321\1\x83\205\15 386,SM,ND
SUB reg_eax,sbyte32 \321\1\x83\205\15 386,SM,ND
SUB reg_eax,imm \321\1\x2D\41 386,SM
SUB reg_rax,sbyte \324\1\x83\205\15 X64,SM,ND
SUB reg_rax,sbyte64 \324\1\x83\205\15 X64,SM,ND
SUB reg_rax,imm \324\1\x2D\41 X64,SM
SUB rm8,imm \1\x80\205\21 8086,SM
SUB rm16,imm \320\145\x81\205\141 8086,SM
SUB rm32,imm \321\155\x81\205\151 386,SM
SUB rm64,imm \324\155\x81\205\151 X64,SM
SUB rm64,imm \324\155\x81\205\251 X64,SM
SUB mem,imm8 \1\x80\205\21 8086,SM
SUB mem,imm16 \320\145\x81\205\141 8086,SM
SUB mem,imm32 \321\155\x81\205\151 386,SM
@ -1348,16 +1347,16 @@ XOR rm16,imm8 \320\1\x83\206\15 8086
XOR rm32,imm8 \321\1\x83\206\15 386
XOR rm64,imm8 \324\1\x83\206\15 X64
XOR reg_al,imm \1\x34\21 8086,SM
XOR reg_ax,sbyte \320\1\x83\206\15 8086,SM,ND
XOR reg_ax,sbyte16 \320\1\x83\206\15 8086,SM,ND
XOR reg_ax,imm \320\1\x35\31 8086,SM
XOR reg_eax,sbyte \321\1\x83\206\15 386,SM,ND
XOR reg_eax,sbyte32 \321\1\x83\206\15 386,SM,ND
XOR reg_eax,imm \321\1\x35\41 386,SM
XOR reg_rax,sbyte \324\1\x83\206\15 X64,SM,ND
XOR reg_rax,sbyte64 \324\1\x83\206\15 X64,SM,ND
XOR reg_rax,imm \324\1\x35\41 X64,SM
XOR rm8,imm \1\x80\206\21 8086,SM
XOR rm16,imm \320\145\x81\206\141 8086,SM
XOR rm32,imm \321\155\x81\206\151 386,SM
XOR rm64,imm \324\155\x81\206\151 X64,SM
XOR rm64,imm \324\155\x81\206\251 X64,SM
XOR mem,imm8 \1\x80\206\21 8086,SM
XOR mem,imm16 \320\145\x81\206\141 8086,SM
XOR mem,imm32 \321\155\x81\206\151 386,SM

View file

@ -72,12 +72,14 @@ extern const struct disasm_index itable[256];
#define IF_SD 0x0000000CUL /* unsized operands can't be non-dword */
#define IF_SQ 0x00000010UL /* unsized operands can't be non-qword */
#define IF_SO 0x00000014UL /* unsized operands can't be non-oword */
#define IF_SZ 0x00000018UL /* unsized operands must match the bitsize */
#define IF_SMASK 0x0000001CUL /* mask for unsized argument size */
#define IF_AR0 0x00000020UL /* SB, SW, SD applies to argument 0 */
#define IF_AR1 0x00000040UL /* SB, SW, SD applies to argument 1 */
#define IF_AR2 0x00000060UL /* SB, SW, SD applies to argument 2 */
#define IF_AR3 0x00000080UL /* SB, SW, SD applies to argument 2 */
#define IF_AR3 0x00000080UL /* SB, SW, SD applies to argument 3 */
#define IF_ARMASK 0x000000E0UL /* mask for unsized argument spec */
#define IF_ARSHFT 5 /* LSB in IF_ARMASK */
#define IF_PRIV 0x00000100UL /* it's a privileged instruction */
#define IF_SMM 0x00000200UL /* it's only valid in SMM */
#define IF_PROT 0x00000400UL /* it's protected mode only */

8
nasm.h
View file

@ -428,7 +428,9 @@ enum {
*
* With IMMEDIATE:
* 16: UNITY (1)
* 17: BYTENESS (-128..127)
* 17: BYTENESS16 (-128..127)
* 18: BYTENESS32 (-128..127)
* 19: BYTENESS64 (-128..127)
*
* Bits 20-26: register classes
* 20: REG_CDT (CRx, DRx, TRx)
@ -539,7 +541,9 @@ typedef uint32_t opflags_t;
/* special type of immediate operand */
#define UNITY 0x00012000U /* for shift/rotate instructions */
#define SBYTE 0x00022000U /* for op r16/32,immediate instrs. */
#define SBYTE16 0x00022000U /* for op r16,immediate instrs. */
#define SBYTE32 0x00042000U /* for op r32,immediate instrs. */
#define SBYTE64 0x00082000U /* for op r64,immediate instrs. */
/* special flags */
#define SAME_AS 0x40000000U

View file

@ -797,9 +797,16 @@ restart_parse:
result->oprs[operand].type |= UNITY;
if (optimizing >= 0 &&
!(result->oprs[operand].type & STRICT)) {
if (reloc_value(value) >= -128 &&
reloc_value(value) <= 127)
result->oprs[operand].type |= SBYTE;
int64_t v64 = reloc_value(value);
int32_t v32 = (int32_t)v64;
int16_t v16 = (int16_t)v32;
if (v64 >= -128 && v64 <= 127)
result->oprs[operand].type |= SBYTE64;
if (v32 >= -128 && v32 <= 127)
result->oprs[operand].type |= SBYTE32;
if (v16 >= -128 && v16 <= 127)
result->oprs[operand].type |= SBYTE16;
}
}
} else { /* it's a register */