summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-02-25 10:19:56 -0800
committerH. Peter Anvin <hpa@zytor.com>2012-02-25 10:19:56 -0800
commit7849dd07b94248a696009229f97f6412781b5337 (patch)
treeb804bf575c90d9cfdf430b94a3bade6612d00129
parentb9bc63c75721a08e964b471a516c78a112c3b03a (diff)
downloadnasm-7849dd07b94248a696009229f97f6412781b5337.tar.gz
Add a "nohle" byte code to skip an instruction pattern
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>
-rw-r--r--assemble.c28
-rw-r--r--disasm.c45
-rwxr-xr-xinsns.pl7
3 files changed, 47 insertions, 33 deletions
diff --git a/assemble.c b/assemble.c
index 06fba53b..2feb62ab 100644
--- a/assemble.c
+++ b/assemble.c
@@ -74,6 +74,10 @@
* 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.
@@ -97,9 +101,6 @@
*
* 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 &&
diff --git a/disasm.c b/disasm.c
index c2a21fdc..6a61ad0e 100644
--- 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;
diff --git a/insns.pl b/insns.pl
index 69dbb777..694726c7 100755
--- 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,