diff options
| author | Richard Henderson <richard.henderson@linaro.org> | 2021-11-09 07:18:33 +0100 |
|---|---|---|
| committer | Richard Henderson <richard.henderson@linaro.org> | 2021-11-09 07:18:33 +0100 |
| commit | f10e7b9f6fc18be390b3bc189e04b5147eb8dbf8 (patch) | |
| tree | 760292c2ddc22c5b75653c5d5dc7ae4ca6d8d729 /target/ppc/int_helper.c | |
| parent | 114f3c8cc427333dbae331dfd2ecae64676b087e (diff) | |
| parent | 71e6fae3a994ab5c69e37d6a52a30c840883fbfb (diff) | |
| download | focaccia-qemu-f10e7b9f6fc18be390b3bc189e04b5147eb8dbf8.tar.gz focaccia-qemu-f10e7b9f6fc18be390b3bc189e04b5147eb8dbf8.zip | |
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-6.2-20211109' into staging
ppc patch queue for 2021-11-09 Here's the latest set of ppc related patches for qemu-6.2, which I hope will squeeze in just barely before the hard freeze. This set includes a change to MAINTAINERS moving maintainership of ppc from myself and Greg Kurz to Cédric le Goater and Daniel Henrique Barboza. So, I expect this to be my last pull request as ppc maintainer. It's been great, but it's time I moved onto other things. Apart from that, this patchset is mostly a lot of updates to TCG implementations of ISA 3.1 (POWER10) instructions from the El Dorado team. There are also a handful of other fixes. # gpg: Signature made Tue 09 Nov 2021 05:14:33 AM CET # gpg: using RSA key 75F46586AE61A66CC44E87DC6C38CACA20D9B392 # gpg: Good signature from "David Gibson <david@gibson.dropbear.id.au>" [full] # gpg: aka "David Gibson (kernel.org) <dwg@kernel.org>" [unknown] # gpg: aka "David Gibson (Red Hat) <dgibson@redhat.com>" [full] # gpg: aka "David Gibson (ozlabs.org) <dgibson@ozlabs.org>" [full] * remotes/dgibson/tags/ppc-for-6.2-20211109: (54 commits) spapr_numa.c: FORM2 table handle nodes with no distance info target/ppc, hw/ppc: Change maintainers target/ppc: cntlzdm/cnttzdm implementation without brcond target/ppc: Implement lxvkq instruction target/ppc: Implement xxblendvb/xxblendvh/xxblendvw/xxblendvd instructions target/ppc: implemented XXSPLTIDP instruction target/ppc: Implemented XXSPLTIW using decodetree target/ppc: implemented XXSPLTI32DX target/ppc: moved XXSPLTIB to using decodetree target/ppc: moved XXSPLTW to using decodetree target/ppc: added the instructions PLXVP and PSTXVP target/ppc: added the instructions PLXV and PSTXV target/ppc: added the instructions LXVPX and STXVPX target/ppc: added the instructions LXVP and STXVP target/ppc: moved stxvx and lxvx from legacy to decodtree target/ppc: moved stxv and lxv from legacy to decodtree target/ppc: receive high/low as argument in get/set_cpu_vsr target/ppc: Introduce REQUIRE_VSX macro target/ppc: Implement Vector Extract Double to VSR using GPR index insns target/ppc: Move vinsertb/vinserth/vinsertw/vinsertd to decodetree ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'target/ppc/int_helper.c')
| -rw-r--r-- | target/ppc/int_helper.c | 135 |
1 files changed, 117 insertions, 18 deletions
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c index eeb7781a9e..9bc327bcba 100644 --- a/target/ppc/int_helper.c +++ b/target/ppc/int_helper.c @@ -324,7 +324,7 @@ target_ulong helper_popcntb(target_ulong val) } #endif -uint64_t helper_cfuged(uint64_t src, uint64_t mask) +uint64_t helper_CFUGED(uint64_t src, uint64_t mask) { /* * Instead of processing the mask bit-by-bit from the most significant to @@ -386,6 +386,42 @@ uint64_t helper_cfuged(uint64_t src, uint64_t mask) return left | (right >> n); } +uint64_t helper_PDEPD(uint64_t src, uint64_t mask) +{ + int i, o; + uint64_t result = 0; + + if (mask == -1) { + return src; + } + + for (i = 0; mask != 0; i++) { + o = ctz64(mask); + mask &= mask - 1; + result |= ((src >> i) & 1) << o; + } + + return result; +} + +uint64_t helper_PEXTD(uint64_t src, uint64_t mask) +{ + int i, o; + uint64_t result = 0; + + if (mask == -1) { + return src; + } + + for (o = 0; mask != 0; o++) { + i = ctz64(mask); + mask &= mask - 1; + result |= ((src >> i) & 1) << o; + } + + return result; +} + /*****************************************************************************/ /* PowerPC 601 specific instructions (POWER bridge) */ target_ulong helper_div(CPUPPCState *env, target_ulong arg1, target_ulong arg2) @@ -1577,25 +1613,73 @@ void helper_vslo(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) } #if defined(HOST_WORDS_BIGENDIAN) -#define VINSERT(suffix, element) \ - void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \ - { \ - memmove(&r->u8[index], &b->u8[8 - sizeof(r->element[0])], \ - sizeof(r->element[0])); \ - } +#define ELEM_ADDR(VEC, IDX, SIZE) (&(VEC)->u8[IDX]) #else -#define VINSERT(suffix, element) \ - void helper_vinsert##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \ - { \ - uint32_t d = (16 - index) - sizeof(r->element[0]); \ - memmove(&r->u8[d], &b->u8[8], sizeof(r->element[0])); \ - } +#define ELEM_ADDR(VEC, IDX, SIZE) (&(VEC)->u8[15 - (IDX)] - (SIZE) + 1) #endif -VINSERT(b, u8) -VINSERT(h, u16) -VINSERT(w, u32) -VINSERT(d, u64) -#undef VINSERT + +#define VINSX(SUFFIX, TYPE) \ +void glue(glue(helper_VINS, SUFFIX), LX)(CPUPPCState *env, ppc_avr_t *t, \ + uint64_t val, target_ulong index) \ +{ \ + const int maxidx = ARRAY_SIZE(t->u8) - sizeof(TYPE); \ + target_long idx = index; \ + \ + if (idx < 0 || idx > maxidx) { \ + idx = idx < 0 ? sizeof(TYPE) - idx : idx; \ + qemu_log_mask(LOG_GUEST_ERROR, \ + "Invalid index for Vector Insert Element after 0x" TARGET_FMT_lx \ + ", RA = " TARGET_FMT_ld " > %d\n", env->nip, idx, maxidx); \ + } else { \ + TYPE src = val; \ + memcpy(ELEM_ADDR(t, idx, sizeof(TYPE)), &src, sizeof(TYPE)); \ + } \ +} +VINSX(B, uint8_t) +VINSX(H, uint16_t) +VINSX(W, uint32_t) +VINSX(D, uint64_t) +#undef ELEM_ADDR +#undef VINSX +#if defined(HOST_WORDS_BIGENDIAN) +#define VEXTDVLX(NAME, SIZE) \ +void helper_##NAME(CPUPPCState *env, ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, \ + target_ulong index) \ +{ \ + const target_long idx = index; \ + ppc_avr_t tmp[2] = { *a, *b }; \ + memset(t, 0, sizeof(*t)); \ + if (idx >= 0 && idx + SIZE <= sizeof(tmp)) { \ + memcpy(&t->u8[ARRAY_SIZE(t->u8) / 2 - SIZE], (void *)tmp + idx, SIZE); \ + } else { \ + qemu_log_mask(LOG_GUEST_ERROR, "Invalid index for " #NAME " after 0x" \ + TARGET_FMT_lx ", RC = " TARGET_FMT_ld " > %d\n", \ + env->nip, idx < 0 ? SIZE - idx : idx, 32 - SIZE); \ + } \ +} +#else +#define VEXTDVLX(NAME, SIZE) \ +void helper_##NAME(CPUPPCState *env, ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, \ + target_ulong index) \ +{ \ + const target_long idx = index; \ + ppc_avr_t tmp[2] = { *b, *a }; \ + memset(t, 0, sizeof(*t)); \ + if (idx >= 0 && idx + SIZE <= sizeof(tmp)) { \ + memcpy(&t->u8[ARRAY_SIZE(t->u8) / 2], \ + (void *)tmp + sizeof(tmp) - SIZE - idx, SIZE); \ + } else { \ + qemu_log_mask(LOG_GUEST_ERROR, "Invalid index for " #NAME " after 0x" \ + TARGET_FMT_lx ", RC = " TARGET_FMT_ld " > %d\n", \ + env->nip, idx < 0 ? SIZE - idx : idx, 32 - SIZE); \ + } \ +} +#endif +VEXTDVLX(VEXTDUBVLX, 1) +VEXTDVLX(VEXTDUHVLX, 2) +VEXTDVLX(VEXTDUWVLX, 4) +VEXTDVLX(VEXTDDVLX, 8) +#undef VEXTDVLX #if defined(HOST_WORDS_BIGENDIAN) #define VEXTRACT(suffix, element) \ void helper_vextract##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \ @@ -1653,6 +1737,21 @@ void helper_xxinsertw(CPUPPCState *env, ppc_vsr_t *xt, *xt = t; } +#define XXBLEND(name, sz) \ +void glue(helper_XXBLENDV, name)(ppc_avr_t *t, ppc_avr_t *a, ppc_avr_t *b, \ + ppc_avr_t *c, uint32_t desc) \ +{ \ + for (int i = 0; i < ARRAY_SIZE(t->glue(u, sz)); i++) { \ + t->glue(u, sz)[i] = (c->glue(s, sz)[i] >> (sz - 1)) ? \ + b->glue(u, sz)[i] : a->glue(u, sz)[i]; \ + } \ +} +XXBLEND(B, 8) +XXBLEND(H, 16) +XXBLEND(W, 32) +XXBLEND(D, 64) +#undef XXBLEND + #define VEXT_SIGNED(name, element, cast) \ void helper_##name(ppc_avr_t *r, ppc_avr_t *b) \ { \ |