|
|
@ -67,7 +67,7 @@ static struct vfp_single vfp_single_default_qnan = { |
|
|
|
|
|
|
|
|
static void vfp_single_dump(const char *str, struct vfp_single *s) |
|
|
static void vfp_single_dump(const char *str, struct vfp_single *s) |
|
|
{ |
|
|
{ |
|
|
LOG_DEBUG(Core_ARM11, "%s: sign=%d exponent=%d significand=%08x", |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "%s: sign=%d exponent=%d significand=%08x", |
|
|
str, s->sign != 0, s->exponent, s->significand); |
|
|
str, s->sign != 0, s->exponent, s->significand); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -158,7 +158,7 @@ u32 vfp_single_normaliseround(ARMul_State* state, int sd, struct vfp_single *vs, |
|
|
} else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0)) |
|
|
} else if ((rmode == FPSCR_ROUND_PLUSINF) ^ (vs->sign != 0)) |
|
|
incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1; |
|
|
incr = (1 << (VFP_SINGLE_LOW_BITS + 1)) - 1; |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "rounding increment = 0x%08x", incr); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "rounding increment = 0x%08x", incr); |
|
|
|
|
|
|
|
|
/*
|
|
|
/*
|
|
|
* Is our rounding going to overflow? |
|
|
* Is our rounding going to overflow? |
|
|
@ -213,7 +213,7 @@ pack: |
|
|
vfp_single_dump("pack: final", vs); |
|
|
vfp_single_dump("pack: final", vs); |
|
|
{ |
|
|
{ |
|
|
s32 d = vfp_single_pack(vs); |
|
|
s32 d = vfp_single_pack(vs); |
|
|
LOG_DEBUG(Core_ARM11, "%s: d(s%d)=%08x exceptions=%08x", func, |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "%s: d(s%d)=%08x exceptions=%08x", func, |
|
|
sd, d, exceptions); |
|
|
sd, d, exceptions); |
|
|
vfp_put_float(state, d, sd); |
|
|
vfp_put_float(state, d, sd); |
|
|
} |
|
|
} |
|
|
@ -304,7 +304,7 @@ u32 vfp_estimate_sqrt_significand(u32 exponent, u32 significand) |
|
|
u32 z, a; |
|
|
u32 z, a; |
|
|
|
|
|
|
|
|
if ((significand & 0xc0000000) != 0x40000000) { |
|
|
if ((significand & 0xc0000000) != 0x40000000) { |
|
|
LOG_DEBUG(Core_ARM11, "invalid significand"); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "invalid significand"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
a = significand << 1; |
|
|
a = significand << 1; |
|
|
@ -394,7 +394,7 @@ sqrt_invalid: |
|
|
term = (u64)vsd.significand * vsd.significand; |
|
|
term = (u64)vsd.significand * vsd.significand; |
|
|
rem = ((u64)vsm.significand << 32) - term; |
|
|
rem = ((u64)vsm.significand << 32) - term; |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "term=%016" PRIx64 "rem=%016" PRIx64, term, rem); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "term=%016" PRIx64 "rem=%016" PRIx64, term, rem); |
|
|
|
|
|
|
|
|
while (rem < 0) { |
|
|
while (rem < 0) { |
|
|
vsd.significand -= 1; |
|
|
vsd.significand -= 1; |
|
|
@ -626,7 +626,7 @@ static u32 vfp_single_ftoui(ARMul_State* state, int sd, int unused, s32 m, u32 f |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "ftoui: d(s%d)=%08x exceptions=%08x", sd, d, exceptions); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "ftoui: d(s%d)=%08x exceptions=%08x", sd, d, exceptions); |
|
|
|
|
|
|
|
|
vfp_put_float(state, d, sd); |
|
|
vfp_put_float(state, d, sd); |
|
|
|
|
|
|
|
|
@ -705,7 +705,7 @@ static u32 vfp_single_ftosi(ARMul_State* state, int sd, int unused, s32 m, u32 f |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "ftosi: d(s%d)=%08x exceptions=%08x", sd, d, exceptions); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "ftosi: d(s%d)=%08x exceptions=%08x", sd, d, exceptions); |
|
|
|
|
|
|
|
|
vfp_put_float(state, (s32)d, sd); |
|
|
vfp_put_float(state, (s32)d, sd); |
|
|
|
|
|
|
|
|
@ -873,7 +873,7 @@ vfp_single_multiply(struct vfp_single *vsd, struct vfp_single *vsn, struct vfp_s |
|
|
struct vfp_single *t = vsn; |
|
|
struct vfp_single *t = vsn; |
|
|
vsn = vsm; |
|
|
vsn = vsm; |
|
|
vsm = t; |
|
|
vsm = t; |
|
|
LOG_DEBUG(Core_ARM11, "swapping M <-> N"); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "swapping M <-> N"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
vsd->sign = vsn->sign ^ vsm->sign; |
|
|
vsd->sign = vsn->sign ^ vsm->sign; |
|
|
@ -926,7 +926,7 @@ vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fp |
|
|
s32 v; |
|
|
s32 v; |
|
|
|
|
|
|
|
|
v = vfp_get_float(state, sn); |
|
|
v = vfp_get_float(state, sn); |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, v); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, v); |
|
|
vfp_single_unpack(&vsn, v, &fpscr); |
|
|
vfp_single_unpack(&vsn, v, &fpscr); |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
vfp_single_normalise_denormal(&vsn); |
|
|
vfp_single_normalise_denormal(&vsn); |
|
|
@ -941,7 +941,7 @@ vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fp |
|
|
vsp.sign = vfp_sign_negate(vsp.sign); |
|
|
vsp.sign = vfp_sign_negate(vsp.sign); |
|
|
|
|
|
|
|
|
v = vfp_get_float(state, sd); |
|
|
v = vfp_get_float(state, sd); |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sd, v); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sd, v); |
|
|
vfp_single_unpack(&vsn, v, &fpscr); |
|
|
vfp_single_unpack(&vsn, v, &fpscr); |
|
|
if (vsn.exponent == 0 && vsn.significand != 0) |
|
|
if (vsn.exponent == 0 && vsn.significand != 0) |
|
|
vfp_single_normalise_denormal(&vsn); |
|
|
vfp_single_normalise_denormal(&vsn); |
|
|
@ -963,7 +963,7 @@ vfp_single_multiply_accumulate(ARMul_State* state, int sd, int sn, s32 m, u32 fp |
|
|
*/ |
|
|
*/ |
|
|
static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
{ |
|
|
{ |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, 0, "fmac"); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, 0, "fmac"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -973,7 +973,7 @@ static u32 vfp_single_fmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
{ |
|
|
{ |
|
|
// TODO: this one has its arguments inverted, investigate.
|
|
|
// TODO: this one has its arguments inverted, investigate.
|
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sd, sn); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sd, sn); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_MULTIPLY, "fnmac"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -982,7 +982,7 @@ static u32 vfp_single_fnmac(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr |
|
|
*/ |
|
|
*/ |
|
|
static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
{ |
|
|
{ |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT, "fmsc"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -991,7 +991,7 @@ static u32 vfp_single_fmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
*/ |
|
|
*/ |
|
|
static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fnmsc(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
{ |
|
|
{ |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); |
|
|
return vfp_single_multiply_accumulate(state, sd, sn, m, fpscr, NEG_SUBTRACT | NEG_MULTIPLY, "fnmsc"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
@ -1004,7 +1004,7 @@ static u32 vfp_single_fmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
u32 exceptions; |
|
|
u32 exceptions; |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
@ -1027,7 +1027,7 @@ static u32 vfp_single_fnmul(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr |
|
|
u32 exceptions; |
|
|
u32 exceptions; |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
if (vsn.exponent == 0 && vsn.significand) |
|
|
@ -1051,7 +1051,7 @@ static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
u32 exceptions; |
|
|
u32 exceptions; |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
/*
|
|
|
/*
|
|
|
* Unpack and normalise denormals. |
|
|
* Unpack and normalise denormals. |
|
|
@ -1074,7 +1074,7 @@ static u32 vfp_single_fadd(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
*/ |
|
|
*/ |
|
|
static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
static u32 vfp_single_fsub(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
{ |
|
|
{ |
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, sd); |
|
|
/*
|
|
|
/*
|
|
|
* Subtraction is addition with one sign inverted. |
|
|
* Subtraction is addition with one sign inverted. |
|
|
*/ |
|
|
*/ |
|
|
@ -1094,7 +1094,7 @@ static u32 vfp_single_fdiv(ARMul_State* state, int sd, int sn, s32 m, u32 fpscr) |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
s32 n = vfp_get_float(state, sn); |
|
|
int tm, tn; |
|
|
int tm, tn; |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "s%u = %08x", sn, n); |
|
|
|
|
|
|
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
vfp_single_unpack(&vsn, n, &fpscr); |
|
|
vfp_single_unpack(&vsm, m, &fpscr); |
|
|
vfp_single_unpack(&vsm, m, &fpscr); |
|
|
@ -1241,7 +1241,7 @@ u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) |
|
|
else |
|
|
else |
|
|
veclen = fpscr & FPSCR_LENGTH_MASK; |
|
|
veclen = fpscr & FPSCR_LENGTH_MASK; |
|
|
|
|
|
|
|
|
LOG_DEBUG(Core_ARM11, "vecstride=%u veclen=%u", vecstride, |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "vecstride=%u veclen=%u", vecstride, |
|
|
(veclen >> FPSCR_LENGTH_BIT) + 1); |
|
|
(veclen >> FPSCR_LENGTH_BIT) + 1); |
|
|
|
|
|
|
|
|
if (!fop->fn) { |
|
|
if (!fop->fn) { |
|
|
@ -1257,16 +1257,16 @@ u32 vfp_single_cpdo(ARMul_State* state, u32 inst, u32 fpscr) |
|
|
|
|
|
|
|
|
type = (fop->flags & OP_DD) ? 'd' : 's'; |
|
|
type = (fop->flags & OP_DD) ? 'd' : 's'; |
|
|
if (op == FOP_EXT) |
|
|
if (op == FOP_EXT) |
|
|
LOG_DEBUG(Core_ARM11, "itr%d (%c%u) = op[%u] (s%u=%08x)", |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "itr%d (%c%u) = op[%u] (s%u=%08x)", |
|
|
vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, |
|
|
vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, |
|
|
sm, m); |
|
|
sm, m); |
|
|
else |
|
|
else |
|
|
LOG_DEBUG(Core_ARM11, "itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)", |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "itr%d (%c%u) = (s%u) op[%u] (s%u=%08x)", |
|
|
vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, |
|
|
vecitr >> FPSCR_LENGTH_BIT, type, dest, sn, |
|
|
FOP_TO_IDX(op), sm, m); |
|
|
FOP_TO_IDX(op), sm, m); |
|
|
|
|
|
|
|
|
except = fop->fn(state, dest, sn, m, fpscr); |
|
|
except = fop->fn(state, dest, sn, m, fpscr); |
|
|
LOG_DEBUG(Core_ARM11, "itr%d: exceptions=%08x", |
|
|
|
|
|
|
|
|
LOG_TRACE(Core_ARM11, "itr%d: exceptions=%08x", |
|
|
vecitr >> FPSCR_LENGTH_BIT, except); |
|
|
vecitr >> FPSCR_LENGTH_BIT, except); |
|
|
|
|
|
|
|
|
exceptions |= except; |
|
|
exceptions |= except; |
|
|
|