diff --git a/assemble.c b/assemble.c
index 681af69..60fe369 100644
--- a/assemble.c
+++ b/assemble.c
@@ -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;
diff --git a/insns.dat b/insns.dat
index 77f7739..2302703 100644
--- a/insns.dat
+++ b/insns.dat
@@ -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
@@ -227,7 +227,6 @@ CDQ		void			\321\1\x99			386
 CDQE		void			\324\1\x98			X64
 CLC		void			\1\xF8				8086
 CLD		void			\1\xFC				8086
-CLFLUSH		mem			\2\x0F\xAE\207			KATMAI
 CLGI		void			\3\x0F\x01\xDD			X64,AMD
 CLI		void			\1\xFA				8086
 CLTS		void			\2\x0F\x06			286,PRIV
@@ -252,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
@@ -547,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
@@ -850,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
@@ -983,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
@@ -1106,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
@@ -1220,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
@@ -1349,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
diff --git a/insns.h b/insns.h
index 3fefa45..49cc185 100644
--- a/insns.h
+++ b/insns.h
@@ -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 */
diff --git a/nasm.h b/nasm.h
index b2c1e93..2591b1c 100644
--- a/nasm.h
+++ b/nasm.h
@@ -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
diff --git a/parser.c b/parser.c
index 6e6a052..8ec6061 100644
--- a/parser.c
+++ b/parser.c
@@ -796,9 +796,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 */
