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
* 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>} */
brcast_num = get_broadcast_num(itemp->opd[i], template_opsize);
} else {

View file

@ -250,9 +250,8 @@ 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 *
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,
@ -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 ");

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
* 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
*/