From ef83ba6cb1ebf1e8e215cc103cd5612ce9175674 Mon Sep 17 00:00:00 2001 From: Mark Charney Date: Fri, 30 Jun 2017 14:33:20 -0400 Subject: [PATCH] improve EVEX & VEX handling of mask register specifier bits * Outside of 64b mode, EVEX.R', EVEX.R, EVEX.X and EVEX.B are ignored. (handled in ILD C code). If not set, those fields are zero. * MASK_B ignores REXB (EVEX.B and VEX.B). It is used in EVEX and VEX mask encodings. SDM(062) states EVEX.B is ignored but omits mention of VEX.B. * In 64b mode, VEX.vvvv[3] must be 1 for mask registers; EVEX.vvvv is not used for mask registers. In non-64b mode VEX.vvvv[3] is ignored for mask regs. * VEX.R must be 1 for mask registers. Change-Id: I209a62c7e27778ca0981e342cb3143f367409abf (cherry picked from commit c41fb5e8f6b77524b94ee2e5860dd6c91a45b628) --- datafiles/avx512f/avx512-reg-table-mask.txt | 21 ++++++++++++--------- src/dec/xed-ild.c | 13 ++++++------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/datafiles/avx512f/avx512-reg-table-mask.txt b/datafiles/avx512f/avx512-reg-table-mask.txt index 3a8e2a8..0b99b92 100644 --- a/datafiles/avx512f/avx512-reg-table-mask.txt +++ b/datafiles/avx512f/avx512-reg-table-mask.txt @@ -50,16 +50,19 @@ REXRR=0 REXR=0 REG=0x5 | OUTREG=XED_REG_K5 REXRR=0 REXR=0 REG=0x6 | OUTREG=XED_REG_K6 REXRR=0 REXR=0 REG=0x7 | OUTREG=XED_REG_K7 -# only used in VEX space for K-mask ops +# MASK_B is used by VEX and EVEX encodings. SDM (rev 062) states in +# EVEX, EVEX.B (REXB) is ignored. SDM does not (yet) say what happens +# on VEX.B but assuming it is similar. + xed_reg_enum_t MASK_B():: -REXB=0 RM=0x0 | OUTREG=XED_REG_K0 -REXB=0 RM=0x1 | OUTREG=XED_REG_K1 -REXB=0 RM=0x2 | OUTREG=XED_REG_K2 -REXB=0 RM=0x3 | OUTREG=XED_REG_K3 -REXB=0 RM=0x4 | OUTREG=XED_REG_K4 -REXB=0 RM=0x5 | OUTREG=XED_REG_K5 -REXB=0 RM=0x6 | OUTREG=XED_REG_K6 -REXB=0 RM=0x7 | OUTREG=XED_REG_K7 +RM=0x0 | OUTREG=XED_REG_K0 +RM=0x1 | OUTREG=XED_REG_K1 +RM=0x2 | OUTREG=XED_REG_K2 +RM=0x3 | OUTREG=XED_REG_K3 +RM=0x4 | OUTREG=XED_REG_K4 +RM=0x5 | OUTREG=XED_REG_K5 +RM=0x6 | OUTREG=XED_REG_K6 +RM=0x7 | OUTREG=XED_REG_K7 # only used in VEX space for K-mask ops # stored inverted diff --git a/src/dec/xed-ild.c b/src/dec/xed-ild.c index 5667648..ddb7f6a 100644 --- a/src/dec/xed-ild.c +++ b/src/dec/xed-ild.c @@ -1347,13 +1347,12 @@ static void evex_scanner(xed_decoded_inst_t* d) evex2.u32 = xed_decoded_inst_get_byte(d, length+2); // above check guarantees that r and x are 1 in 16/32b mode. - xed3_operand_set_rexr(d, ~evex1.s.r_inv&1); - xed3_operand_set_rexx(d, ~evex1.s.x_inv&1); - - // force rexb to zero in 16/32b mode because it can be used for gprs - xed3_operand_set_rexb(d, (xed3_mode_64b(d) & ~evex1.s.b_inv)&1); - // rexrr not used for gprs. Only for evex x/y/zmm regs - xed3_operand_set_rexrr(d, ~evex1.s.rr_inv&1); + if (xed3_mode_64b(d)) { + xed3_operand_set_rexr(d, ~evex1.s.r_inv&1); + xed3_operand_set_rexx(d, ~evex1.s.x_inv&1); + xed3_operand_set_rexb(d, ~evex1.s.b_inv&1); + xed3_operand_set_rexrr(d, ~evex1.s.rr_inv&1); + } xed3_operand_set_map(d, evex1.s.map);