diff options
-rw-r--r-- | assemble.c | 193 | ||||
-rw-r--r-- | insns.dat | 97 | ||||
-rw-r--r-- | insns.h | 4 | ||||
-rw-r--r-- | nasm.h | 8 | ||||
-rw-r--r-- | parser.c | 13 |
5 files changed, 200 insertions, 115 deletions
@@ -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; +} + +/* 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; - if (size == 16) - v = (int16_t)v; /* sign extend if 16 bits */ + return v >= -128 && v <= 127; +} - return ret && v >= -128L && v <= 127L; +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; @@ -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 @@ -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 */ @@ -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 @@ -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 */ |