Message ID | 52694896.5040304@gmail.com |
---|---|
State | New |
Headers | show |
On 10/24/2013 09:19 AM, Tom Musta wrote: > > +#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \ > +static void gen_##name(DisasContext * ctx) \ > +{ \ > + TCGv_i32 opc; \ > + if (unlikely(!ctx->vsx_enabled)) { \ > + gen_exception(ctx, POWERPC_EXCP_VSXU); \ > + return; \ > + } \ > + /* NIP cannot be restored if the memory exception comes from an helper */ \ > + gen_update_nip(ctx, ctx->nip - 4); \ > + opc = tcg_const_i32(ctx->opcode); \ > + gen_helper_##name(cpu_env, opc); \ > + tcg_temp_free_i32(opc); \ > +} I'm not a fan of delaying decode to the helpers... You're mostly doing this to avoid passing 3-4 arguments for the register numbers? r~
On 10/24/2013 1:51 PM, Richard Henderson wrote: > On 10/24/2013 09:19 AM, Tom Musta wrote: >> >> +#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \ >> +static void gen_##name(DisasContext * ctx) \ >> +{ \ >> + TCGv_i32 opc; \ >> + if (unlikely(!ctx->vsx_enabled)) { \ >> + gen_exception(ctx, POWERPC_EXCP_VSXU); \ >> + return; \ >> + } \ >> + /* NIP cannot be restored if the memory exception comes from an helper */ \ >> + gen_update_nip(ctx, ctx->nip - 4); \ >> + opc = tcg_const_i32(ctx->opcode); \ >> + gen_helper_##name(cpu_env, opc); \ >> + tcg_temp_free_i32(opc); \ >> +} > > I'm not a fan of delaying decode to the helpers... > > You're mostly doing this to avoid passing 3-4 arguments > for the register numbers? Because the VSRs are 128 bits wide and because there is an interesting relationship with the FPRs and AVRs, passing 6 or more arguments would typically be required (2 per VSR). And, they would need to be stitched back together into a single structure in order to use the loops in the vector routines. I did prototype something like this and didn't like it. Unless you are suggesting that the decoded VSR index (0..63) be passed to the helper?
On 10/24/2013 01:42 PM, Tom Musta wrote: > > Unless you are suggesting that the decoded VSR index (0..63) be passed to the > helper? It was a thought. I'll leave the ultimate decision to ppc maintainers. The insns setting cr6 and crf[BF] get more complicated, but in general those could be handled by returning the cc value that should be stored, and have tcg code actually assign the field. r~
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c index f0b0a49..cea94ac 100644 --- a/target-ppc/fpu_helper.c +++ b/target-ppc/fpu_helper.c @@ -1717,3 +1717,44 @@ uint32_t helper_efdcmpeq(CPUPPCState *env, uint64_t op1, uint64_t op2) /* XXX: TODO: test special values (NaN, infinites, ...) */ return helper_efdtsteq(env, op1, op2); } + +#define DECODE_SPLIT(opcode, shift1, nb1, shift2, nb2) \ + (((((opcode) >> (shift1)) & ((1 << (nb1)) - 1)) << nb2) | \ + (((opcode) >> (shift2)) & ((1 << (nb2)) - 1))) + +#define xT(opcode) DECODE_SPLIT(opcode, 0, 1, 21, 5) +#define xA(opcode) DECODE_SPLIT(opcode, 2, 1, 16, 5) +#define xB(opcode) DECODE_SPLIT(opcode, 1, 1, 11, 5) +#define xC(opcode) DECODE_SPLIT(opcode, 3, 1, 6, 5) +#define BF(opcode) (((opcode) >> (31-8)) & 7) + +typedef union _ppc_vsr_t { + uint64_t u64[2]; + uint32_t u32[4]; + float32 f32[4]; + float64 f64[2]; +} ppc_vsr_t; + +static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) +{ + if (n < 32) { + vsr->f64[0] = env->fpr[n]; + vsr->u64[1] = env->vsr[n]; + } else { + vsr->u64[0] = env->avr[n-32].u64[0]; + vsr->u64[1] = env->avr[n-32].u64[1]; + } +} + +static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) +{ + if (n < 32) { + env->fpr[n] = vsr->f64[0]; + env->vsr[n] = vsr->u64[1]; + } else { + env->avr[n-32].u64[0] = vsr->u64[0]; + env->avr[n-32].u64[1] = vsr->u64[1]; + } +} + +#define float64_to_float64(x, env) x diff --git a/target-ppc/translate.c b/target-ppc/translate.c index ef57bae..5b51c0c 100644 --- a/target-ppc/translate.c +++ b/target-ppc/translate.c @@ -7278,6 +7278,20 @@ VSX_VECTOR_MOVE(xvnabssp, OP_NABS, SGN_MASK_SP) VSX_VECTOR_MOVE(xvnegsp, OP_NEG, SGN_MASK_SP) VSX_VECTOR_MOVE(xvcpsgnsp, OP_CPSGN, SGN_MASK_SP) +#define GEN_VSX_HELPER_2(name, op1, op2, inval, type) \ +static void gen_##name(DisasContext * ctx) \ +{ \ + TCGv_i32 opc; \ + if (unlikely(!ctx->vsx_enabled)) { \ + gen_exception(ctx, POWERPC_EXCP_VSXU); \ + return; \ + } \ + /* NIP cannot be restored if the memory exception comes from an helper */ \ + gen_update_nip(ctx, ctx->nip - 4); \ + opc = tcg_const_i32(ctx->opcode); \ + gen_helper_##name(cpu_env, opc); \ + tcg_temp_free_i32(opc); \ +} #define VSX_LOGICAL(name, tcg_op) \ static void glue(gen_, name)(DisasContext * ctx) \
This patch adds general support that will be used by the VSX helper routines: - a union describing the various VSR subfields. - access routines to get and set VSRs - VSX decoders - a general routine to generate a handler that invokes a VSX helper. Signed-off-by: Tom Musta <tommusta@gmail.com> --- target-ppc/fpu_helper.c | 41 +++++++++++++++++++++++++++++++++++++++++ target-ppc/translate.c | 14 ++++++++++++++ 2 files changed, 55 insertions(+), 0 deletions(-)