AVX-512: Remember the position of operand with broadcast or embedded rounding

It was not so straight forward to find the postion of operand that has
a broadcasting, embedded rounding mode or SAE (Suppress All Exceptions)
decorator out from operands types or bytecode.
Remebering the postion of the operand of interest in the parser reduces
the burden that assembler looks through the operands.

Signed-off-by: Jin Kyu Song <jin.kyu.song@intel.com>
Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
This commit is contained in:
Jin Kyu Song 2013-08-28 19:15:23 -07:00 committed by Cyrill Gorcunov
parent fe0ee08586
commit e3a06b9d0a
3 changed files with 15 additions and 16 deletions

View file

@ -1150,7 +1150,7 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
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 */
@ -1158,24 +1158,23 @@ static int64_t calcsize(int32_t segment, int64_t offset, int bits,
/* 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;
@ -1924,16 +1923,9 @@ static enum match_result find_match(const struct itemplate **tempp,
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)

1
nasm.h
View file

@ -690,6 +690,7 @@ typedef struct insn { /* an instruction itself */
/* 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 };

View file

@ -262,6 +262,8 @@ restart_parse:
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) {
@ -1034,6 +1036,10 @@ is_expression:
"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 */