aboutsummaryrefslogtreecommitdiff
path: root/target/ppc/int_helper.c
diff options
context:
space:
mode:
authorMatheus Ferst <matheus.ferst@eldorado.org.br>2021-11-04 09:36:59 -0300
committerDavid Gibson <david@gibson.dropbear.id.au>2021-11-09 10:32:52 +1100
commit2cc12af399d6f8abb8433ef7f7e75ece177d4d39 (patch)
treef97a0ad0bb3307240eed0f6dd71fe6721bbbd231 /target/ppc/int_helper.c
parent2c716b4da5251aa8428bd3a9a4a5cc6a6c2c5c89 (diff)
downloadqemu-2cc12af399d6f8abb8433ef7f7e75ece177d4d39.zip
qemu-2cc12af399d6f8abb8433ef7f7e75ece177d4d39.tar.gz
qemu-2cc12af399d6f8abb8433ef7f7e75ece177d4d39.tar.bz2
target/ppc: Implement Vector Insert from GPR using GPR index insns
Implements the following PowerISA v3.1 instructions: vinsblx: Vector Insert Byte from GPR using GPR-specified Left-Index vinshlx: Vector Insert Halfword from GPR using GPR-specified Left-Index vinswlx: Vector Insert Word from GPR using GPR-specified Left-Index vinsdlx: Vector Insert Doubleword from GPR using GPR-specified Left-Index vinsbrx: Vector Insert Byte from GPR using GPR-specified Right-Index vinshrx: Vector Insert Halfword from GPR using GPR-specified Right-Index vinswrx: Vector Insert Word from GPR using GPR-specified Right-Index vinsdrx: Vector Insert Doubleword from GPR using GPR-specified Right-Index The helpers and do_vinsx receive i64 to allow code sharing with the future implementation of Vector Insert from VSR using GPR Index. Signed-off-by: Matheus Ferst <matheus.ferst@eldorado.org.br> Message-Id: <20211104123719.323713-6-matheus.ferst@eldorado.org.br> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc/int_helper.c')
-rw-r--r--target/ppc/int_helper.c30
1 files changed, 30 insertions, 0 deletions
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index 4254173..80b7f88 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1632,6 +1632,36 @@ VINSERT(h, u16)
VINSERT(w, u32)
VINSERT(d, u64)
#undef VINSERT
+
+#if defined(HOST_WORDS_BIGENDIAN)
+#define ELEM_ADDR(VEC, IDX, SIZE) (&(VEC)->u8[IDX])
+#else
+#define ELEM_ADDR(VEC, IDX, SIZE) (&(VEC)->u8[15 - (IDX)] - (SIZE) + 1)
+#endif
+
+#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 VEXTRACT(suffix, element) \
void helper_vextract##suffix(ppc_avr_t *r, ppc_avr_t *b, uint32_t index) \