tcg: Adjust simd_desc size encoding

With larger vector sizes, it turns out oprsz == maxsz, and we only
need to represent mismatch for oprsz <= 32. We do, however, need
to represent larger oprsz and do so without reducing SIMD_DATA_BITS.

Reduce the size of the oprsz field and increase the maxsz field.
Steal the oprsz value of 24 to indicate equality with maxsz.

Backports e2e7168a214b0ed98dc357bba96816486a289762
This commit is contained in:
Richard Henderson 2021-03-01 19:23:36 -05:00 committed by Lioncash
parent 567fa21c65
commit 1551f6be9d
2 changed files with 40 additions and 18 deletions

View file

@ -20,29 +20,41 @@
#ifndef TCG_TCG_GVEC_DESC_H
#define TCG_TCG_GVEC_DESC_H
/* ??? These bit widths are set for ARM SVE, maxing out at 256 byte vectors. */
#define SIMD_OPRSZ_SHIFT 0
#define SIMD_OPRSZ_BITS 5
/*
* This configuration allows MAXSZ to represent 2048 bytes, and
* OPRSZ to match MAXSZ, or represent the smaller values 8, 16, or 32.
*
* Encode this with:
* 0, 1, 3 -> 8, 16, 32
* 2 -> maxsz
*
* This steals the input that would otherwise map to 24 to match maxsz.
*/
#define SIMD_MAXSZ_SHIFT 0
#define SIMD_MAXSZ_BITS 8
#define SIMD_MAXSZ_SHIFT (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
#define SIMD_MAXSZ_BITS 5
#define SIMD_OPRSZ_SHIFT (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
#define SIMD_OPRSZ_BITS 2
#define SIMD_DATA_SHIFT (SIMD_MAXSZ_SHIFT + SIMD_MAXSZ_BITS)
#define SIMD_DATA_SHIFT (SIMD_OPRSZ_SHIFT + SIMD_OPRSZ_BITS)
#define SIMD_DATA_BITS (32 - SIMD_DATA_SHIFT)
/* Create a descriptor from components. */
uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data);
/* Extract the operation size from a descriptor. */
static inline intptr_t simd_oprsz(uint32_t desc)
{
return (extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS) + 1) * 8;
}
/* Extract the max vector size from a descriptor. */
static inline intptr_t simd_maxsz(uint32_t desc)
{
return (extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) + 1) * 8;
return extract32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS) * 8 + 8;
}
/* Extract the operation size from a descriptor. */
static inline intptr_t simd_oprsz(uint32_t desc)
{
uint32_t f = extract32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS);
intptr_t o = f * 8 + 8;
intptr_t m = simd_maxsz(desc);
return f == 2 ? m : o;
}
/* Extract the operation-specific data from a descriptor. */

View file

@ -37,11 +37,21 @@ static const TCGOpcode vecop_list_empty[1] = { 0 };
of the operand offsets so that we can check them all at once. */
static void check_size_align(uint32_t oprsz, uint32_t maxsz, uint32_t ofs)
{
uint32_t opr_align = oprsz >= 16 ? 15 : 7;
uint32_t max_align = maxsz >= 16 || oprsz >= 16 ? 15 : 7;
tcg_debug_assert(oprsz > 0);
uint32_t max_align;
switch (oprsz) {
case 8:
case 16:
case 32:
tcg_debug_assert(oprsz <= maxsz);
tcg_debug_assert((oprsz & opr_align) == 0);
break;
default:
tcg_debug_assert(oprsz == maxsz);
break;
}
tcg_debug_assert(maxsz <= (8 << SIMD_MAXSZ_BITS));
max_align = maxsz >= 16 ? 15 : 7;
tcg_debug_assert((maxsz & max_align) == 0);
tcg_debug_assert((ofs & max_align) == 0);
}