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)
This commit is contained in:
Mark Charney
2017-06-30 14:33:20 -04:00
committed by Mark Charney
parent 8f4f45418c
commit ef83ba6cb1
2 changed files with 18 additions and 16 deletions

View File

@@ -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

View File

@@ -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.
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);
// 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_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);