int rfield;
opflags_t rflags;
struct operand *opy = &ins->oprs[op2];
- struct operand *oplast;
+ struct operand *op_er_sae;
ea_data.rex = 0; /* Ensure ea.REX is initially 0 */
/* pick rfield from operand b (opx) */
rflags = regflag(opx);
rfield = nasm_regvals[opx->basereg];
- /* find the last SIMD operand where ER decorator resides */
- oplast = &ins->oprs[op1 > op2 ? op1 : op2];
- while (oplast && is_class(REG_CLASS_GPR, oplast->type))
- oplast--;
} else {
rflags = 0;
rfield = c & 7;
- oplast = opy;
}
- if (oplast->decoflags & ER) {
+ /* EVEX.b1 : evex_brerop contains the operand position */
+ op_er_sae = (ins->evex_brerop >= 0 ?
+ &ins->oprs[ins->evex_brerop] : NULL);
+
+ if (op_er_sae && (op_er_sae->decoflags & ER)) {
/* set EVEX.RC (rounding control) and b */
ins->evex_p[2] |= (((ins->evex_rm - BRC_RN) << 5) & EVEX_P2LL) |
EVEX_P2B;
} else {
/* set EVEX.L'L (vector length) */
ins->evex_p[2] |= ((ins->vex_wlp << (5 - 2)) & EVEX_P2LL);
- if ((oplast->decoflags & SAE) ||
+ if ((op_er_sae && (op_er_sae->decoflags & SAE)) ||
(opy->decoflags & BRDCAST_MASK)) {
/* set EVEX.b */
ins->evex_p[2] |= EVEX_P2B;
enum match_result m, merr;
opflags_t xsizeflags[MAX_OPERANDS];
bool opsizemissing = false;
- int8_t broadcast = -1;
+ int8_t broadcast = instruction->evex_brerop;
int i;
- /* find the position of broadcasting operand */
- for (i = 0; i < instruction->operands; i++)
- if (instruction->oprs[i].decoflags & BRDCAST_MASK) {
- broadcast = i;
- break;
- }
-
/* broadcasting uses a different data element size */
for (i = 0; i < instruction->operands; i++)
if (i == broadcast)
/* EVEX.P2: [z,L'L,b,V',aaa] */
enum ttypes evex_tuple; /* Tuple type for compressed Disp8*N */
int evex_rm; /* static rounding mode for AVX3 (EVEX) */
+ int8_t evex_brerop; /* BR/ER/SAE operand position */
} insn;
enum geninfo { GI_SWITCH };
result->label = NULL; /* Assume no label */
result->eops = NULL; /* must do this, whatever happens */
result->operands = 0; /* must initialize this */
+ result->evex_rm = 0; /* Ensure EVEX rounding mode is reset */
+ result->evex_brerop = -1; /* Reset EVEX broadcasting/ER op position */
/* Ignore blank lines */
if (i == TOKEN_EOS) {
"register size specification ignored");
}
}
+
+ /* remember the position of operand having broadcasting/ER mode */
+ if (result->oprs[operand].decoflags & (BRDCAST_MASK | ER | SAE))
+ result->evex_brerop = operand;
}
result->operands = operand; /* set operand count */