X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=target-ppc%2Fop_helper.c;h=3afd217bc207dda138e6d4d9e555cc1245e04a71;hb=c7eb95e1180c524a9ef97e3fdfc8ad5d40b0cebb;hp=eb155aa50f0593ea7ed8c694e21847b067c7cce7;hpb=1add6e234a1cb25e951fb161f144d294ac2cfd05;p=qemu diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c index eb155aa..3afd217 100644 --- a/target-ppc/op_helper.c +++ b/target-ppc/op_helper.c @@ -28,6 +28,13 @@ //#define DEBUG_EXCEPTIONS //#define DEBUG_SOFTWARE_TLB +#ifdef DEBUG_SOFTWARE_TLB +# define LOG_SWTLB(...) qemu_log(__VA_ARGS__) +#else +# define LOG_SWTLB(...) do { } while (0) +#endif + + /*****************************************************************************/ /* Exceptions processing helpers */ @@ -74,18 +81,14 @@ void helper_store_cr (target_ulong val, uint32_t mask) /* SPR accesses */ void helper_load_dump_spr (uint32_t sprn) { - if (loglevel != 0) { - fprintf(logfile, "Read SPR %d %03x => " ADDRX "\n", + qemu_log("Read SPR %d %03x => " ADDRX "\n", sprn, sprn, env->spr[sprn]); - } } void helper_store_dump_spr (uint32_t sprn) { - if (loglevel != 0) { - fprintf(logfile, "Write SPR %d %03x <= " ADDRX "\n", + qemu_log("Write SPR %d %03x <= " ADDRX "\n", sprn, sprn, env->spr[sprn]); - } } target_ulong helper_load_tbl (void) @@ -182,10 +185,8 @@ void helper_store_hid0_601 (target_ulong val) env->hflags_nmsr &= ~(1 << MSR_LE); env->hflags_nmsr |= (1 << MSR_LE) & (((val >> 3) & 1) << MSR_LE); env->hflags |= env->hflags_nmsr; - if (loglevel != 0) { - fprintf(logfile, "%s: set endianness to %c => " ADDRX "\n", + qemu_log("%s: set endianness to %c => " ADDRX "\n", __func__, val & 0x8 ? 'l' : 'b', env->hflags); - } } env->spr[SPR_HID0] = (uint32_t)val; } @@ -1500,15 +1501,14 @@ uint64_t helper_fsqrt (uint64_t arg) /* fre - fre. */ uint64_t helper_fre (uint64_t arg) { - CPU_DoubleU fone, farg; - fone.ll = 0x3FF0000000000000ULL; /* 1.0 */ + CPU_DoubleU farg; farg.ll = arg; if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN reciprocal */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } else { - farg.d = float64_div(fone.d, farg.d, &env->fp_status); + farg.d = float64_div(float64_one, farg.d, &env->fp_status); } return farg.d; } @@ -1516,16 +1516,15 @@ uint64_t helper_fre (uint64_t arg) /* fres - fres. */ uint64_t helper_fres (uint64_t arg) { - CPU_DoubleU fone, farg; + CPU_DoubleU farg; float32 f32; - fone.ll = 0x3FF0000000000000ULL; /* 1.0 */ farg.ll = arg; if (unlikely(float64_is_signaling_nan(farg.d))) { /* sNaN reciprocal */ farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSNAN); } else { - farg.d = float64_div(fone.d, farg.d, &env->fp_status); + farg.d = float64_div(float64_one, farg.d, &env->fp_status); f32 = float64_to_float32(farg.d, &env->fp_status); farg.d = float32_to_float64(f32, &env->fp_status); } @@ -1535,9 +1534,8 @@ uint64_t helper_fres (uint64_t arg) /* frsqrte - frsqrte. */ uint64_t helper_frsqrte (uint64_t arg) { - CPU_DoubleU fone, farg; + CPU_DoubleU farg; float32 f32; - fone.ll = 0x3FF0000000000000ULL; /* 1.0 */ farg.ll = arg; if (unlikely(float64_is_signaling_nan(farg.d))) { @@ -1548,7 +1546,7 @@ uint64_t helper_frsqrte (uint64_t arg) farg.ll = fload_invalid_op_excp(POWERPC_EXCP_FP_VXSQRT); } else { farg.d = float64_sqrt(farg.d, &env->fp_status); - farg.d = float64_div(fone.d, farg.d, &env->fp_status); + farg.d = float64_div(float64_one, farg.d, &env->fp_status); f32 = float64_to_float32(farg.d, &env->fp_status); farg.d = float32_to_float64(f32, &env->fp_status); } @@ -1860,15 +1858,11 @@ target_ulong helper_load_dcr (target_ulong dcrn) target_ulong val = 0; if (unlikely(env->dcr_env == NULL)) { - if (loglevel != 0) { - fprintf(logfile, "No DCR environment\n"); - } + qemu_log("No DCR environment\n"); helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); } else if (unlikely(ppc_dcr_read(env->dcr_env, dcrn, &val) != 0)) { - if (loglevel != 0) { - fprintf(logfile, "DCR read error %d %03x\n", (int)dcrn, (int)dcrn); - } + qemu_log("DCR read error %d %03x\n", (int)dcrn, (int)dcrn); helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG); } @@ -1878,15 +1872,11 @@ target_ulong helper_load_dcr (target_ulong dcrn) void helper_store_dcr (target_ulong dcrn, target_ulong val) { if (unlikely(env->dcr_env == NULL)) { - if (loglevel != 0) { - fprintf(logfile, "No DCR environment\n"); - } + qemu_log("No DCR environment\n"); helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_INVAL_INVAL); } else if (unlikely(ppc_dcr_write(env->dcr_env, dcrn, val) != 0)) { - if (loglevel != 0) { - fprintf(logfile, "DCR write error %d %03x\n", (int)dcrn, (int)dcrn); - } + qemu_log("DCR write error %d %03x\n", (int)dcrn, (int)dcrn); helper_raise_exception_err(POWERPC_EXCP_PROGRAM, POWERPC_EXCP_INVAL | POWERPC_EXCP_PRIV_REG); } @@ -1972,6 +1962,23 @@ target_ulong helper_dlmzb (target_ulong high, target_ulong low, uint32_t update_ for (index = ARRAY_SIZE(r->element)-1; index >= 0; index--) #endif +/* If X is a NaN, store the corresponding QNaN into RESULT. Otherwise, + * execute the following block. */ +#define DO_HANDLE_NAN(result, x) \ + if (float32_is_nan(x) || float32_is_signaling_nan(x)) { \ + CPU_FloatU __f; \ + __f.f = x; \ + __f.l = __f.l | (1 << 22); /* Set QNaN bit. */ \ + result = __f.f; \ + } else + +#define HANDLE_NAN1(result, x) \ + DO_HANDLE_NAN(result, x) +#define HANDLE_NAN2(result, x, y) \ + DO_HANDLE_NAN(result, x) DO_HANDLE_NAN(result, y) +#define HANDLE_NAN3(result, x, y, z) \ + DO_HANDLE_NAN(result, x) DO_HANDLE_NAN(result, y) DO_HANDLE_NAN(result, z) + /* Saturating arithmetic helpers. */ #define SATCVT(from, to, from_type, to_type, min, max, use_min, use_max) \ static always_inline to_type cvt##from##to (from_type x, int *sat) \ @@ -2057,6 +2064,16 @@ STVE(stvewx, stl, bswap32, u32) #undef I #undef LVE +void helper_mtvscr (ppc_avr_t *r) +{ +#if defined(WORDS_BIGENDIAN) + env->vscr = r->u32[3]; +#else + env->vscr = r->u32[0]; +#endif + set_flush_to_zero(vscr_nj, &env->vec_status); +} + void helper_vaddcuw (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) { int i; @@ -2082,6 +2099,59 @@ VARITH(uwm, u32) #undef VARITH_DO #undef VARITH +#define VARITHFP(suffix, func) \ + void helper_v##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) { \ + r->f[i] = func(a->f[i], b->f[i], &env->vec_status); \ + } \ + } \ + } +VARITHFP(addfp, float32_add) +VARITHFP(subfp, float32_sub) +#undef VARITHFP + +#define VARITHSAT_CASE(type, op, cvt, element) \ + { \ + type result = (type)a->element[i] op (type)b->element[i]; \ + r->element[i] = cvt(result, &sat); \ + } + +#define VARITHSAT_DO(name, op, optype, cvt, element) \ + void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int sat = 0; \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ + switch (sizeof(r->element[0])) { \ + case 1: VARITHSAT_CASE(optype, op, cvt, element); break; \ + case 2: VARITHSAT_CASE(optype, op, cvt, element); break; \ + case 4: VARITHSAT_CASE(optype, op, cvt, element); break; \ + } \ + } \ + if (sat) { \ + env->vscr |= (1 << VSCR_SAT); \ + } \ + } +#define VARITHSAT_SIGNED(suffix, element, optype, cvt) \ + VARITHSAT_DO(adds##suffix##s, +, optype, cvt, element) \ + VARITHSAT_DO(subs##suffix##s, -, optype, cvt, element) +#define VARITHSAT_UNSIGNED(suffix, element, optype, cvt) \ + VARITHSAT_DO(addu##suffix##s, +, optype, cvt, element) \ + VARITHSAT_DO(subu##suffix##s, -, optype, cvt, element) +VARITHSAT_SIGNED(b, s8, int16_t, cvtshsb) +VARITHSAT_SIGNED(h, s16, int32_t, cvtswsh) +VARITHSAT_SIGNED(w, s32, int64_t, cvtsdsw) +VARITHSAT_UNSIGNED(b, u8, uint16_t, cvtshub) +VARITHSAT_UNSIGNED(h, u16, uint32_t, cvtswuh) +VARITHSAT_UNSIGNED(w, u32, uint64_t, cvtsduw) +#undef VARITHSAT_CASE +#undef VARITHSAT_DO +#undef VARITHSAT_SIGNED +#undef VARITHSAT_UNSIGNED + #define VAVG_DO(name, element, etype) \ void helper_v##name (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ @@ -2101,6 +2171,19 @@ VAVG(w, s32, int64_t, u32, uint64_t) #undef VAVG_DO #undef VAVG +#define VCF(suffix, cvt, element) \ + void helper_vcf##suffix (ppc_avr_t *r, ppc_avr_t *b, uint32_t uim) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + float32 t = cvt(b->element[i], &env->vec_status); \ + r->f[i] = float32_scalbn (t, -uim, &env->vec_status); \ + } \ + } +VCF(ux, uint32_to_float32, u32) +VCF(sx, int32_to_float32, s32) +#undef VCF + #define VCMP_DO(suffix, compare, element, record) \ void helper_vcmp##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ @@ -2137,6 +2220,119 @@ VCMP(gtsw, >, s32) #undef VCMP_DO #undef VCMP +#define VCMPFP_DO(suffix, compare, order, record) \ + void helper_vcmp##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + uint32_t ones = (uint32_t)-1; \ + uint32_t all = ones; \ + uint32_t none = 0; \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + uint32_t result; \ + int rel = float32_compare_quiet(a->f[i], b->f[i], &env->vec_status); \ + if (rel == float_relation_unordered) { \ + result = 0; \ + } else if (rel compare order) { \ + result = ones; \ + } else { \ + result = 0; \ + } \ + r->u32[i] = result; \ + all &= result; \ + none |= result; \ + } \ + if (record) { \ + env->crf[6] = ((all != 0) << 3) | ((none == 0) << 1); \ + } \ + } +#define VCMPFP(suffix, compare, order) \ + VCMPFP_DO(suffix, compare, order, 0) \ + VCMPFP_DO(suffix##_dot, compare, order, 1) +VCMPFP(eqfp, ==, float_relation_equal) +VCMPFP(gefp, !=, float_relation_less) +VCMPFP(gtfp, ==, float_relation_greater) +#undef VCMPFP_DO +#undef VCMPFP + +static always_inline void vcmpbfp_internal (ppc_avr_t *r, ppc_avr_t *a, + ppc_avr_t *b, int record) +{ + int i; + int all_in = 0; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + int le_rel = float32_compare_quiet(a->f[i], b->f[i], &env->vec_status); + if (le_rel == float_relation_unordered) { + r->u32[i] = 0xc0000000; + /* ALL_IN does not need to be updated here. */ + } else { + float32 bneg = float32_chs(b->f[i]); + int ge_rel = float32_compare_quiet(a->f[i], bneg, &env->vec_status); + int le = le_rel != float_relation_greater; + int ge = ge_rel != float_relation_less; + r->u32[i] = ((!le) << 31) | ((!ge) << 30); + all_in |= (!le | !ge); + } + } + if (record) { + env->crf[6] = (all_in == 0) << 1; + } +} + +void helper_vcmpbfp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +{ + vcmpbfp_internal(r, a, b, 0); +} + +void helper_vcmpbfp_dot (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) +{ + vcmpbfp_internal(r, a, b, 1); +} + +#define VCT(suffix, satcvt, element) \ + void helper_vct##suffix (ppc_avr_t *r, ppc_avr_t *b, uint32_t uim) \ + { \ + int i; \ + int sat = 0; \ + float_status s = env->vec_status; \ + set_float_rounding_mode(float_round_to_zero, &s); \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + if (float32_is_nan(b->f[i]) || \ + float32_is_signaling_nan(b->f[i])) { \ + r->element[i] = 0; \ + } else { \ + float64 t = float32_to_float64(b->f[i], &s); \ + int64_t j; \ + t = float64_scalbn(t, uim, &s); \ + j = float64_to_int64(t, &s); \ + r->element[i] = satcvt(j, &sat); \ + } \ + } \ + if (sat) { \ + env->vscr |= (1 << VSCR_SAT); \ + } \ + } +VCT(uxs, cvtsduw, u32) +VCT(sxs, cvtsdsw, s32) +#undef VCT + +void helper_vmaddfp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + HANDLE_NAN3(r->f[i], a->f[i], b->f[i], c->f[i]) { + /* Need to do the computation in higher precision and round + * once at the end. */ + float64 af, bf, cf, t; + af = float32_to_float64(a->f[i], &env->vec_status); + bf = float32_to_float64(b->f[i], &env->vec_status); + cf = float32_to_float64(c->f[i], &env->vec_status); + t = float64_mul(af, cf, &env->vec_status); + t = float64_add(t, bf, &env->vec_status); + r->f[i] = float64_to_float32(t, &env->vec_status); + } + } +} + void helper_vmhaddshs (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int sat = 0; @@ -2193,6 +2389,24 @@ VMINMAX(uw, u32) #undef VMINMAX_DO #undef VMINMAX +#define VMINMAXFP(suffix, rT, rF) \ + void helper_v##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + HANDLE_NAN2(r->f[i], a->f[i], b->f[i]) { \ + if (float32_lt_quiet(a->f[i], b->f[i], &env->vec_status)) { \ + r->f[i] = rT->f[i]; \ + } else { \ + r->f[i] = rF->f[i]; \ + } \ + } \ + } \ + } +VMINMAXFP(minfp, a, b) +VMINMAXFP(maxfp, b, a) +#undef VMINMAXFP + void helper_vmladduhm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { int i; @@ -2355,6 +2569,25 @@ VMUL(uh, u16, u32) #undef VMUL_DO #undef VMUL +void helper_vnmsubfp (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + HANDLE_NAN3(r->f[i], a->f[i], b->f[i], c->f[i]) { + /* Need to do the computation is higher precision and round + * once at the end. */ + float64 af, bf, cf, t; + af = float32_to_float64(a->f[i], &env->vec_status); + bf = float32_to_float64(b->f[i], &env->vec_status); + cf = float32_to_float64(c->f[i], &env->vec_status); + t = float64_mul(af, cf, &env->vec_status); + t = float64_sub(t, bf, &env->vec_status); + t = float64_chs(t); + r->f[i] = float64_to_float32(t, &env->vec_status); + } + } +} + void helper_vperm (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { ppc_avr_t result; @@ -2431,6 +2664,34 @@ VPK(uwum, u32, u16, I, 0) #undef VPK #undef PKBIG +void helper_vrefp (ppc_avr_t *r, ppc_avr_t *b) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + HANDLE_NAN1(r->f[i], b->f[i]) { + r->f[i] = float32_div(float32_one, b->f[i], &env->vec_status); + } + } +} + +#define VRFI(suffix, rounding) \ + void helper_vrfi##suffix (ppc_avr_t *r, ppc_avr_t *b) \ + { \ + int i; \ + float_status s = env->vec_status; \ + set_float_rounding_mode(rounding, &s); \ + for (i = 0; i < ARRAY_SIZE(r->f); i++) { \ + HANDLE_NAN1(r->f[i], b->f[i]) { \ + r->f[i] = float32_round_to_int (b->f[i], &s); \ + } \ + } \ + } +VRFI(n, float_round_nearest_even) +VRFI(m, float_round_down) +VRFI(p, float_round_up) +VRFI(z, float_round_to_zero) +#undef VRFI + #define VROTATE(suffix, element) \ void helper_vrl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ @@ -2446,12 +2707,72 @@ VROTATE(h, u16) VROTATE(w, u32) #undef VROTATE +void helper_vrsqrtefp (ppc_avr_t *r, ppc_avr_t *b) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + HANDLE_NAN1(r->f[i], b->f[i]) { + float32 t = float32_sqrt(b->f[i], &env->vec_status); + r->f[i] = float32_div(float32_one, t, &env->vec_status); + } + } +} + void helper_vsel (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b, ppc_avr_t *c) { r->u64[0] = (a->u64[0] & ~c->u64[0]) | (b->u64[0] & c->u64[0]); r->u64[1] = (a->u64[1] & ~c->u64[1]) | (b->u64[1] & c->u64[1]); } +void helper_vlogefp (ppc_avr_t *r, ppc_avr_t *b) +{ + int i; + for (i = 0; i < ARRAY_SIZE(r->f); i++) { + HANDLE_NAN1(r->f[i], b->f[i]) { + r->f[i] = float32_log2(b->f[i], &env->vec_status); + } + } +} + +#if defined(WORDS_BIGENDIAN) +#define LEFT 0 +#define RIGHT 1 +#else +#define LEFT 1 +#define RIGHT 0 +#endif +/* The specification says that the results are undefined if all of the + * shift counts are not identical. We check to make sure that they are + * to conform to what real hardware appears to do. */ +#define VSHIFT(suffix, leftp) \ + void helper_vs##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ + { \ + int shift = b->u8[LO_IDX*0x15] & 0x7; \ + int doit = 1; \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->u8); i++) { \ + doit = doit && ((b->u8[i] & 0x7) == shift); \ + } \ + if (doit) { \ + if (shift == 0) { \ + *r = *a; \ + } else if (leftp) { \ + uint64_t carry = a->u64[LO_IDX] >> (64 - shift); \ + r->u64[HI_IDX] = (a->u64[HI_IDX] << shift) | carry; \ + r->u64[LO_IDX] = a->u64[LO_IDX] << shift; \ + } else { \ + uint64_t carry = a->u64[HI_IDX] << (64 - shift); \ + r->u64[LO_IDX] = (a->u64[LO_IDX] >> shift) | carry; \ + r->u64[HI_IDX] = a->u64[HI_IDX] >> shift; \ + } \ + } \ + } +VSHIFT(l, LEFT) +VSHIFT(r, RIGHT) +#undef VSHIFT +#undef LEFT +#undef RIGHT + #define VSL(suffix, element) \ void helper_vsl##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ @@ -2531,6 +2852,20 @@ VSPLT(w, u32) #undef SPLAT_ELEMENT #undef _SPLAT_MASKED +#define VSPLTI(suffix, element, splat_type) \ + void helper_vspltis##suffix (ppc_avr_t *r, uint32_t splat) \ + { \ + splat_type x = (int8_t)(splat << 3) >> 3; \ + int i; \ + for (i = 0; i < ARRAY_SIZE(r->element); i++) { \ + r->element[i] = x; \ + } \ + } +VSPLTI(b, s8, int8_t) +VSPLTI(h, s16, int16_t) +VSPLTI(w, s32, int32_t) +#undef VSPLTI + #define VSR(suffix, element) \ void helper_vsr##suffix (ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b) \ { \ @@ -2723,6 +3058,10 @@ VUPK(lsh, s32, s16, UPKLO) #undef UPKHI #undef UPKLO +#undef DO_HANDLE_NAN +#undef HANDLE_NAN1 +#undef HANDLE_NAN2 +#undef HANDLE_NAN3 #undef VECTOR_FOR_INORDER_I #undef HI_IDX #undef LO_IDX @@ -2776,7 +3115,7 @@ static always_inline uint32_t efscfsi (uint32_t val) { CPU_FloatU u; - u.f = int32_to_float32(val, &env->spe_status); + u.f = int32_to_float32(val, &env->vec_status); return u.l; } @@ -2785,7 +3124,7 @@ static always_inline uint32_t efscfui (uint32_t val) { CPU_FloatU u; - u.f = uint32_to_float32(val, &env->spe_status); + u.f = uint32_to_float32(val, &env->vec_status); return u.l; } @@ -2799,7 +3138,7 @@ static always_inline int32_t efsctsi (uint32_t val) if (unlikely(float32_is_nan(u.f))) return 0; - return float32_to_int32(u.f, &env->spe_status); + return float32_to_int32(u.f, &env->vec_status); } static always_inline uint32_t efsctui (uint32_t val) @@ -2811,7 +3150,7 @@ static always_inline uint32_t efsctui (uint32_t val) if (unlikely(float32_is_nan(u.f))) return 0; - return float32_to_uint32(u.f, &env->spe_status); + return float32_to_uint32(u.f, &env->vec_status); } static always_inline uint32_t efsctsiz (uint32_t val) @@ -2823,7 +3162,7 @@ static always_inline uint32_t efsctsiz (uint32_t val) if (unlikely(float32_is_nan(u.f))) return 0; - return float32_to_int32_round_to_zero(u.f, &env->spe_status); + return float32_to_int32_round_to_zero(u.f, &env->vec_status); } static always_inline uint32_t efsctuiz (uint32_t val) @@ -2835,7 +3174,7 @@ static always_inline uint32_t efsctuiz (uint32_t val) if (unlikely(float32_is_nan(u.f))) return 0; - return float32_to_uint32_round_to_zero(u.f, &env->spe_status); + return float32_to_uint32_round_to_zero(u.f, &env->vec_status); } static always_inline uint32_t efscfsf (uint32_t val) @@ -2843,9 +3182,9 @@ static always_inline uint32_t efscfsf (uint32_t val) CPU_FloatU u; float32 tmp; - u.f = int32_to_float32(val, &env->spe_status); - tmp = int64_to_float32(1ULL << 32, &env->spe_status); - u.f = float32_div(u.f, tmp, &env->spe_status); + u.f = int32_to_float32(val, &env->vec_status); + tmp = int64_to_float32(1ULL << 32, &env->vec_status); + u.f = float32_div(u.f, tmp, &env->vec_status); return u.l; } @@ -2855,9 +3194,9 @@ static always_inline uint32_t efscfuf (uint32_t val) CPU_FloatU u; float32 tmp; - u.f = uint32_to_float32(val, &env->spe_status); - tmp = uint64_to_float32(1ULL << 32, &env->spe_status); - u.f = float32_div(u.f, tmp, &env->spe_status); + u.f = uint32_to_float32(val, &env->vec_status); + tmp = uint64_to_float32(1ULL << 32, &env->vec_status); + u.f = float32_div(u.f, tmp, &env->vec_status); return u.l; } @@ -2871,10 +3210,10 @@ static always_inline uint32_t efsctsf (uint32_t val) /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float32_is_nan(u.f))) return 0; - tmp = uint64_to_float32(1ULL << 32, &env->spe_status); - u.f = float32_mul(u.f, tmp, &env->spe_status); + tmp = uint64_to_float32(1ULL << 32, &env->vec_status); + u.f = float32_mul(u.f, tmp, &env->vec_status); - return float32_to_int32(u.f, &env->spe_status); + return float32_to_int32(u.f, &env->vec_status); } static always_inline uint32_t efsctuf (uint32_t val) @@ -2886,10 +3225,10 @@ static always_inline uint32_t efsctuf (uint32_t val) /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float32_is_nan(u.f))) return 0; - tmp = uint64_to_float32(1ULL << 32, &env->spe_status); - u.f = float32_mul(u.f, tmp, &env->spe_status); + tmp = uint64_to_float32(1ULL << 32, &env->vec_status); + u.f = float32_mul(u.f, tmp, &env->vec_status); - return float32_to_uint32(u.f, &env->spe_status); + return float32_to_uint32(u.f, &env->vec_status); } #define HELPER_SPE_SINGLE_CONV(name) \ @@ -2951,7 +3290,7 @@ static always_inline uint32_t efsadd (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - u1.f = float32_add(u1.f, u2.f, &env->spe_status); + u1.f = float32_add(u1.f, u2.f, &env->vec_status); return u1.l; } @@ -2960,7 +3299,7 @@ static always_inline uint32_t efssub (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - u1.f = float32_sub(u1.f, u2.f, &env->spe_status); + u1.f = float32_sub(u1.f, u2.f, &env->vec_status); return u1.l; } @@ -2969,7 +3308,7 @@ static always_inline uint32_t efsmul (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - u1.f = float32_mul(u1.f, u2.f, &env->spe_status); + u1.f = float32_mul(u1.f, u2.f, &env->vec_status); return u1.l; } @@ -2978,7 +3317,7 @@ static always_inline uint32_t efsdiv (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - u1.f = float32_div(u1.f, u2.f, &env->spe_status); + u1.f = float32_div(u1.f, u2.f, &env->vec_status); return u1.l; } @@ -3017,7 +3356,7 @@ static always_inline uint32_t efststlt (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - return float32_lt(u1.f, u2.f, &env->spe_status) ? 4 : 0; + return float32_lt(u1.f, u2.f, &env->vec_status) ? 4 : 0; } static always_inline uint32_t efststgt (uint32_t op1, uint32_t op2) @@ -3025,7 +3364,7 @@ static always_inline uint32_t efststgt (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 4; + return float32_le(u1.f, u2.f, &env->vec_status) ? 0 : 4; } static always_inline uint32_t efststeq (uint32_t op1, uint32_t op2) @@ -3033,7 +3372,7 @@ static always_inline uint32_t efststeq (uint32_t op1, uint32_t op2) CPU_FloatU u1, u2; u1.l = op1; u2.l = op2; - return float32_eq(u1.f, u2.f, &env->spe_status) ? 4 : 0; + return float32_eq(u1.f, u2.f, &env->vec_status) ? 4 : 0; } static always_inline uint32_t efscmplt (uint32_t op1, uint32_t op2) @@ -3100,7 +3439,7 @@ uint64_t helper_efdcfsi (uint32_t val) { CPU_DoubleU u; - u.d = int32_to_float64(val, &env->spe_status); + u.d = int32_to_float64(val, &env->vec_status); return u.ll; } @@ -3109,7 +3448,7 @@ uint64_t helper_efdcfsid (uint64_t val) { CPU_DoubleU u; - u.d = int64_to_float64(val, &env->spe_status); + u.d = int64_to_float64(val, &env->vec_status); return u.ll; } @@ -3118,7 +3457,7 @@ uint64_t helper_efdcfui (uint32_t val) { CPU_DoubleU u; - u.d = uint32_to_float64(val, &env->spe_status); + u.d = uint32_to_float64(val, &env->vec_status); return u.ll; } @@ -3127,7 +3466,7 @@ uint64_t helper_efdcfuid (uint64_t val) { CPU_DoubleU u; - u.d = uint64_to_float64(val, &env->spe_status); + u.d = uint64_to_float64(val, &env->vec_status); return u.ll; } @@ -3141,7 +3480,7 @@ uint32_t helper_efdctsi (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_int32(u.d, &env->spe_status); + return float64_to_int32(u.d, &env->vec_status); } uint32_t helper_efdctui (uint64_t val) @@ -3153,7 +3492,7 @@ uint32_t helper_efdctui (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_uint32(u.d, &env->spe_status); + return float64_to_uint32(u.d, &env->vec_status); } uint32_t helper_efdctsiz (uint64_t val) @@ -3165,7 +3504,7 @@ uint32_t helper_efdctsiz (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_int32_round_to_zero(u.d, &env->spe_status); + return float64_to_int32_round_to_zero(u.d, &env->vec_status); } uint64_t helper_efdctsidz (uint64_t val) @@ -3177,7 +3516,7 @@ uint64_t helper_efdctsidz (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_int64_round_to_zero(u.d, &env->spe_status); + return float64_to_int64_round_to_zero(u.d, &env->vec_status); } uint32_t helper_efdctuiz (uint64_t val) @@ -3189,7 +3528,7 @@ uint32_t helper_efdctuiz (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_uint32_round_to_zero(u.d, &env->spe_status); + return float64_to_uint32_round_to_zero(u.d, &env->vec_status); } uint64_t helper_efdctuidz (uint64_t val) @@ -3201,7 +3540,7 @@ uint64_t helper_efdctuidz (uint64_t val) if (unlikely(float64_is_nan(u.d))) return 0; - return float64_to_uint64_round_to_zero(u.d, &env->spe_status); + return float64_to_uint64_round_to_zero(u.d, &env->vec_status); } uint64_t helper_efdcfsf (uint32_t val) @@ -3209,9 +3548,9 @@ uint64_t helper_efdcfsf (uint32_t val) CPU_DoubleU u; float64 tmp; - u.d = int32_to_float64(val, &env->spe_status); - tmp = int64_to_float64(1ULL << 32, &env->spe_status); - u.d = float64_div(u.d, tmp, &env->spe_status); + u.d = int32_to_float64(val, &env->vec_status); + tmp = int64_to_float64(1ULL << 32, &env->vec_status); + u.d = float64_div(u.d, tmp, &env->vec_status); return u.ll; } @@ -3221,9 +3560,9 @@ uint64_t helper_efdcfuf (uint32_t val) CPU_DoubleU u; float64 tmp; - u.d = uint32_to_float64(val, &env->spe_status); - tmp = int64_to_float64(1ULL << 32, &env->spe_status); - u.d = float64_div(u.d, tmp, &env->spe_status); + u.d = uint32_to_float64(val, &env->vec_status); + tmp = int64_to_float64(1ULL << 32, &env->vec_status); + u.d = float64_div(u.d, tmp, &env->vec_status); return u.ll; } @@ -3237,10 +3576,10 @@ uint32_t helper_efdctsf (uint64_t val) /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float64_is_nan(u.d))) return 0; - tmp = uint64_to_float64(1ULL << 32, &env->spe_status); - u.d = float64_mul(u.d, tmp, &env->spe_status); + tmp = uint64_to_float64(1ULL << 32, &env->vec_status); + u.d = float64_mul(u.d, tmp, &env->vec_status); - return float64_to_int32(u.d, &env->spe_status); + return float64_to_int32(u.d, &env->vec_status); } uint32_t helper_efdctuf (uint64_t val) @@ -3252,10 +3591,10 @@ uint32_t helper_efdctuf (uint64_t val) /* NaN are not treated the same way IEEE 754 does */ if (unlikely(float64_is_nan(u.d))) return 0; - tmp = uint64_to_float64(1ULL << 32, &env->spe_status); - u.d = float64_mul(u.d, tmp, &env->spe_status); + tmp = uint64_to_float64(1ULL << 32, &env->vec_status); + u.d = float64_mul(u.d, tmp, &env->vec_status); - return float64_to_uint32(u.d, &env->spe_status); + return float64_to_uint32(u.d, &env->vec_status); } uint32_t helper_efscfd (uint64_t val) @@ -3264,7 +3603,7 @@ uint32_t helper_efscfd (uint64_t val) CPU_FloatU u2; u1.ll = val; - u2.f = float64_to_float32(u1.d, &env->spe_status); + u2.f = float64_to_float32(u1.d, &env->vec_status); return u2.l; } @@ -3275,7 +3614,7 @@ uint64_t helper_efdcfs (uint32_t val) CPU_FloatU u1; u1.l = val; - u2.d = float32_to_float64(u1.f, &env->spe_status); + u2.d = float32_to_float64(u1.f, &env->vec_status); return u2.ll; } @@ -3286,7 +3625,7 @@ uint64_t helper_efdadd (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - u1.d = float64_add(u1.d, u2.d, &env->spe_status); + u1.d = float64_add(u1.d, u2.d, &env->vec_status); return u1.ll; } @@ -3295,7 +3634,7 @@ uint64_t helper_efdsub (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - u1.d = float64_sub(u1.d, u2.d, &env->spe_status); + u1.d = float64_sub(u1.d, u2.d, &env->vec_status); return u1.ll; } @@ -3304,7 +3643,7 @@ uint64_t helper_efdmul (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - u1.d = float64_mul(u1.d, u2.d, &env->spe_status); + u1.d = float64_mul(u1.d, u2.d, &env->vec_status); return u1.ll; } @@ -3313,7 +3652,7 @@ uint64_t helper_efddiv (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - u1.d = float64_div(u1.d, u2.d, &env->spe_status); + u1.d = float64_div(u1.d, u2.d, &env->vec_status); return u1.ll; } @@ -3323,7 +3662,7 @@ uint32_t helper_efdtstlt (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - return float64_lt(u1.d, u2.d, &env->spe_status) ? 4 : 0; + return float64_lt(u1.d, u2.d, &env->vec_status) ? 4 : 0; } uint32_t helper_efdtstgt (uint64_t op1, uint64_t op2) @@ -3331,7 +3670,7 @@ uint32_t helper_efdtstgt (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - return float64_le(u1.d, u2.d, &env->spe_status) ? 0 : 4; + return float64_le(u1.d, u2.d, &env->vec_status) ? 0 : 4; } uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2) @@ -3339,7 +3678,7 @@ uint32_t helper_efdtsteq (uint64_t op1, uint64_t op2) CPU_DoubleU u1, u2; u1.ll = op1; u2.ll = op2; - return float64_eq(u1.d, u2.d, &env->spe_status) ? 4 : 0; + return float64_eq(u1.d, u2.d, &env->vec_status) ? 4 : 0; } uint32_t helper_efdcmplt (uint64_t op1, uint64_t op2) @@ -3472,13 +3811,9 @@ static void do_6xx_tlb (target_ulong new_EPN, int is_code) EPN = env->spr[SPR_DMISS]; } way = (env->spr[SPR_SRR1] >> 17) & 1; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX + LOG_SWTLB("%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX " PTE1 " ADDRX " way %d\n", __func__, new_EPN, EPN, CMP, RPN, way); - } -#endif /* Store this TLB */ ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), way, is_code, CMP, RPN); @@ -3504,13 +3839,9 @@ static void do_74xx_tlb (target_ulong new_EPN, int is_code) CMP = env->spr[SPR_PTEHI]; EPN = env->spr[SPR_TLBMISS] & ~0x3; way = env->spr[SPR_TLBMISS] & 0x3; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX + LOG_SWTLB("%s: EPN " ADDRX " " ADDRX " PTE0 " ADDRX " PTE1 " ADDRX " way %d\n", __func__, new_EPN, EPN, CMP, RPN, way); - } -#endif /* Store this TLB */ ppc6xx_tlb_store(env, (uint32_t)(new_EPN & TARGET_PAGE_MASK), way, is_code, CMP, RPN); @@ -3634,22 +3965,14 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val) ppcemb_tlb_t *tlb; target_ulong page, end; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s entry %d val " ADDRX "\n", __func__, (int)entry, val); - } -#endif + LOG_SWTLB("%s entry %d val " ADDRX "\n", __func__, (int)entry, val); entry &= 0x3F; tlb = &env->tlb[entry].tlbe; /* Invalidate previous TLB (if it's valid) */ if (tlb->prot & PAGE_VALID) { end = tlb->EPN + tlb->size; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: invalidate old TLB %d start " ADDRX + LOG_SWTLB("%s: invalidate old TLB %d start " ADDRX " end " ADDRX "\n", __func__, (int)entry, tlb->EPN, end); - } -#endif for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) tlb_flush_page(env, page); } @@ -3674,26 +3997,18 @@ void helper_4xx_tlbwe_hi (target_ulong entry, target_ulong val) } tlb->PID = env->spr[SPR_40x_PID]; /* PID */ tlb->attr = val & 0xFF; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX + LOG_SWTLB("%s: set up TLB %d RPN " PADDRX " EPN " ADDRX " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, (int)entry, tlb->RPN, tlb->EPN, tlb->size, tlb->prot & PAGE_READ ? 'r' : '-', tlb->prot & PAGE_WRITE ? 'w' : '-', tlb->prot & PAGE_EXEC ? 'x' : '-', tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); - } -#endif /* Invalidate new TLB (if valid) */ if (tlb->prot & PAGE_VALID) { end = tlb->EPN + tlb->size; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: invalidate TLB %d start " ADDRX + LOG_SWTLB("%s: invalidate TLB %d start " ADDRX " end " ADDRX "\n", __func__, (int)entry, tlb->EPN, end); - } -#endif for (page = tlb->EPN; page < end; page += TARGET_PAGE_SIZE) tlb_flush_page(env, page); } @@ -3703,11 +4018,7 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val) { ppcemb_tlb_t *tlb; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s entry %i val " ADDRX "\n", __func__, (int)entry, val); - } -#endif + LOG_SWTLB("%s entry %i val " ADDRX "\n", __func__, (int)entry, val); entry &= 0x3F; tlb = &env->tlb[entry].tlbe; tlb->RPN = val & 0xFFFFFC00; @@ -3716,17 +4027,13 @@ void helper_4xx_tlbwe_lo (target_ulong entry, target_ulong val) tlb->prot |= PAGE_EXEC; if (val & 0x100) tlb->prot |= PAGE_WRITE; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s: set up TLB %d RPN " PADDRX " EPN " ADDRX + LOG_SWTLB("%s: set up TLB %d RPN " PADDRX " EPN " ADDRX " size " ADDRX " prot %c%c%c%c PID %d\n", __func__, (int)entry, tlb->RPN, tlb->EPN, tlb->size, tlb->prot & PAGE_READ ? 'r' : '-', tlb->prot & PAGE_WRITE ? 'w' : '-', tlb->prot & PAGE_EXEC ? 'x' : '-', tlb->prot & PAGE_VALID ? 'v' : '-', (int)tlb->PID); - } -#endif } target_ulong helper_4xx_tlbsx (target_ulong address) @@ -3741,12 +4048,8 @@ void helper_440_tlbwe (uint32_t word, target_ulong entry, target_ulong value) target_ulong EPN, RPN, size; int do_flush_tlbs; -#if defined (DEBUG_SOFTWARE_TLB) - if (loglevel != 0) { - fprintf(logfile, "%s word %d entry %d value " ADDRX "\n", + LOG_SWTLB("%s word %d entry %d value " ADDRX "\n", __func__, word, (int)entry, value); - } -#endif do_flush_tlbs = 0; entry &= 0x3F; tlb = &env->tlb[entry].tlbe;