From ec2074d27f14f28260e80694bcd603ed16e3b927 Mon Sep 17 00:00:00 2001 From: "H. Peter Anvin" Date: Mon, 7 Nov 2022 16:24:39 -0800 Subject: [PATCH] fp16: fix incorred handling of broadcast flags The FP16 patch had a case of bit overlap. Clean up the handling of broadcast flags a little in the process. Signed-off-by: H. Peter Anvin --- asm/assemble.c | 10 +++------- disasm/disasm.c | 11 +++++------ include/nasm.h | 30 ++++++++++++++++++++---------- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/asm/assemble.c b/asm/assemble.c index e64ac851..e8a8d808 100644 --- a/asm/assemble.c +++ b/asm/assemble.c @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * Copyright 1996-2022 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -2445,10 +2445,7 @@ static enum match_result find_match(const struct itemplate **tempp, if (i == broadcast) { instruction->oprs[i].decoflags |= xsizeflags[i]; - instruction->oprs[i].type |= (xsizeflags[i] == BR_BITS16 ? - BITS16 : - (xsizeflags[i] == BR_BITS32 ? - BITS32 : BITS64)); + instruction->oprs[i].type |= brsize_to_size(xsizeflags[i]); } else { instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */ } @@ -2653,8 +2650,7 @@ static enum match_result matches(const struct itemplate *itemp, * the instruction type. decorator flag should match. */ if (deco_brsize) { - template_opsize = (deco_brsize == BR_BITS16 ? BITS16 : - (deco_brsize == BR_BITS32 ? BITS32 : BITS64)); + template_opsize = brsize_to_size(deco_brsize); /* calculate the proper number : {1to} */ brcast_num = get_broadcast_num(itemp->opd[i], template_opsize); } else { diff --git a/disasm/disasm.c b/disasm/disasm.c index bcf39b94..0f3ffc79 100644 --- a/disasm/disasm.c +++ b/disasm/disasm.c @@ -250,10 +250,9 @@ static uint32_t append_evex_mem_deco(char *buf, uint32_t num, opflags_t type, if ((evex[2] & EVEX_P2B) && (deco & BRDCAST_MASK)) { decoflags_t deco_brsize = deco & BRSIZE_MASK; - opflags_t template_opsize = (deco_brsize == BR_BITS16 ? BITS16 : - (deco_brsize == BR_BITS32 ? BITS32 : BITS64)); - uint8_t br_num = (type & SIZE_MASK) / BITS128 * - BITS64 / template_opsize * 2; + opflags_t template_opsize = brsize_to_size(deco_brsize); + unsigned int br_num = (type & SIZE_MASK) / BITS128 * + BITS64 / template_opsize * 2; num_chars += snprintf(buf + num_chars, num - num_chars, "{1to%d}", br_num); @@ -1543,10 +1542,10 @@ int32_t disasm(uint8_t *data, int32_t data_size, char *output, int outbufsize, i /* when broadcasting, each element size should be used */ if (deco & BR_BITS16) slen += - snprintf(output + slen, outbufsize - slen, "dword "); + snprintf(output + slen, outbufsize - slen, "word "); else if (deco & BR_BITS32) slen += - snprintf(output + slen, outbufsize - slen, "word "); + snprintf(output + slen, outbufsize - slen, "dword "); else if (deco & BR_BITS64) slen += snprintf(output + slen, outbufsize - slen, "qword "); diff --git a/include/nasm.h b/include/nasm.h index 5ebb3bbc..1e0b2b91 100644 --- a/include/nasm.h +++ b/include/nasm.h @@ -1,6 +1,6 @@ /* ----------------------------------------------------------------------- * * - * Copyright 1996-2020 The NASM Authors - All Rights Reserved + * Copyright 1996-2022 The NASM Authors - All Rights Reserved * See the file AUTHORS included with the NASM distribution for * the specific copyright holders. * @@ -1278,8 +1278,8 @@ enum decorator_tokens { * ..........................1..... broadcast * .........................1...... static rounding * ........................1....... SAE - * .....................111........ broadcast element size - * ..................111........... number of broadcast elements + * ....................1111........ broadcast element size + * .................111............ number of broadcast elements */ #define OP_GENVAL(val, bits, shift) (((val) & ((UINT64_C(1) << (bits)) - 1)) << (shift)) @@ -1341,23 +1341,24 @@ enum decorator_tokens { /* * Broadcasting element size. * - * Bits: 8 - 10 + * Bits: 8 - 11 */ #define BRSIZE_SHIFT (8) -#define BRSIZE_BITS (3) +#define BRSIZE_BITS (4) #define BRSIZE_MASK OP_GENMASK(BRSIZE_BITS, BRSIZE_SHIFT) #define GEN_BRSIZE(bit) OP_GENBIT(bit, BRSIZE_SHIFT) -#define BR_BITS16 GEN_BRSIZE(0) -#define BR_BITS32 GEN_BRSIZE(1) -#define BR_BITS64 GEN_BRSIZE(2) +#define BR_BITS8 GEN_BRSIZE(0) /* For potential future use */ +#define BR_BITS16 GEN_BRSIZE(1) +#define BR_BITS32 GEN_BRSIZE(2) +#define BR_BITS64 GEN_BRSIZE(3) /* * Number of broadcasting elements * - * Bits: 11 - 13 + * Bits: 12 - 14 */ -#define BRNUM_SHIFT (10) +#define BRNUM_SHIFT (12) #define BRNUM_BITS (3) #define BRNUM_MASK OP_GENMASK(BRNUM_BITS, BRNUM_SHIFT) #define VAL_BRNUM(val) OP_GENVAL(val, BRNUM_BITS, BRNUM_SHIFT) @@ -1367,6 +1368,7 @@ enum decorator_tokens { #define BR_1TO8 VAL_BRNUM(2) #define BR_1TO16 VAL_BRNUM(3) #define BR_1TO32 VAL_BRNUM(4) +#define BR_1TO64 VAL_BRNUM(5) /* For potential future use */ #define MASK OPMASK_MASK /* Opmask (k1 ~ 7) can be used */ #define Z Z_MASK @@ -1376,6 +1378,14 @@ enum decorator_tokens { #define ER STATICRND_MASK /* ER(Embedded Rounding) == Static rounding mode */ #define SAE SAE_MASK /* SAE(Suppress All Exception) */ +/* + * Broadcast flags (BR_BITS*) to sizes (BITS*) + */ +static inline opflags_t brsize_to_size(opflags_t brbits) +{ + return (brbits & BRSIZE_MASK) << (SIZE_SHIFT - BRSIZE_SHIFT); +} + /* * Global modes */