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 | ... | ... |