aboutsummaryrefslogtreecommitdiff
path: root/tcg
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2020-08-30 08:57:20 -0700
committerRichard Henderson <richard.henderson@linaro.org>2020-10-08 05:57:32 -0500
commite2e7168a214b0ed98dc357bba96816486a289762 (patch)
treeda936e20dd164e5997a49cca286266d85ad54cd8 /tcg
parent6eeea6725a70e6fcb5abba0764496bdab07ddfb3 (diff)
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. Tested-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg')
-rw-r--r--tcg/tcg-op-gvec.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/tcg/tcg-op-gvec.c b/tcg/tcg-op-gvec.c
index 7ebd9e8298..ddbe06b71a 100644
--- a/tcg/tcg-op-gvec.c
+++ b/tcg/tcg-op-gvec.c
@@ -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);
- tcg_debug_assert(oprsz <= maxsz);
- tcg_debug_assert((oprsz & opr_align) == 0);
+ uint32_t max_align;
+
+ switch (oprsz) {
+ case 8:
+ case 16:
+ case 32:
+ tcg_debug_assert(oprsz <= maxsz);
+ 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);
}
@@ -77,12 +87,21 @@ uint32_t simd_desc(uint32_t oprsz, uint32_t maxsz, int32_t data)
{
uint32_t desc = 0;
- assert(oprsz % 8 == 0 && oprsz <= (8 << SIMD_OPRSZ_BITS));
- assert(maxsz % 8 == 0 && maxsz <= (8 << SIMD_MAXSZ_BITS));
- assert(data == sextract32(data, 0, SIMD_DATA_BITS));
+ check_size_align(oprsz, maxsz, 0);
+ tcg_debug_assert(data == sextract32(data, 0, SIMD_DATA_BITS));
oprsz = (oprsz / 8) - 1;
maxsz = (maxsz / 8) - 1;
+
+ /*
+ * We have just asserted in check_size_align that either
+ * oprsz is {8,16,32} or matches maxsz. Encode the final
+ * case with '2', as that would otherwise map to 24.
+ */
+ if (oprsz == maxsz) {
+ oprsz = 2;
+ }
+
desc = deposit32(desc, SIMD_OPRSZ_SHIFT, SIMD_OPRSZ_BITS, oprsz);
desc = deposit32(desc, SIMD_MAXSZ_SHIFT, SIMD_MAXSZ_BITS, maxsz);
desc = deposit32(desc, SIMD_DATA_SHIFT, SIMD_DATA_BITS, data);