Add a "nohle" byte code to skip an instruction pattern
authorH. Peter Anvin <hpa@zytor.com>
Sat, 25 Feb 2012 18:19:56 +0000 (10:19 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sat, 25 Feb 2012 18:19:56 +0000 (10:19 -0800)
The a2/a3 mem_offs MOV opcodes are invalid with XRELEASE; those
instructions instead have to use a modrm form.  Therefore give a way
to annotate those instruction patters so the pattern matcher will move
on to the next pattern, rather than selecting them and then issue a
warning.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
assemble.c
disasm.c
insns.pl

index 06fba53..2feb62a 100644 (file)
  *                 an arbitrary value in bits 3..0 (assembled as zero.)
  * \2ab          - a ModRM, calculated on EA in operand a, with the spare
  *                 field equal to digit b.
+ * \240                 - skip this instruction pattern if HLE prefixes present
+ * \241                 - instruction takes XRELEASE (F3) with or without lock
+ * \242                 - instruction takes XACQUIRE/XRELEASE with or without lock
+ * \243                 - instruction takes XACQUIRE/XRELEASE with lock only
  * \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.
  *
  * t = 0 for VEX (C4/C5), t = 1 for XOP (8F).
  *
- * \271                 - instruction takes XRELEASE (F3) with or without lock
- * \272                 - instruction takes XACQUIRE/XRELEASE with or without lock
- * \273                 - instruction takes XACQUIRE/XRELEASE with lock only
  * \274..\277    - a signed byte immediate operand, from operand 0..3,
  *                 which is to be extended to the operand size.
  * \310          - indicates fixed 16-bit address size, i.e. optional 0x67.
@@ -958,6 +959,18 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
             length++;
             break;
 
+        case 0240:
+            if (has_prefix(ins, PPS_REP, P_XACQUIRE) ||
+                has_prefix(ins, PPS_REP, P_XRELEASE))
+                return -1;
+            break;
+
+        case 0241:
+        case 0242:
+        case 0243:
+            hleok = c & 3;
+            break;
+
         case4(0250):
             length += is_sbyte32(opx) ? 1 : 4;
             break;
@@ -980,12 +993,6 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
             ins->vex_wlp = *codes++;
             break;
 
-        case 0271:
-        case 0272:
-        case 0273:
-            hleok = c & 3;
-            break;
-
         case4(0274):
             length++;
             break;
@@ -1559,6 +1566,9 @@ static void gencode(int32_t segment, int64_t offset, int bits,
             offset++;
             break;
 
+        case4(0240):
+            break;
+
         case4(0250):
             data = opx->offset;
             if (opx->wrt == NO_SEG && opx->segment == NO_SEG &&
index c2a21fd..6a61ad0 100644 (file)
--- a/disasm.c
+++ b/disasm.c
@@ -648,6 +648,30 @@ static int matches(const struct itemplate *t, uint8_t *data,
            break;
        }
 
+        case 0240:
+            break;
+
+        case 0241:
+            if (prefix->rep == 0xF3)
+                drep = P_XRELEASE;
+            break;
+
+        case 0242:
+            if (prefix->rep == 0xF2)
+                drep = P_XACQUIRE;
+            else if (prefix->rep == 0xF3)
+                drep = P_XRELEASE;
+            break;
+
+        case 0243:
+            if (prefix->lock == 0xF0) {
+                if (prefix->rep == 0xF2)
+                    drep = P_XACQUIRE;
+                else if (prefix->rep == 0xF3)
+                    drep = P_XRELEASE;
+            }
+            break;
+
        case4(0250):
            if (s_field_for == op1) {
                opx->offset = gets8(data);
@@ -703,27 +727,6 @@ static int matches(const struct itemplate *t, uint8_t *data,
            break;
        }
 
-        case 0271:
-            if (prefix->rep == 0xF3)
-                drep = P_XRELEASE;
-            break;
-
-        case 0272:
-            if (prefix->rep == 0xF2)
-                drep = P_XACQUIRE;
-            else if (prefix->rep == 0xF3)
-                drep = P_XRELEASE;
-            break;
-
-        case 0273:
-            if (prefix->lock == 0xF0) {
-                if (prefix->rep == 0xF2)
-                    drep = P_XACQUIRE;
-                else if (prefix->rep == 0xF3)
-                    drep = P_XRELEASE;
-            }
-            break;
-
        case 0310:
             if (asize != 16)
                 return false;
index 69dbb77..694726c 100755 (executable)
--- a/insns.pl
+++ b/insns.pl
@@ -707,9 +707,10 @@ sub byte_code_compile($$) {
        'repe' => 0335,
        'nohi' => 0325,         # Use spl/bpl/sil/dil even without REX
        'wait' => 0341,         # Needs a wait prefix
-       'hlexr' => 0271,
-       'hlenl' => 0272,
-       'hle' => 0273,
+       'nohle' => 0240,
+       'hlexr' => 0241,
+       'hlenl' => 0242,
+       'hle' => 0243,
        # This instruction takes XMM VSIB
        'vsibx' => 0374,
        'vm32x' => 0374,