diff options
author | Jin Kyu Song <jin.kyu.song@intel.com> | 2013-11-26 17:14:07 -0800 |
---|---|---|
committer | Jin Kyu Song <jin.kyu.song@intel.com> | 2013-11-27 15:43:32 -0800 |
commit | 08ae610ec96d2f07543eb0caf90ec429ddf89f32 (patch) | |
tree | a3609ac6cf5ab441ad4a28fd80b8745767a5e5c8 | |
parent | 1ab16e46731678dd965c9e1148e62c944d9c5ed6 (diff) | |
download | nasm-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.c | 4 | ||||
-rwxr-xr-x | insns.pl | 5 | ||||
-rw-r--r-- | opflags.h | 27 | ||||
-rw-r--r-- | regs.dat | 9 |
4 files changed, 34 insertions, 11 deletions
@@ -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; @@ -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); @@ -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 */ @@ -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 |