summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJin Kyu Song <jin.kyu.song@intel.com>2013-11-26 17:14:07 -0800
committerJin Kyu Song <jin.kyu.song@intel.com>2013-11-27 15:43:32 -0800
commit08ae610ec96d2f07543eb0caf90ec429ddf89f32 (patch)
treea3609ac6cf5ab441ad4a28fd80b8745767a5e5c8
parent1ab16e46731678dd965c9e1148e62c944d9c5ed6 (diff)
downloadnasm-08ae610ec96d2f07543eb0caf90ec429ddf89f32.tar.gz
opflags: Separate vector registers into low-16 and high-16
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>
-rw-r--r--assemble.c4
-rwxr-xr-xinsns.pl5
-rw-r--r--opflags.h27
-rw-r--r--regs.dat9
4 files changed, 34 insertions, 11 deletions
diff --git a/assemble.c b/assemble.c
index 193c4872..a7ca1aa1 100644
--- a/assemble.c
+++ b/assemble.c
@@ -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;
diff --git a/insns.pl b/insns.pl
index 8515c02e..2ce9a511 100755
--- 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);
diff --git a/opflags.h b/opflags.h
index 16c65cbf..707452e5 100644
--- a/opflags.h
+++ b/opflags.h
@@ -185,13 +185,10 @@
#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) */
@@ -246,7 +243,7 @@
#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 */
@@ -255,4 +252,26 @@
#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 */
diff --git a/regs.dat b/regs.dat
index 46d54096..51682d68 100644
--- 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