summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2012-02-25 22:22:07 -0800
committerH. Peter Anvin <hpa@zytor.com>2012-02-25 22:22:07 -0800
commitfb3f4e6ddbb00dea78cdccc71b824d829dc058de (patch)
treedff0693143ac65e803d833c8d51e6ba0d5144ae2
parentc5473121afc4025669ef4b86b99bdbfc7a46c44d (diff)
downloadnasm-fb3f4e6ddbb00dea78cdccc71b824d829dc058de.tar.gz
HLE: Change NOHLE to be an instruction flag
The way our matching system works we have to make NOHLE an instruction flag rather than an byte code; by the time we run the byte code interpreter we have already picked an instruction pattern once and for all. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--assemble.c19
-rw-r--r--disasm.c3
-rw-r--r--insns.dat8
-rw-r--r--insns.h46
-rwxr-xr-xinsns.pl1
-rw-r--r--test/hle.asm15
6 files changed, 55 insertions, 37 deletions
diff --git a/assemble.c b/assemble.c
index bf5c103f..4d8702cb 100644
--- a/assemble.c
+++ b/assemble.c
@@ -175,6 +175,7 @@ enum match_result {
MERR_OPSIZEMISMATCH,
MERR_BADCPU,
MERR_BADMODE,
+ MERR_BADHLE,
/*
* Matching success; the conditional ones first
*/
@@ -980,12 +981,6 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
ins->vex_wlp = *codes++;
break;
- case 0264:
- if (has_prefix(ins, PPS_REP, P_XACQUIRE) ||
- has_prefix(ins, PPS_REP, P_XRELEASE))
- return -1;
- break;
-
case 0265:
case 0266:
case 0267:
@@ -1629,7 +1624,9 @@ static void gencode(int32_t segment, int64_t offset, int bits,
}
break;
- case4(0264):
+ case 0265:
+ case 0266:
+ case 0267:
break;
case4(0274):
@@ -2247,6 +2244,14 @@ static enum match_result matches(const struct itemplate *itemp,
return MERR_BADMODE;
/*
+ * If we have a HLE prefix, look for the NOHLE flag
+ */
+ if ((itemp->flags & IF_NOHLE) &&
+ (has_prefix(instruction, PPS_REP, P_XACQUIRE) ||
+ has_prefix(instruction, PPS_REP, P_XRELEASE)))
+ return MERR_BADHLE;
+
+ /*
* Check if special handling needed for Jumps
*/
if ((itemp->code[0] & ~1) == 0370)
diff --git a/disasm.c b/disasm.c
index ba4b8d25..b6e55bc1 100644
--- a/disasm.c
+++ b/disasm.c
@@ -703,9 +703,6 @@ static int matches(const struct itemplate *t, uint8_t *data,
break;
}
- case 0264:
- break;
-
case 0265:
if (prefix->rep == 0xF3)
drep = P_XRELEASE;
diff --git a/insns.dat b/insns.dat
index 9c4c4e70..dac9c12f 100644
--- a/insns.dat
+++ b/insns.dat
@@ -790,10 +790,10 @@ MOV reg_al,mem_offs [-i: a0 iwdq] 8086,SM
MOV reg_ax,mem_offs [-i: o16 a1 iwdq] 8086,SM
MOV reg_eax,mem_offs [-i: o32 a1 iwdq] 386,SM
MOV reg_rax,mem_offs [-i: o64 a1 iwdq] X64,SM
-MOV mem_offs,reg_al [i-: nohle a2 iwdq] 8086,SM
-MOV mem_offs,reg_ax [i-: nohle o16 a3 iwdq] 8086,SM
-MOV mem_offs,reg_eax [i-: nohle o32 a3 iwdq] 386,SM
-MOV mem_offs,reg_rax [i-: nohle o64 a3 iwdq] X64,SM
+MOV mem_offs,reg_al [i-: a2 iwdq] 8086,SM
+MOV mem_offs,reg_ax [i-: o16 a3 iwdq] 8086,SM,NOHLE
+MOV mem_offs,reg_eax [i-: o32 a3 iwdq] 386,SM,NOHLE
+MOV mem_offs,reg_rax [i-: o64 a3 iwdq] X64,SM,NOHLE
MOV reg32,reg_creg [mr: rex.l 0f 20 /r] 386,PRIV,NOLONG
MOV reg64,reg_creg [mr: o64nw 0f 20 /r] X64,PRIV
MOV reg_creg,reg32 [rm: rex.l 0f 22 /r] 386,PRIV,NOLONG
diff --git a/insns.h b/insns.h
index 8faf5103..5ab58fa7 100644
--- a/insns.h
+++ b/insns.h
@@ -97,28 +97,30 @@ extern const uint8_t nasm_bytecodes[];
#define IF_PROT 0x00000000UL /* it's protected mode only */
#define IF_LOCK 0x00000400UL /* lockable if operand 0 is memory */
#define IF_NOLONG 0x00000800UL /* it's not available in long mode */
-#define IF_UNDOC 0x00001000UL /* it's an undocumented instruction */
-#define IF_FPU 0x00002000UL /* it's an FPU instruction */
-#define IF_MMX 0x00004000UL /* it's an MMX instruction */
-#define IF_3DNOW 0x00008000UL /* it's a 3DNow! instruction */
-#define IF_SSE 0x00010000UL /* it's a SSE (KNI, MMX2) instruction */
-#define IF_SSE2 0x00020000UL /* it's a SSE2 instruction */
-#define IF_SSE3 0x00040000UL /* it's a SSE3 (PNI) instruction */
-#define IF_VMX 0x00080000UL /* it's a VMX instruction */
-#define IF_LONG 0x00100000UL /* long mode instruction */
-#define IF_SSSE3 0x00200000UL /* it's an SSSE3 instruction */
-#define IF_SSE4A 0x00400000UL /* AMD SSE4a */
-#define IF_SSE41 0x00800000UL /* it's an SSE4.1 instruction */
-#define IF_SSE42 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_SSE5 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_AVX 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_AVX2 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_FMA 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_BMI1 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_BMI2 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_HLE 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_RTM 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
-#define IF_INVPCID 0x00800000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_LONG 0x00001000UL /* long mode instruction */
+#define IF_NOHLE 0x00002000UL /* HLE prefixes forbidden */
+/* These flags are currently not used for anything - intended for insn set */
+#define IF_UNDOC 0x00000000UL /* it's an undocumented instruction */
+#define IF_FPU 0x00000000UL /* it's an FPU instruction */
+#define IF_MMX 0x00000000UL /* it's an MMX instruction */
+#define IF_3DNOW 0x00000000UL /* it's a 3DNow! instruction */
+#define IF_SSE 0x00000000UL /* it's a SSE (KNI, MMX2) instruction */
+#define IF_SSE2 0x00000000UL /* it's a SSE2 instruction */
+#define IF_SSE3 0x00000000UL /* it's a SSE3 (PNI) instruction */
+#define IF_VMX 0x00000000UL /* it's a VMX instruction */
+#define IF_SSSE3 0x00000000UL /* it's an SSSE3 instruction */
+#define IF_SSE4A 0x00000000UL /* AMD SSE4a */
+#define IF_SSE41 0x00000000UL /* it's an SSE4.1 instruction */
+#define IF_SSE42 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_SSE5 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_AVX 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_AVX2 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_FMA 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_BMI1 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_BMI2 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_HLE 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_RTM 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
+#define IF_INVPCID 0x00000000UL /* HACK NEED TO REORGANIZE THESE BITS */
#define IF_PMASK 0xFF000000UL /* the mask for processor types */
#define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */
/* also the highest possible processor */
diff --git a/insns.pl b/insns.pl
index 2ec891c2..28c13486 100755
--- a/insns.pl
+++ b/insns.pl
@@ -726,7 +726,6 @@ sub byte_code_compile($$) {
'jcc8' => 0370, # Match only if Jcc possible with single byte
'jmp8' => 0371, # Match only if JMP possible with single byte
'jlen' => 0373, # Length of jump
- 'nohle' => 0264,
'hlexr' => 0265,
'hlenl' => 0266,
'hle' => 0267,
diff --git a/test/hle.asm b/test/hle.asm
new file mode 100644
index 00000000..e93b0b91
--- /dev/null
+++ b/test/hle.asm
@@ -0,0 +1,15 @@
+ bits 32
+
+ xacquire lock add [esi],eax
+ xacquire xchg [eax],ebx
+ xrelease lock mov [eax],ecx
+ xrelease mov [eax],ecx
+ xacquire add ecx,[eax]
+ xrelease mov [eax],ecx
+
+ ; Different opcodes!
+ mov [sym],eax
+ xrelease mov [sym],eax
+ xacquire mov [sym],eax
+
+sym dd 0