diff options
author | H. Peter Anvin <hpa@zytor.com> | 2017-04-02 18:38:58 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2017-04-02 18:38:58 -0700 |
commit | 8e37ff4ea1177643ea3d9befa8e45a301d649b5b (patch) | |
tree | 0e39d9490d4f50421157d2c6218443bcd9052209 /asm/parser.c | |
parent | e886c0e9683884b51740d0b3aa3a11f023fdbe04 (diff) | |
download | nasm-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.c | 60 |
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) |