opflags: Separate vector registers into low-16 and high-16
authorJin Kyu Song <jin.kyu.song@intel.com>
Wed, 27 Nov 2013 01:14:07 +0000 (17:14 -0800)
committerJin Kyu Song <jin.kyu.song@intel.com>
Wed, 27 Nov 2013 23:43:32 +0000 (15:43 -0800)
Since only EVEX supports all 32 vector registers encoding for now,
VEX/REX encoded instructions should not take high-16 registers as operands.

This filtering had been done using instruction flag so far, but
using the opflags makes more sense.

[XYZ]MMREG operands used for non-EVEX instructions are automatically
converted to [XYZ]MM_L16 in insns.pl

Signed-off-by: Jin Kyu Song <jin.kyu.song@intel.com>
assemble.c
insns.pl
opflags.h
regs.dat

index 193c487..a7ca1aa 100644 (file)
@@ -2232,10 +2232,6 @@ static enum match_result matches(const struct itemplate *itemp,
                  */
                 return MERR_BRNUMMISMATCH;
             }
-        } else if (is_register(instruction->oprs[i].basereg) &&
-                   nasm_regvals[instruction->oprs[i].basereg] >= 16 &&
-                   !itemp_has(itemp, IF_AVX512)) {
-            return MERR_ENCMISMATCH;
         } else if (instruction->prefixes[PPS_EVEX] &&
                    !itemp_has(itemp, IF_AVX512)) {
             return MERR_ENCMISMATCH;
index 8515c02..2ce9a51 100755 (executable)
--- a/insns.pl
+++ b/insns.pl
@@ -464,6 +464,11 @@ sub format_insn($$$$$) {
                 $opp =~ s/^([a-z]+)rm$/rm_$1/;
                 $opp =~ s/^rm$/rm_gpr/;
                 $opp =~ s/^reg$/reg_gpr/;
+                # only for evex insns, high-16 regs are allowed
+                if ($codes !~ /(^|\s)evex\./) {
+                    $opp =~ s/^(rm_[xyz]mm)$/$1_l16/;
+                    $opp =~ s/^([xyz]mm)reg$/$1_l16/;
+                }
                 push(@opx, $opp, @oppx) if $opp;
             }
             $op = join('|', @opx);
index 16c65cb..707452e 100644 (file)
--- a/opflags.h
+++ b/opflags.h
 #define MMXREG                  (                  REG_CLASS_RM_MMX           | REGMEM | REGISTER)      /* MMX register */
 #define RM_XMM                  (                  REG_CLASS_RM_XMM           | REGMEM)                 /* XMM (SSE) operand */
 #define XMMREG                  (                  REG_CLASS_RM_XMM           | REGMEM | REGISTER)      /* XMM (SSE) register */
-#define XMM0                    (GEN_SUBCLASS(1) | REG_CLASS_RM_XMM           | REGMEM | REGISTER)      /* XMM register zero */
 #define RM_YMM                  (                  REG_CLASS_RM_YMM           | REGMEM)                 /* YMM (AVX) operand */
 #define YMMREG                  (                  REG_CLASS_RM_YMM           | REGMEM | REGISTER)      /* YMM (AVX) register */
-#define YMM0                    (GEN_SUBCLASS(1) | REG_CLASS_RM_YMM           | REGMEM | REGISTER)      /* YMM register zero */
 #define RM_ZMM                  (                  REG_CLASS_RM_ZMM           | REGMEM)                 /* ZMM (AVX512) operand */
 #define ZMMREG                  (                  REG_CLASS_RM_ZMM           | REGMEM | REGISTER)      /* ZMM (AVX512) register */
-#define ZMM0                    (GEN_SUBCLASS(1) | REG_CLASS_RM_ZMM           | REGMEM | REGISTER)      /* ZMM register zero */
 #define RM_OPMASK               (                  REG_CLASS_OPMASK           | REGMEM)                 /* Opmask operand */
 #define OPMASKREG               (                  REG_CLASS_OPMASK           | REGMEM | REGISTER)      /* Opmask register */
 #define OPMASK0                 (GEN_SUBCLASS(1) | REG_CLASS_OPMASK           | REGMEM | REGISTER)      /* Opmask register zero (k0) */
 #define ZMEM                    (GEN_SUBCLASS(5) | MEMORY)      /* 512-bit vector SIB */
 
 /* memory which matches any type of r/m operand */
-#define MEMORY_ANY              (MEMORY | RM_GPR | RM_MMX | RM_XMM | RM_YMM | RM_ZMM | RM_OPMASK | RM_BND)
+#define MEMORY_ANY              (MEMORY | RM_GPR | RM_MMX | RM_XMM_L16 | RM_YMM_L16 | RM_ZMM_L16 | RM_OPMASK | RM_BND)
 
 /* special immediate values */
 #define UNITY                   (GEN_SUBCLASS(0) | IMMEDIATE)   /* operand equals 1 */
 #define SDWORD                  (GEN_SUBCLASS(3) | IMMEDIATE)   /* operand is in the range -0x80000000..0x7FFFFFFF */
 #define UDWORD                  (GEN_SUBCLASS(4) | IMMEDIATE)   /* operand is in the range 0..0xFFFFFFFF */
 
+/*
+ * split vector registers - low 16 and high 16.
+ * avoid a conflict in subclass bitfield with any of special EA types.
+ */
+#define RM_XMM_L16              (GEN_SUBCLASS(6) | RM_XMM)                                              /* XMM r/m operand  0 ~ 15 */
+#define RM_XMM_H16              (                  RM_XMM)                                              /* XMM r/m operand 16 ~ 31 */
+#define XMM0                    (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | XMMREG)                            /* XMM register   zero  */
+#define XMM_L16                 (                  GEN_SUBCLASS(6) | XMMREG)                            /* XMM register  0 ~ 15 */
+#define XMM_H16                 (                                    XMMREG)                            /* XMM register 16 ~ 31 */
+
+#define RM_YMM_L16              (GEN_SUBCLASS(6) | RM_YMM)                                              /* YMM r/m operand  0 ~ 15 */
+#define RM_YMM_H16              (                  RM_YMM)                                              /* YMM r/m operand 16 ~ 31 */
+#define YMM0                    (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | YMMREG)                            /* YMM register   zero  */
+#define YMM_L16                 (                  GEN_SUBCLASS(6) | YMMREG)                            /* YMM register  0 ~ 15 */
+#define YMM_H16                 (                                    YMMREG)                            /* YMM register 16 ~ 31 */
+
+#define RM_ZMM_L16              (GEN_SUBCLASS(6) | RM_ZMM)                                              /* ZMM r/m operand  0 ~ 15 */
+#define RM_ZMM_H16              (                  RM_ZMM)                                              /* ZMM r/m operand 16 ~ 31 */
+#define ZMM0                    (GEN_SUBCLASS(1) | GEN_SUBCLASS(6) | ZMMREG)                            /* ZMM register   zero  */
+#define ZMM_L16                 (                  GEN_SUBCLASS(6) | ZMMREG)                            /* ZMM register  0 ~ 15 */
+#define ZMM_H16                 (                                    ZMMREG)                            /* ZMM register 16 ~ 31 */
+
 #endif /* NASM_OPFLAGS_H */
index 46d5409..51682d6 100644 (file)
--- a/regs.dat
+++ b/regs.dat
@@ -117,15 +117,18 @@ mm0-7     MMXREG          mmxreg          0
 
 # SSE registers
 xmm0   XMM0            xmmreg          0
-xmm1-31        XMMREG          xmmreg          1
+xmm1-15        XMM_L16         xmmreg          1
+xmm16-31       XMM_H16         xmmreg          16
 
 # AVX registers
 ymm0   YMM0            ymmreg          0
-ymm1-31        YMMREG          ymmreg          1
+ymm1-15        YMM_L16         ymmreg          1
+ymm16-31       YMM_H16         ymmreg          16
 
 # AVX512 registers
 zmm0   ZMM0            zmmreg          0
-zmm1-31        ZMMREG          zmmreg          1
+zmm1-15        ZMM_L16         zmmreg          1
+zmm16-31       ZMM_H16         zmmreg          16
 
 # Opmask registers
 k0     OPMASK0         opmaskreg       0