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,10 +147,15 @@ | ||
| 147 | #ifdef TARGET_SPARC64 | 147 | #ifdef TARGET_SPARC64 |
| 148 | #define FSR_FTT_NMASK 0xfffffffffffe3fffULL | 148 | #define FSR_FTT_NMASK 0xfffffffffffe3fffULL |
| 149 | #define FSR_FTT_CEXC_NMASK 0xfffffffffffe3fe0ULL | 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 | #else | 153 | #else |
| 151 | #define FSR_FTT_NMASK 0xfffe3fffULL | 154 | #define FSR_FTT_NMASK 0xfffe3fffULL |
| 152 | #define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL | 155 | #define FSR_FTT_CEXC_NMASK 0xfffe3fe0ULL |
| 156 | +#define FSR_LDFSR_OLDMASK 0x000fc000ULL | ||
| 153 | #endif | 157 | #endif |
| 158 | +#define FSR_LDFSR_MASK 0xcfc00fffULL | ||
| 154 | #define FSR_FTT_IEEE_EXCP (1ULL << 14) | 159 | #define FSR_FTT_IEEE_EXCP (1ULL << 14) |
| 155 | #define FSR_FTT_UNIMPFPOP (3ULL << 14) | 160 | #define FSR_FTT_UNIMPFPOP (3ULL << 14) |
| 156 | #define FSR_FTT_SEQ_ERROR (4ULL << 14) | 161 | #define FSR_FTT_SEQ_ERROR (4ULL << 14) |
| @@ -329,22 +334,6 @@ typedef struct CPUSPARCState { | @@ -329,22 +334,6 @@ typedef struct CPUSPARCState { | ||
| 329 | sparc_def_t *def; | 334 | sparc_def_t *def; |
| 330 | } CPUSPARCState; | 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 | /* helper.c */ | 337 | /* helper.c */ |
| 349 | CPUSPARCState *cpu_sparc_init(const char *cpu_model); | 338 | CPUSPARCState *cpu_sparc_init(const char *cpu_model); |
| 350 | void cpu_sparc_set_id(CPUSPARCState *env, unsigned int cpu); | 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,7 +1412,7 @@ void cpu_dump_state(CPUState *env, FILE *f, | ||
| 1412 | env->psrs?'S':'-', env->psrps?'P':'-', | 1412 | env->psrs?'S':'-', env->psrps?'P':'-', |
| 1413 | env->psret?'E':'-', env->wim); | 1413 | env->psret?'E':'-', env->wim); |
| 1414 | #endif | 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 | #ifdef TARGET_SPARC64 | 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,8 +55,7 @@ DEF_HELPER(uint64_t, helper_ld_asi, (target_ulong addr, int asi, int size, \ | ||
| 55 | DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ | 55 | DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ |
| 56 | int size)) | 56 | int size)) |
| 57 | #endif | 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 | DEF_HELPER(void, helper_check_ieee_exceptions, (void)) | 59 | DEF_HELPER(void, helper_check_ieee_exceptions, (void)) |
| 61 | DEF_HELPER(void, helper_clear_float_exceptions, (void)) | 60 | DEF_HELPER(void, helper_clear_float_exceptions, (void)) |
| 62 | DEF_HELPER(void, helper_fabss, (void)) | 61 | DEF_HELPER(void, helper_fabss, (void)) |
| @@ -70,6 +69,7 @@ DEF_HELPER(void, helper_fsqrtq, (void)) | @@ -70,6 +69,7 @@ DEF_HELPER(void, helper_fsqrtq, (void)) | ||
| 70 | DEF_HELPER(void, helper_fcmpq, (void)) | 69 | DEF_HELPER(void, helper_fcmpq, (void)) |
| 71 | DEF_HELPER(void, helper_fcmpeq, (void)) | 70 | DEF_HELPER(void, helper_fcmpeq, (void)) |
| 72 | #ifdef TARGET_SPARC64 | 71 | #ifdef TARGET_SPARC64 |
| 72 | +DEF_HELPER(void, helper_ldxfsr, (uint64_t new_fsr)) | ||
| 73 | DEF_HELPER(void, helper_fabsd, (void)) | 73 | DEF_HELPER(void, helper_fabsd, (void)) |
| 74 | DEF_HELPER(void, helper_fcmps_fcc1, (void)) | 74 | DEF_HELPER(void, helper_fcmps_fcc1, (void)) |
| 75 | DEF_HELPER(void, helper_fcmpd_fcc1, (void)) | 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,11 +2487,10 @@ void helper_stqf(target_ulong addr, int mem_idx) | ||
| 2487 | #endif | 2487 | #endif |
| 2488 | } | 2488 | } |
| 2489 | 2489 | ||
| 2490 | -void helper_ldfsr(void) | 2490 | +static inline void set_fsr(void) |
| 2491 | { | 2491 | { |
| 2492 | int rnd_mode; | 2492 | int rnd_mode; |
| 2493 | 2493 | ||
| 2494 | - PUT_FSR32(env, *((uint32_t *) &FT0)); | ||
| 2495 | switch (env->fsr & FSR_RD_MASK) { | 2494 | switch (env->fsr & FSR_RD_MASK) { |
| 2496 | case FSR_RD_NEAREST: | 2495 | case FSR_RD_NEAREST: |
| 2497 | rnd_mode = float_round_nearest_even; | 2496 | rnd_mode = float_round_nearest_even; |
| @@ -2510,11 +2509,20 @@ void helper_ldfsr(void) | @@ -2510,11 +2509,20 @@ void helper_ldfsr(void) | ||
| 2510 | set_float_rounding_mode(rnd_mode, &env->fp_status); | 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 | void helper_debug(void) | 2526 | void helper_debug(void) |
| 2519 | { | 2527 | { |
| 2520 | env->exception_index = EXCP_DEBUG; | 2528 | env->exception_index = EXCP_DEBUG; |
target-sparc/translate.c
| @@ -4368,12 +4368,19 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4368,12 +4368,19 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4368 | tcg_gen_st_i32(cpu_tmp32, cpu_env, | 4368 | tcg_gen_st_i32(cpu_tmp32, cpu_env, |
| 4369 | offsetof(CPUState, fpr[rd])); | 4369 | offsetof(CPUState, fpr[rd])); |
| 4370 | break; | 4370 | break; |
| 4371 | - case 0x21: /* load fsr */ | 4371 | + case 0x21: /* ldfsr, V9 ldxfsr */ |
| 4372 | +#ifdef TARGET_SPARC64 | ||
| 4372 | gen_address_mask(dc, cpu_addr); | 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 | break; | 4384 | break; |
| 4378 | case 0x22: /* load quad fpreg */ | 4385 | case 0x22: /* load quad fpreg */ |
| 4379 | { | 4386 | { |
| @@ -4506,11 +4513,19 @@ static void disas_sparc_insn(DisasContext * dc) | @@ -4506,11 +4513,19 @@ static void disas_sparc_insn(DisasContext * dc) | ||
| 4506 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); | 4513 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4507 | break; | 4514 | break; |
| 4508 | case 0x25: /* stfsr, V9 stxfsr */ | 4515 | case 0x25: /* stfsr, V9 stxfsr */ |
| 4516 | +#ifdef TARGET_SPARC64 | ||
| 4509 | gen_address_mask(dc, cpu_addr); | 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 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); | 4527 | tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); |
| 4528 | +#endif | ||
| 4514 | break; | 4529 | break; |
| 4515 | case 0x26: | 4530 | case 0x26: |
| 4516 | #ifdef TARGET_SPARC64 | 4531 | #ifdef TARGET_SPARC64 |