summaryrefslogtreecommitdiff
path: root/asm/parser.c
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2017-04-02 18:38:58 -0700
committerH. Peter Anvin <hpa@zytor.com>2017-04-02 18:38:58 -0700
commit8e37ff4ea1177643ea3d9befa8e45a301d649b5b (patch)
tree0e39d9490d4f50421157d2c6218443bcd9052209 /asm/parser.c
parente886c0e9683884b51740d0b3aa3a11f023fdbe04 (diff)
downloadnasm-8e37ff4ea1177643ea3d9befa8e45a301d649b5b.tar.gz
BR3392392: fix broadcast decorators and improve error messages
Checkin c33d95fde9f8ae6252c8ecf4d66c543dfa914d83: BR 3392370: {z} decorator allowed on MOVDQ* memory operands ... inadvertently broke broadcast operations, which only apply to memory operands and therefore were only handled in one of the two brace-parser implementations. Fix that. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
Diffstat (limited to 'asm/parser.c')
-rw-r--r--asm/parser.c60
1 files changed, 32 insertions, 28 deletions
diff --git a/asm/parser.c b/asm/parser.c
index 9093cf20..d1e82ed0 100644
--- a/asm/parser.c
+++ b/asm/parser.c
@@ -191,52 +191,56 @@ static void process_size_override(insn *result, operand *op)
}
/*
- * when two or more decorators follow a register operand,
- * consecutive decorators are parsed here.
- * opmask and zeroing decorators can be placed in any order.
- * e.g. zmm1 {k2}{z} or zmm2 {z}{k3}
- * decorator(s) are placed at the end of an operand.
+ * Brace decorators are are parsed here. opmask and zeroing
+ * decorators can be placed in any order. e.g. zmm1 {k2}{z} or zmm2
+ * {z}{k3} decorator(s) are placed at the end of an operand.
*/
static bool parse_braces(decoflags_t *decoflags)
{
- int i;
- bool recover = false;
+ int i, j;
i = tokval.t_type;
- do {
- if (i == TOKEN_OPMASK) {
+
+ while (true) {
+ switch (i) {
+ case TOKEN_OPMASK:
if (*decoflags & OPMASK_MASK) {
- nasm_error(ERR_NONFATAL, "opmask k%"PRIu64" is already set",
+ nasm_error(ERR_NONFATAL,
+ "opmask k%"PRIu64" is already set",
*decoflags & OPMASK_MASK);
*decoflags &= ~OPMASK_MASK;
}
*decoflags |= VAL_OPMASK(nasm_regvals[tokval.t_integer]);
- } else if (i == TOKEN_DECORATOR) {
- switch (tokval.t_integer) {
+ break;
+ case TOKEN_DECORATOR:
+ j = tokval.t_integer;
+ switch (j) {
case BRC_Z:
- /*
- * according to AVX512 spec, only zeroing/merging decorator
- * is supported with opmask
- */
- *decoflags |= GEN_Z(0);
+ *decoflags |= Z_MASK;
+ break;
+ case BRC_1TO2:
+ case BRC_1TO4:
+ case BRC_1TO8:
+ case BRC_1TO16:
+ *decoflags |= BRDCAST_MASK | VAL_BRNUM(j - BRC_1TO2);
break;
default:
- nasm_error(ERR_NONFATAL, "{%s} is not an expected decorator",
- tokval.t_charptr);
+ nasm_error(ERR_NONFATAL,
+ "{%s} is not an expected decorator",
+ tokval.t_charptr);
break;
}
- } else if (i == ',' || i == TOKEN_EOS){
- break;
- } else {
- nasm_error(ERR_NONFATAL, "only a series of valid decorators"
- " expected");
- recover = true;
break;
+ case ',':
+ case TOKEN_EOS:
+ return false;
+ default:
+ nasm_error(ERR_NONFATAL,
+ "only a series of valid decorators expected");
+ return true;
}
i = stdscan(NULL, &tokval);
- } while(1);
-
- return recover;
+ }
}
static int parse_mref(operand *op, const expr *e)