Skip to content

Commit

Permalink
target-ppc: Add VSX ISA2.06 xtdiv Instructions
Browse files Browse the repository at this point in the history
This patch adds the VSX floating point test for software divide
instructions defined by V2.06 of the PowerPC ISA: xstdivdp, xvtdivdp,
and xvtdivsp.

Signed-off-by: Tom Musta <tommusta@gmail.com>
Reviewed-by: Richard Henderson <rth@twiddle.net>
Signed-off-by: Alexander Graf <agraf@suse.de>
  • Loading branch information
Tom Musta authored and agraf committed Mar 5, 2014
1 parent d3f9df8 commit bc80838
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 0 deletions.
67 changes: 67 additions & 0 deletions target-ppc/fpu_helper.c
Expand Up @@ -2028,3 +2028,70 @@ void helper_##op(CPUPPCState *env, uint32_t opcode) \
VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1)
VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0)
VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0)

static inline int ppc_float32_get_unbiased_exp(float32 f)
{
return ((f >> 23) & 0xFF) - 127;
}

static inline int ppc_float64_get_unbiased_exp(float64 f)
{
return ((f >> 52) & 0x7FF) - 1023;
}

/* VSX_TDIV - VSX floating point test for divide
* op - instruction mnemonic
* nels - number of elements (1, 2 or 4)
* tp - type (float32 or float64)
* fld - vsr_t field (f32 or f64)
* emin - minimum unbiased exponent
* emax - maximum unbiased exponent
* nbits - number of fraction bits
*/
#define VSX_TDIV(op, nels, tp, fld, emin, emax, nbits) \
void helper_##op(CPUPPCState *env, uint32_t opcode) \
{ \
ppc_vsr_t xa, xb; \
int i; \
int fe_flag = 0; \
int fg_flag = 0; \
\
getVSR(xA(opcode), &xa, env); \
getVSR(xB(opcode), &xb, env); \
\
for (i = 0; i < nels; i++) { \
if (unlikely(tp##_is_infinity(xa.fld[i]) || \
tp##_is_infinity(xb.fld[i]) || \
tp##_is_zero(xb.fld[i]))) { \
fe_flag = 1; \
fg_flag = 1; \
} else { \
int e_a = ppc_##tp##_get_unbiased_exp(xa.fld[i]); \
int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]); \
\
if (unlikely(tp##_is_any_nan(xa.fld[i]) || \
tp##_is_any_nan(xb.fld[i]))) { \
fe_flag = 1; \
} else if ((e_b <= emin) || (e_b >= (emax-2))) { \
fe_flag = 1; \
} else if (!tp##_is_zero(xa.fld[i]) && \
(((e_a - e_b) >= emax) || \
((e_a - e_b) <= (emin+1)) || \
(e_a <= (emin+nbits)))) { \
fe_flag = 1; \
} \
\
if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) { \
/* XB is not zero because of the above check and */ \
/* so must be denormalized. */ \
fg_flag = 1; \
} \
} \
} \
\
env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \
}

VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52)
VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52)
VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23)
3 changes: 3 additions & 0 deletions target-ppc/helper.h
Expand Up @@ -258,6 +258,7 @@ DEF_HELPER_2(xsdivdp, void, env, i32)
DEF_HELPER_2(xsredp, void, env, i32)
DEF_HELPER_2(xssqrtdp, void, env, i32)
DEF_HELPER_2(xsrsqrtedp, void, env, i32)
DEF_HELPER_2(xstdivdp, void, env, i32)

DEF_HELPER_2(xvadddp, void, env, i32)
DEF_HELPER_2(xvsubdp, void, env, i32)
Expand All @@ -266,6 +267,7 @@ DEF_HELPER_2(xvdivdp, void, env, i32)
DEF_HELPER_2(xvredp, void, env, i32)
DEF_HELPER_2(xvsqrtdp, void, env, i32)
DEF_HELPER_2(xvrsqrtedp, void, env, i32)
DEF_HELPER_2(xvtdivdp, void, env, i32)

DEF_HELPER_2(xvaddsp, void, env, i32)
DEF_HELPER_2(xvsubsp, void, env, i32)
Expand All @@ -274,6 +276,7 @@ DEF_HELPER_2(xvdivsp, void, env, i32)
DEF_HELPER_2(xvresp, void, env, i32)
DEF_HELPER_2(xvsqrtsp, void, env, i32)
DEF_HELPER_2(xvrsqrtesp, void, env, i32)
DEF_HELPER_2(xvtdivsp, void, env, i32)

DEF_HELPER_2(efscfsi, i32, env, i32)
DEF_HELPER_2(efscfui, i32, env, i32)
Expand Down
6 changes: 6 additions & 0 deletions target-ppc/translate.c
Expand Up @@ -7311,6 +7311,7 @@ GEN_VSX_HELPER_2(xsdivdp, 0x00, 0x07, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsredp, 0x14, 0x05, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xssqrtdp, 0x16, 0x04, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xsrsqrtedp, 0x14, 0x04, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xstdivdp, 0x14, 0x07, 0, PPC2_VSX)

GEN_VSX_HELPER_2(xvadddp, 0x00, 0x0C, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvsubdp, 0x00, 0x0D, 0, PPC2_VSX)
Expand All @@ -7319,6 +7320,7 @@ GEN_VSX_HELPER_2(xvdivdp, 0x00, 0x0F, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvredp, 0x14, 0x0D, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvsqrtdp, 0x16, 0x0C, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvrsqrtedp, 0x14, 0x0C, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvtdivdp, 0x14, 0x0F, 0, PPC2_VSX)

GEN_VSX_HELPER_2(xvaddsp, 0x00, 0x08, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvsubsp, 0x00, 0x09, 0, PPC2_VSX)
Expand All @@ -7327,6 +7329,7 @@ GEN_VSX_HELPER_2(xvdivsp, 0x00, 0x0B, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvresp, 0x14, 0x09, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvsqrtsp, 0x16, 0x08, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvrsqrtesp, 0x14, 0x08, 0, PPC2_VSX)
GEN_VSX_HELPER_2(xvtdivsp, 0x14, 0x0B, 0, PPC2_VSX)

#define VSX_LOGICAL(name, tcg_op) \
static void glue(gen_, name)(DisasContext * ctx) \
Expand Down Expand Up @@ -10016,6 +10019,7 @@ GEN_XX3FORM(xsdivdp, 0x00, 0x07, PPC2_VSX),
GEN_XX2FORM(xsredp, 0x14, 0x05, PPC2_VSX),
GEN_XX2FORM(xssqrtdp, 0x16, 0x04, PPC2_VSX),
GEN_XX2FORM(xsrsqrtedp, 0x14, 0x04, PPC2_VSX),
GEN_XX3FORM(xstdivdp, 0x14, 0x07, PPC2_VSX),

GEN_XX3FORM(xvadddp, 0x00, 0x0C, PPC2_VSX),
GEN_XX3FORM(xvsubdp, 0x00, 0x0D, PPC2_VSX),
Expand All @@ -10024,6 +10028,7 @@ GEN_XX3FORM(xvdivdp, 0x00, 0x0F, PPC2_VSX),
GEN_XX2FORM(xvredp, 0x14, 0x0D, PPC2_VSX),
GEN_XX2FORM(xvsqrtdp, 0x16, 0x0C, PPC2_VSX),
GEN_XX2FORM(xvrsqrtedp, 0x14, 0x0C, PPC2_VSX),
GEN_XX3FORM(xvtdivdp, 0x14, 0x0F, PPC2_VSX),

GEN_XX3FORM(xvaddsp, 0x00, 0x08, PPC2_VSX),
GEN_XX3FORM(xvsubsp, 0x00, 0x09, PPC2_VSX),
Expand All @@ -10032,6 +10037,7 @@ GEN_XX3FORM(xvdivsp, 0x00, 0x0B, PPC2_VSX),
GEN_XX2FORM(xvresp, 0x14, 0x09, PPC2_VSX),
GEN_XX2FORM(xvsqrtsp, 0x16, 0x08, PPC2_VSX),
GEN_XX2FORM(xvrsqrtesp, 0x14, 0x08, PPC2_VSX),
GEN_XX3FORM(xvtdivsp, 0x14, 0x0B, PPC2_VSX),

#undef VSX_LOGICAL
#define VSX_LOGICAL(name, opc2, opc3, fl2) \
Expand Down

0 comments on commit bc80838

Please sign in to comment.