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 |