diff options
author | Nikunj A Dadhania <nikunj@linux.vnet.ibm.com> | 2016-12-09 17:47:20 +0530 |
---|---|---|
committer | David Gibson <david@gibson.dropbear.id.au> | 2017-01-31 10:10:13 +1100 |
commit | 6914bc4fb5c16cdf92d59e620e3f69de302ed838 (patch) | |
tree | 8f3399b84d293305fe475a231ec91adbc76e59b5 /target/ppc | |
parent | 234068abfb345f08b160be71e0a4099c19384712 (diff) |
target-ppc: implement lxvl instruction
lxvl: Load VSX Vector with Length
Little/Big-endian Storage:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
|“T”|“h”|“i”|“s”|“ ”|“i”|“s”|“ ”|“a”|“ ”|“T”|“E”|“S”|“T”|FF|FF|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
Loading 14 bytes results in:
Vector (8-bit elements) in BE:
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
|“T”|“h”|“i”|“s”|“ ”|“i”|“s”|“ ”|“a”|“ ”|“T”|“E”|“S”|“T”|00|00|
+---+---+---+---+---+---+---+---+---+---+---+---+---+---+--+--+
Vector (8-bit elements) in LE:
+--+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
|00|00|“T”|“S”|“E”|“T”|“ ”|“a”|“ ”|“s”|“i”|“ ”|“s”|“i”|"h"|"T"|
+--+--+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
Signed-off-by: Nikunj A Dadhania <nikunj@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target/ppc')
-rw-r--r-- | target/ppc/helper.h | 3 | ||||
-rw-r--r-- | target/ppc/mem_helper.c | 35 | ||||
-rw-r--r-- | target/ppc/translate/vsx-impl.inc.c | 29 | ||||
-rw-r--r-- | target/ppc/translate/vsx-ops.inc.c | 3 |
4 files changed, 70 insertions, 0 deletions
diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 3257820793..1c7081577d 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -312,6 +312,9 @@ DEF_HELPER_3(lvewx, void, env, avr, tl) DEF_HELPER_3(stvebx, void, env, avr, tl) DEF_HELPER_3(stvehx, void, env, avr, tl) DEF_HELPER_3(stvewx, void, env, avr, tl) +#if defined(TARGET_PPC64) +DEF_HELPER_4(lxvl, void, env, tl, tl, tl) +#endif DEF_HELPER_4(vsumsws, void, env, avr, avr, avr) DEF_HELPER_4(vsum2sws, void, env, avr, avr, avr) DEF_HELPER_4(vsum4sbs, void, env, avr, avr, avr) diff --git a/target/ppc/mem_helper.c b/target/ppc/mem_helper.c index 1ab8a6eab4..c4ddc5be0c 100644 --- a/target/ppc/mem_helper.c +++ b/target/ppc/mem_helper.c @@ -24,6 +24,7 @@ #include "helper_regs.h" #include "exec/cpu_ldst.h" +#include "internal.h" //#define DEBUG_OP @@ -284,6 +285,40 @@ STVE(stvewx, cpu_stl_data_ra, bswap32, u32) #undef I #undef LVE +#ifdef TARGET_PPC64 +#define GET_NB(rb) ((rb >> 56) & 0xFF) + +#define VSX_LXVL(name, lj) \ +void helper_##name(CPUPPCState *env, target_ulong addr, \ + target_ulong xt_num, target_ulong rb) \ +{ \ + int i; \ + ppc_vsr_t xt; \ + uint64_t nb = GET_NB(rb); \ + \ + xt.s128 = int128_zero(); \ + if (nb) { \ + nb = (nb >= 16) ? 16 : nb; \ + if (msr_le && !lj) { \ + for (i = 16; i > 16 - nb; i--) { \ + xt.VsrB(i - 1) = cpu_ldub_data_ra(env, addr, GETPC()); \ + addr = addr_add(env, addr, 1); \ + } \ + } else { \ + for (i = 0; i < nb; i++) { \ + xt.VsrB(i) = cpu_ldub_data_ra(env, addr, GETPC()); \ + addr = addr_add(env, addr, 1); \ + } \ + } \ + } \ + putVSR(xt_num, &xt, env); \ +} + +VSX_LXVL(lxvl, 0) +#undef VSX_LXVL +#undef GET_NB +#endif /* TARGET_PPC64 */ + #undef HI_IDX #undef LO_IDX diff --git a/target/ppc/translate/vsx-impl.inc.c b/target/ppc/translate/vsx-impl.inc.c index 7000035a25..1f64fb7d16 100644 --- a/target/ppc/translate/vsx-impl.inc.c +++ b/target/ppc/translate/vsx-impl.inc.c @@ -240,6 +240,35 @@ VSX_VECTOR_LOAD_STORE(stxv, st_i64, 0) VSX_VECTOR_LOAD_STORE(lxvx, ld_i64, 1) VSX_VECTOR_LOAD_STORE(stxvx, st_i64, 1) +#ifdef TARGET_PPC64 +#define VSX_VECTOR_LOAD_STORE_LENGTH(name) \ +static void gen_##name(DisasContext *ctx) \ +{ \ + TCGv EA, xt; \ + \ + if (xT(ctx->opcode) < 32) { \ + if (unlikely(!ctx->vsx_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VSXU); \ + return; \ + } \ + } else { \ + if (unlikely(!ctx->altivec_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VPU); \ + return; \ + } \ + } \ + EA = tcg_temp_new(); \ + xt = tcg_const_tl(xT(ctx->opcode)); \ + gen_set_access_type(ctx, ACCESS_INT); \ + gen_addr_register(ctx, EA); \ + gen_helper_##name(cpu_env, EA, xt, cpu_gpr[rB(ctx->opcode)]); \ + tcg_temp_free(EA); \ + tcg_temp_free(xt); \ +} + +VSX_VECTOR_LOAD_STORE_LENGTH(lxvl) +#endif + #define VSX_LOAD_SCALAR_DS(name, operation) \ static void gen_##name(DisasContext *ctx) \ { \ diff --git a/target/ppc/translate/vsx-ops.inc.c b/target/ppc/translate/vsx-ops.inc.c index f684066dbe..62a0afc9e9 100644 --- a/target/ppc/translate/vsx-ops.inc.c +++ b/target/ppc/translate/vsx-ops.inc.c @@ -10,6 +10,9 @@ GEN_HANDLER_E(lxvw4x, 0x1F, 0x0C, 0x18, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(lxvh8x, 0x1F, 0x0C, 0x19, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(lxvb16x, 0x1F, 0x0C, 0x1B, 0, PPC_NONE, PPC2_ISA300), GEN_HANDLER_E(lxvx, 0x1F, 0x0C, 0x08, 0x00000040, PPC_NONE, PPC2_ISA300), +#if defined(TARGET_PPC64) +GEN_HANDLER_E(lxvl, 0x1F, 0x0D, 0x08, 0, PPC_NONE, PPC2_ISA300), +#endif GEN_HANDLER_E(stxsdx, 0x1F, 0xC, 0x16, 0, PPC_NONE, PPC2_VSX), GEN_HANDLER_E(stxsibx, 0x1F, 0xD, 0x1C, 0, PPC_NONE, PPC2_ISA300), |