From: Jin Kyu Song Date: Wed, 27 Nov 2013 01:14:07 +0000 (-0800) Subject: opflags: Separate vector registers into low-16 and high-16 X-Git-Tag: nasm-2.11.05~49 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=08ae610ec96d2f07543eb0caf90ec429ddf89f32;p=platform%2Fupstream%2Fnasm.git 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 --- diff --git a/assemble.c b/assemble.c index 193c487..a7ca1aa 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 8515c02..2ce9a51 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 16c65cb..707452e 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 46d5409..51682d6 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