Add support for register-number immediates with fixed 4-bit values
authorH. Peter Anvin <hpa@zytor.com>
Wed, 7 May 2008 03:11:14 +0000 (20:11 -0700)
committerH. Peter Anvin <hpa@zytor.com>
Wed, 7 May 2008 03:11:14 +0000 (20:11 -0700)
Add support for imm8 bytes which has a register value in the top four
bits and an arbitrary fixed value in the bottom four bits.

assemble.c
disasm.c

index 7a237a0..56a05e6 100644 (file)
@@ -50,6 +50,8 @@
  * \171                 - placement of DREX suffix in the absence of an EA
  * \172\ab      - the register number from operand a in bits 7..4, with
  *                 the 4-bit immediate from operand b in bits 0..3.
+ * \173\xab     - the register number from operand a in bits 7..4, with
+ *                the value b in bits 0..3.
  * \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
@@ -994,6 +996,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
        case 0171:
            break;
        case 0172:
+       case 0173:
            codes++;
            length++;
            break;
@@ -1590,6 +1593,15 @@ static void gencode(int32_t segment, int64_t offset, int bits,
            offset++;
            break;
 
+       case 0173:
+           c = *codes++;
+           opx = &ins->oprs[c >> 4];
+           bytes[0] = regvals[opx->basereg] << 4;
+           bytes[0] |= c & 15;
+           out(offset, segment, bytes, OUT_RAWDATA, 1, NO_SEG, NO_SEG);
+           offset++;
+           break;
+
         case 0250:
         case 0251:
         case 0252:
index a997d40..36eaf3a 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -659,6 +659,19 @@ static int matches(const struct itemplate *t, uint8_t *data,
        }
        break;
 
+       case 0173:
+       {
+           uint8_t ximm = *data++;
+           c = *r++;
+
+           if ((c ^ ximm) & 15)
+               return false;
+
+           ins->oprs[c >> 4].basereg = ximm >> 4;
+           ins->oprs[c >> 4].segment |= SEG_RMREG;
+       }
+       break;
+
        case4(0200):
        case4(0204):
        case4(0210):