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 <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2022-11-07 16:24:39 -08:00
parent 8f2e3cc376
commit ec2074d27f
3 changed files with 28 additions and 23 deletions

View file

@ -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 * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -2445,10 +2445,7 @@ static enum match_result find_match(const struct itemplate **tempp,
if (i == broadcast) { if (i == broadcast) {
instruction->oprs[i].decoflags |= xsizeflags[i]; instruction->oprs[i].decoflags |= xsizeflags[i];
instruction->oprs[i].type |= (xsizeflags[i] == BR_BITS16 ? instruction->oprs[i].type |= brsize_to_size(xsizeflags[i]);
BITS16 :
(xsizeflags[i] == BR_BITS32 ?
BITS32 : BITS64));
} else { } else {
instruction->oprs[i].type |= xsizeflags[i]; /* Set the size */ 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. * the instruction type. decorator flag should match.
*/ */
if (deco_brsize) { if (deco_brsize) {
template_opsize = (deco_brsize == BR_BITS16 ? BITS16 : template_opsize = brsize_to_size(deco_brsize);
(deco_brsize == BR_BITS32 ? BITS32 : BITS64));
/* calculate the proper number : {1to<brcast_num>} */ /* calculate the proper number : {1to<brcast_num>} */
brcast_num = get_broadcast_num(itemp->opd[i], template_opsize); brcast_num = get_broadcast_num(itemp->opd[i], template_opsize);
} else { } else {

View file

@ -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)) { if ((evex[2] & EVEX_P2B) && (deco & BRDCAST_MASK)) {
decoflags_t deco_brsize = deco & BRSIZE_MASK; decoflags_t deco_brsize = deco & BRSIZE_MASK;
opflags_t template_opsize = (deco_brsize == BR_BITS16 ? BITS16 : opflags_t template_opsize = brsize_to_size(deco_brsize);
(deco_brsize == BR_BITS32 ? BITS32 : BITS64)); unsigned int br_num = (type & SIZE_MASK) / BITS128 *
uint8_t br_num = (type & SIZE_MASK) / BITS128 * BITS64 / template_opsize * 2;
BITS64 / template_opsize * 2;
num_chars += snprintf(buf + num_chars, num - num_chars, num_chars += snprintf(buf + num_chars, num - num_chars,
"{1to%d}", br_num); "{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 */ /* when broadcasting, each element size should be used */
if (deco & BR_BITS16) if (deco & BR_BITS16)
slen += slen +=
snprintf(output + slen, outbufsize - slen, "dword "); snprintf(output + slen, outbufsize - slen, "word ");
else if (deco & BR_BITS32) else if (deco & BR_BITS32)
slen += slen +=
snprintf(output + slen, outbufsize - slen, "word "); snprintf(output + slen, outbufsize - slen, "dword ");
else if (deco & BR_BITS64) else if (deco & BR_BITS64)
slen += slen +=
snprintf(output + slen, outbufsize - slen, "qword "); snprintf(output + slen, outbufsize - slen, "qword ");

View file

@ -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 * See the file AUTHORS included with the NASM distribution for
* the specific copyright holders. * the specific copyright holders.
* *
@ -1278,8 +1278,8 @@ enum decorator_tokens {
* ..........................1..... broadcast * ..........................1..... broadcast
* .........................1...... static rounding * .........................1...... static rounding
* ........................1....... SAE * ........................1....... SAE
* .....................111........ broadcast element size * ....................1111........ broadcast element size
* ..................111........... number of broadcast elements * .................111............ number of broadcast elements
*/ */
#define OP_GENVAL(val, bits, shift) (((val) & ((UINT64_C(1) << (bits)) - 1)) << (shift)) #define OP_GENVAL(val, bits, shift) (((val) & ((UINT64_C(1) << (bits)) - 1)) << (shift))
@ -1341,23 +1341,24 @@ enum decorator_tokens {
/* /*
* Broadcasting element size. * Broadcasting element size.
* *
* Bits: 8 - 10 * Bits: 8 - 11
*/ */
#define BRSIZE_SHIFT (8) #define BRSIZE_SHIFT (8)
#define BRSIZE_BITS (3) #define BRSIZE_BITS (4)
#define BRSIZE_MASK OP_GENMASK(BRSIZE_BITS, BRSIZE_SHIFT) #define BRSIZE_MASK OP_GENMASK(BRSIZE_BITS, BRSIZE_SHIFT)
#define GEN_BRSIZE(bit) OP_GENBIT(bit, BRSIZE_SHIFT) #define GEN_BRSIZE(bit) OP_GENBIT(bit, BRSIZE_SHIFT)
#define BR_BITS16 GEN_BRSIZE(0) #define BR_BITS8 GEN_BRSIZE(0) /* For potential future use */
#define BR_BITS32 GEN_BRSIZE(1) #define BR_BITS16 GEN_BRSIZE(1)
#define BR_BITS64 GEN_BRSIZE(2) #define BR_BITS32 GEN_BRSIZE(2)
#define BR_BITS64 GEN_BRSIZE(3)
/* /*
* Number of broadcasting elements * Number of broadcasting elements
* *
* Bits: 11 - 13 * Bits: 12 - 14
*/ */
#define BRNUM_SHIFT (10) #define BRNUM_SHIFT (12)
#define BRNUM_BITS (3) #define BRNUM_BITS (3)
#define BRNUM_MASK OP_GENMASK(BRNUM_BITS, BRNUM_SHIFT) #define BRNUM_MASK OP_GENMASK(BRNUM_BITS, BRNUM_SHIFT)
#define VAL_BRNUM(val) OP_GENVAL(val, 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_1TO8 VAL_BRNUM(2)
#define BR_1TO16 VAL_BRNUM(3) #define BR_1TO16 VAL_BRNUM(3)
#define BR_1TO32 VAL_BRNUM(4) #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 MASK OPMASK_MASK /* Opmask (k1 ~ 7) can be used */
#define Z Z_MASK #define Z Z_MASK
@ -1376,6 +1378,14 @@ enum decorator_tokens {
#define ER STATICRND_MASK /* ER(Embedded Rounding) == Static rounding mode */ #define ER STATICRND_MASK /* ER(Embedded Rounding) == Static rounding mode */
#define SAE SAE_MASK /* SAE(Suppress All Exception) */ #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 * Global modes
*/ */