Commit 23d0766b authored by Mark Cave-Ayland's avatar Mark Cave-Ayland Committed by David Gibson
Browse files

target/ppc: introduce GEN_VSX_HELPER_R3 macro to fpu_helper.c



Rather than perform the VSR register decoding within the helper itself,
introduce a new GEN_VSX_HELPER_R3 macro which performs the decode based
upon rD, rA and rB at translation time.

Signed-off-by: default avatarMark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
Reviewed-by: default avatarRichard Henderson <richard.henderson@linaro.org>
Message-Id: <20190616123751.781-11-mark.cave-ayland@ilande.co.uk>
Signed-off-by: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 8d830485
Loading
Loading
Loading
Loading
+12 −24
Original line number Diff line number Diff line
@@ -1842,11 +1842,9 @@ VSX_ADD_SUB(xssubsp, sub, 1, float64, VsrD(0), 1, 1)
VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0)
VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0)

void helper_xsaddqp(CPUPPCState *env, uint32_t opcode)
void helper_xsaddqp(CPUPPCState *env, uint32_t opcode,
                    ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
    ppc_vsr_t t = *xt;
    float_status tstat;

@@ -1920,11 +1918,9 @@ VSX_MUL(xsmulsp, 1, float64, VsrD(0), 1, 1)
VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0)
VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0)

void helper_xsmulqp(CPUPPCState *env, uint32_t opcode)
void helper_xsmulqp(CPUPPCState *env, uint32_t opcode,
                    ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
    ppc_vsr_t t = *xt;
    float_status tstat;

@@ -1999,11 +1995,9 @@ VSX_DIV(xsdivsp, 1, float64, VsrD(0), 1, 1)
VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0)
VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0)

void helper_xsdivqp(CPUPPCState *env, uint32_t opcode)
void helper_xsdivqp(CPUPPCState *env, uint32_t opcode,
                    ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
    ppc_vsr_t t = *xt;
    float_status tstat;

@@ -2620,11 +2614,9 @@ VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i))
VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i))

#define VSX_MAX_MINC(name, max)                                               \
void helper_##name(CPUPPCState *env, uint32_t opcode)                         \
void helper_##name(CPUPPCState *env, uint32_t opcode,                         \
                   ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)               \
{                                                                             \
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];                               \
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];                               \
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];                               \
    ppc_vsr_t t = *xt;                                                        \
    bool vxsnan_flag = false, vex_flag = false;                               \
                                                                              \
@@ -2657,11 +2649,9 @@ VSX_MAX_MINC(xsmaxcdp, 1);
VSX_MAX_MINC(xsmincdp, 0);

#define VSX_MAX_MINJ(name, max)                                               \
void helper_##name(CPUPPCState *env, uint32_t opcode)                         \
void helper_##name(CPUPPCState *env, uint32_t opcode,                         \
                   ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)               \
{                                                                             \
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];                               \
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];                               \
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];                               \
    ppc_vsr_t t = *xt;                                                        \
    bool vxsnan_flag = false, vex_flag = false;                               \
                                                                              \
@@ -3436,11 +3426,9 @@ void helper_xssqrtqp(CPUPPCState *env, uint32_t opcode)
    do_float_check_status(env, GETPC());
}

void helper_xssubqp(CPUPPCState *env, uint32_t opcode)
void helper_xssubqp(CPUPPCState *env, uint32_t opcode,
                    ppc_vsr_t *xt, ppc_vsr_t *xa, ppc_vsr_t *xb)
{
    ppc_vsr_t *xt = &env->vsr[rD(opcode) + 32];
    ppc_vsr_t *xa = &env->vsr[rA(opcode) + 32];
    ppc_vsr_t *xb = &env->vsr[rB(opcode) + 32];
    ppc_vsr_t t = *xt;
    float_status tstat;

+8 −8
Original line number Diff line number Diff line
@@ -366,12 +366,12 @@ DEF_HELPER_4(bcdtrunc, i32, avr, avr, avr, i32)
DEF_HELPER_4(bcdutrunc, i32, avr, avr, avr, i32)

DEF_HELPER_4(xsadddp, void, env, vsr, vsr, vsr)
DEF_HELPER_2(xsaddqp, void, env, i32)
DEF_HELPER_5(xsaddqp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_4(xssubdp, void, env, vsr, vsr, vsr)
DEF_HELPER_4(xsmuldp, void, env, vsr, vsr, vsr)
DEF_HELPER_2(xsmulqp, void, env, i32)
DEF_HELPER_5(xsmulqp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_4(xsdivdp, void, env, vsr, vsr, vsr)
DEF_HELPER_2(xsdivqp, void, env, i32)
DEF_HELPER_5(xsdivqp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_3(xsredp, void, env, vsr, vsr)
DEF_HELPER_3(xssqrtdp, void, env, vsr, vsr)
DEF_HELPER_3(xsrsqrtedp, void, env, vsr, vsr)
@@ -397,10 +397,10 @@ DEF_HELPER_2(xscmpoqp, void, env, i32)
DEF_HELPER_2(xscmpuqp, void, env, i32)
DEF_HELPER_4(xsmaxdp, void, env, vsr, vsr, vsr)
DEF_HELPER_4(xsmindp, void, env, vsr, vsr, vsr)
DEF_HELPER_2(xsmaxcdp, void, env, i32)
DEF_HELPER_2(xsmincdp, void, env, i32)
DEF_HELPER_2(xsmaxjdp, void, env, i32)
DEF_HELPER_2(xsminjdp, void, env, i32)
DEF_HELPER_5(xsmaxcdp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_5(xsmincdp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_5(xsmaxjdp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_5(xsminjdp, void, env, i32, vsr, vsr, vsr)
DEF_HELPER_3(xscvdphp, void, env, vsr, vsr)
DEF_HELPER_2(xscvdpqp, void, env, i32)
DEF_HELPER_3(xscvdpsp, void, env, vsr, vsr)
@@ -434,7 +434,7 @@ DEF_HELPER_3(xsrdpiz, void, env, vsr, vsr)
DEF_HELPER_2(xsrqpi, void, env, i32)
DEF_HELPER_2(xsrqpxp, void, env, i32)
DEF_HELPER_2(xssqrtqp, void, env, i32)
DEF_HELPER_2(xssubqp, void, env, i32)
DEF_HELPER_5(xssubqp, void, env, i32, vsr, vsr, vsr)

DEF_HELPER_4(xsaddsp, void, env, vsr, vsr, vsr)
DEF_HELPER_4(xssubsp, void, env, vsr, vsr, vsr)
+28 −8
Original line number Diff line number Diff line
@@ -1095,6 +1095,26 @@ static void gen_##name(DisasContext *ctx) \
    tcg_temp_free_ptr(xb);                                                    \
}

#define GEN_VSX_HELPER_R3(name, op1, op2, inval, type)                        \
static void gen_##name(DisasContext *ctx)                                     \
{                                                                             \
    TCGv_i32 opc;                                                             \
    TCGv_ptr xt, xa, xb;                                                      \
    if (unlikely(!ctx->vsx_enabled)) {                                        \
        gen_exception(ctx, POWERPC_EXCP_VSXU);                                \
        return;                                                               \
    }                                                                         \
    opc = tcg_const_i32(ctx->opcode);                                         \
    xt = gen_vsr_ptr(rD(ctx->opcode) + 32);                                   \
    xa = gen_vsr_ptr(rA(ctx->opcode) + 32);                                   \
    xb = gen_vsr_ptr(rB(ctx->opcode) + 32);                                   \
    gen_helper_##name(cpu_env, opc, xt, xa, xb);                              \
    tcg_temp_free_i32(opc);                                                   \
    tcg_temp_free_ptr(xt);                                                    \
    tcg_temp_free_ptr(xa);                                                    \
    tcg_temp_free_ptr(xb);                                                    \
}

#define GEN_VSX_HELPER_XT_XB_ENV(name, op1, op2, inval, type) \
static void gen_##name(DisasContext *ctx)                     \
{                                                             \
@@ -1114,12 +1134,12 @@ static void gen_##name(DisasContext *ctx) \
}

GEN_VSX_HELPER_X3(xsadddp, 0x00, 0x04, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsaddqp, 0x04, 0x00, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsaddqp, 0x04, 0x00, 0, PPC2_ISA300)
GEN_VSX_HELPER_X3(xssubdp, 0x00, 0x05, 0, PPC2_VSX)
GEN_VSX_HELPER_X3(xsmuldp, 0x00, 0x06, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsmulqp, 0x04, 0x01, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsmulqp, 0x04, 0x01, 0, PPC2_ISA300)
GEN_VSX_HELPER_X3(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsdivqp, 0x04, 0x11, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsdivqp, 0x04, 0x11, 0, PPC2_ISA300)
GEN_VSX_HELPER_X2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
GEN_VSX_HELPER_X2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
GEN_VSX_HELPER_X2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
@@ -1145,10 +1165,10 @@ GEN_VSX_HELPER_2(xscmpoqp, 0x04, 0x04, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xscmpuqp, 0x04, 0x14, 0, PPC2_VSX)
GEN_VSX_HELPER_X3(xsmaxdp, 0x00, 0x14, 0, PPC2_VSX)
GEN_VSX_HELPER_X3(xsmindp, 0x00, 0x15, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300)
GEN_VSX_HELPER_2(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300)
GEN_VSX_HELPER_2(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300)
GEN_VSX_HELPER_2(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsmaxcdp, 0x00, 0x10, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsmincdp, 0x00, 0x11, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsmaxjdp, 0x00, 0x12, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xsminjdp, 0x00, 0x12, 0, PPC2_ISA300)
GEN_VSX_HELPER_X2(xscvdphp, 0x16, 0x15, 0x11, PPC2_ISA300)
GEN_VSX_HELPER_X2(xscvdpsp, 0x12, 0x10, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xscvdpqp, 0x04, 0x1A, 0x16, PPC2_ISA300)
@@ -1178,7 +1198,7 @@ GEN_VSX_HELPER_XT_XB_ENV(xsrsp, 0x12, 0x11, 0, PPC2_VSX207)
GEN_VSX_HELPER_2(xsrqpi, 0x05, 0x00, 0, PPC2_ISA300)
GEN_VSX_HELPER_2(xsrqpxp, 0x05, 0x01, 0, PPC2_ISA300)
GEN_VSX_HELPER_2(xssqrtqp, 0x04, 0x19, 0x1B, PPC2_ISA300)
GEN_VSX_HELPER_2(xssubqp, 0x04, 0x10, 0, PPC2_ISA300)
GEN_VSX_HELPER_R3(xssubqp, 0x04, 0x10, 0, PPC2_ISA300)

GEN_VSX_HELPER_X3(xsaddsp, 0x00, 0x00, 0, PPC2_VSX207)
GEN_VSX_HELPER_X3(xssubsp, 0x00, 0x01, 0, PPC2_VSX207)