Commit 3a3b925d4724e729a7cfe33c4f61e346252a2a2f
1 parent
6f9e3801
Implement ldxfsr/stxfsr, fix ld(x)fsr masks, convert to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5185 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
5 changed files
with
43 additions
and
31 deletions
target-sparc/cpu.h
| ... | ... | @@ -147,10 +147,15 @@ |
| 147 | 147 | #ifdef TARGET_SPARC64 |
| 148 | 148 | #define FSR_FTT_NMASK 0xfffffffffffe3fffULL |
| 149 | 149 | #define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL |
| 150 | +#define FSR_LDFSR_OLDMASK 0x0000003f000fc000ULL | |
| 151 | +#define FSR_LDXFSR_MASK 0x0000003fcfc00fffULL | |
| 152 | +#define FSR_LDXFSR_OLDMASK 0x00000000000fc000ULL | |
| 150 | 153 | #else |
| 151 | 154 | #define FSR_FTT_NMASK 0xfffe3fffULL |
| 152 | 155 | #define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL |
| 156 | +#define FSR_LDFSR_OLDMASK 0x000fc000ULL | |
| 153 | 157 | #endif |
| 158 | +#define FSR_LDFSR_MASK 0xcfc00fffULL | |
| 154 | 159 | #define FSR_FTT_IEEE_EXCP (1ULL << 14) |
| 155 | 160 | #define FSR_FTT_UNIMPFPOP (3ULL << 14) |
| 156 | 161 | #define FSR_FTT_SEQ_ERROR (4ULL << 14) |
| ... | ... | @@ -329,22 +334,6 @@ typedef struct CPUSPARCState { |
| 329 | 334 | sparc_def_t *def; |
| 330 | 335 | } CPUSPARCState; |
| 331 | 336 | |
| 332 | -#if defined(TARGET_SPARC64) | |
| 333 | -#define GET_FSR32(env) (env->fsr & 0xcfc1ffff) | |
| 334 | -#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ | |
| 335 | - env->fsr = (_tmp & 0xcfc1c3ff) | (env->fsr & 0x3f00000000ULL); \ | |
| 336 | - } while (0) | |
| 337 | -#define GET_FSR64(env) (env->fsr & 0x3fcfc1ffffULL) | |
| 338 | -#define PUT_FSR64(env, val) do { uint64_t _tmp = val; \ | |
| 339 | - env->fsr = _tmp & 0x3fcfc1c3ffULL; \ | |
| 340 | - } while (0) | |
| 341 | -#else | |
| 342 | -#define GET_FSR32(env) (env->fsr) | |
| 343 | -#define PUT_FSR32(env, val) do { uint32_t _tmp = val; \ | |
| 344 | - env->fsr = (_tmp & 0xcfc1dfff) | (env->fsr & 0x000e0000); \ | |
| 345 | - } while (0) | |
| 346 | -#endif | |
| 347 | - | |
| 348 | 337 | /* helper.c */ |
| 349 | 338 | CPUSPARCState *cpu_sparc_init(const char *cpu_model); |
| 350 | 339 | void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); | ... | ... |
target-sparc/helper.c
| ... | ... | @@ -1412,7 +1412,7 @@ void cpu_dump_state(CPUState *env, FILE *f, |
| 1412 | 1412 | env->psrs?'S':'-', env->psrps?'P':'-', |
| 1413 | 1413 | env->psret?'E':'-', env->wim); |
| 1414 | 1414 | #endif |
| 1415 | - cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env)); | |
| 1415 | + cpu_fprintf(f, "fsr: 0x%08x\n", env->fsr); | |
| 1416 | 1416 | } |
| 1417 | 1417 | |
| 1418 | 1418 | #ifdef TARGET_SPARC64 | ... | ... |
target-sparc/helper.h
| ... | ... | @@ -55,8 +55,7 @@ DEF_HELPER(uint64_t, helper_ld_asi, (target_ulong addr, int asi, int size, \ |
| 55 | 55 | DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ |
| 56 | 56 | int size)) |
| 57 | 57 | #endif |
| 58 | -DEF_HELPER(void, helper_ldfsr, (void)) | |
| 59 | -DEF_HELPER(void, helper_stfsr, (void)) | |
| 58 | +DEF_HELPER(void, helper_ldfsr, (uint32_t new_fsr)) | |
| 60 | 59 | DEF_HELPER(void, helper_check_ieee_exceptions, (void)) |
| 61 | 60 | DEF_HELPER(void, helper_clear_float_exceptions, (void)) |
| 62 | 61 | DEF_HELPER(void, helper_fabss, (void)) |
| ... | ... | @@ -70,6 +69,7 @@ DEF_HELPER(void, helper_fsqrtq, (void)) |
| 70 | 69 | DEF_HELPER(void, helper_fcmpq, (void)) |
| 71 | 70 | DEF_HELPER(void, helper_fcmpeq, (void)) |
| 72 | 71 | #ifdef TARGET_SPARC64 |
| 72 | +DEF_HELPER(void, helper_ldxfsr, (uint64_t new_fsr)) | |
| 73 | 73 | DEF_HELPER(void, helper_fabsd, (void)) |
| 74 | 74 | DEF_HELPER(void, helper_fcmps_fcc1, (void)) |
| 75 | 75 | DEF_HELPER(void, helper_fcmpd_fcc1, (void)) | ... | ... |
target-sparc/op_helper.c
| ... | ... | @@ -2487,11 +2487,10 @@ void helper_stqf(target_ulong addr, int mem_idx) |
| 2487 | 2487 | #endif |
| 2488 | 2488 | } |
| 2489 | 2489 | |
| 2490 | -void helper_ldfsr(void) | |
| 2490 | +static inline void set_fsr(void) | |
| 2491 | 2491 | { |
| 2492 | 2492 | int rnd_mode; |
| 2493 | 2493 | |
| 2494 | - PUT_FSR32(env, *((uint32_t *) &FT0)); | |
| 2495 | 2494 | switch (env->fsr & FSR_RD_MASK) { |
| 2496 | 2495 | case FSR_RD_NEAREST: |
| 2497 | 2496 | rnd_mode = float_round_nearest_even; |
| ... | ... | @@ -2510,11 +2509,20 @@ void helper_ldfsr(void) |
| 2510 | 2509 | set_float_rounding_mode(rnd_mode, &env->fp_status); |
| 2511 | 2510 | } |
| 2512 | 2511 | |
| 2513 | -void helper_stfsr(void) | |
| 2512 | +void helper_ldfsr(uint32_t new_fsr) | |
| 2514 | 2513 | { |
| 2515 | - *((uint32_t *) &FT0) = GET_FSR32(env); | |
| 2514 | + env->fsr = (new_fsr & FSR_LDFSR_MASK) | (env->fsr & FSR_LDFSR_OLDMASK); | |
| 2515 | + set_fsr(); | |
| 2516 | 2516 | } |
| 2517 | 2517 | |
| 2518 | +#ifdef TARGET_SPARC64 | |
| 2519 | +void helper_ldxfsr(uint64_t new_fsr) | |
| 2520 | +{ | |
| 2521 | + env->fsr = (new_fsr & FSR_LDXFSR_MASK) | (env->fsr & FSR_LDXFSR_OLDMASK); | |
| 2522 | + set_fsr(); | |
| 2523 | +} | |
| 2524 | +#endif | |
| 2525 | + | |
| 2518 | 2526 | void helper_debug(void) |
| 2519 | 2527 | { |
| 2520 | 2528 | env->exception_index = EXCP_DEBUG; | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -4368,12 +4368,19 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4368 | 4368 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
| 4369 | 4369 | offsetof(CPUState, fpr[rd])); |
| 4370 | 4370 | break; |
| 4371 | - case 0x21: /* load fsr */ | |
| 4371 | + case 0x21: /* ldfsr, V9 ldxfsr */ | |
| 4372 | +#ifdef TARGET_SPARC64 | |
| 4372 | 4373 | gen_address_mask(dc, cpu_addr); |
| 4373 | - tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | |
| 4374 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, | |
| 4375 | - offsetof(CPUState, ft0)); | |
| 4376 | - tcg_gen_helper_0_0(helper_ldfsr); | |
| 4374 | + if (rd == 1) { | |
| 4375 | + tcg_gen_qemu_ld64(cpu_tmp64, cpu_addr, dc->mem_idx); | |
| 4376 | + tcg_gen_helper_0_1(helper_ldxfsr, cpu_tmp64); | |
| 4377 | + } else | |
| 4378 | +#else | |
| 4379 | + { | |
| 4380 | + tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | |
| 4381 | + tcg_gen_helper_0_1(helper_ldfsr, cpu_tmp32); | |
| 4382 | + } | |
| 4383 | +#endif | |
| 4377 | 4384 | break; |
| 4378 | 4385 | case 0x22: /* load quad fpreg */ |
| 4379 | 4386 | { |
| ... | ... | @@ -4506,11 +4513,19 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4506 | 4513 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4507 | 4514 | break; |
| 4508 | 4515 | case 0x25: /* stfsr, V9 stxfsr */ |
| 4516 | +#ifdef TARGET_SPARC64 | |
| 4509 | 4517 | gen_address_mask(dc, cpu_addr); |
| 4510 | - tcg_gen_helper_0_0(helper_stfsr); | |
| 4511 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, | |
| 4512 | - offsetof(CPUState, ft0)); | |
| 4518 | + tcg_gen_ld_i64(cpu_tmp64, cpu_env, offsetof(CPUState, fsr)); | |
| 4519 | + if (rd == 1) | |
| 4520 | + tcg_gen_qemu_st64(cpu_tmp64, cpu_addr, dc->mem_idx); | |
| 4521 | + else { | |
| 4522 | + tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp64); | |
| 4523 | + tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); | |
| 4524 | + } | |
| 4525 | +#else | |
| 4526 | + tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUState, fsr)); | |
| 4513 | 4527 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4528 | +#endif | |
| 4514 | 4529 | break; |
| 4515 | 4530 | case 0x26: |
| 4516 | 4531 | #ifdef TARGET_SPARC64 | ... | ... |