HLE: Change NOHLE to be an instruction flag
authorH. Peter Anvin <hpa@zytor.com>
Sun, 26 Feb 2012 06:22:07 +0000 (22:22 -0800)
committerH. Peter Anvin <hpa@zytor.com>
Sun, 26 Feb 2012 06:22:07 +0000 (22:22 -0800)
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>
assemble.c
disasm.c
insns.dat
insns.h
insns.pl
test/hle.asm [new file with mode: 0644]

index bf5c103..4d8702c 100644 (file)
@@ -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)
index ba4b8d2..b6e55bc 100644 (file)
--- 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;
index 9c4c4e7..dac9c12 100644 (file)
--- 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 8faf510..5ab58fa 100644 (file)
--- 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 */
index 2ec891c..28c1348 100755 (executable)
--- 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 (file)
index 0000000..e93b0b9
--- /dev/null
@@ -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