Commit 714547bbc7db79a1d7e6544bf90c9ee1073d6881
1 parent
bcdf9b4d
Convert basic float32 ops to TCG
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@5189 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
3 changed files
with
329 additions
and
190 deletions
target-sparc/helper.h
| ... | ... | @@ -58,12 +58,12 @@ DEF_HELPER(void, helper_st_asi, (target_ulong addr, uint64_t val, int asi, \ |
| 58 | 58 | DEF_HELPER(void, helper_ldfsr, (uint32_t new_fsr)) |
| 59 | 59 | DEF_HELPER(void, helper_check_ieee_exceptions, (void)) |
| 60 | 60 | DEF_HELPER(void, helper_clear_float_exceptions, (void)) |
| 61 | -DEF_HELPER(void, helper_fabss, (void)) | |
| 62 | -DEF_HELPER(void, helper_fsqrts, (void)) | |
| 61 | +DEF_HELPER(float32, helper_fabss, (float32 src)) | |
| 62 | +DEF_HELPER(float32, helper_fsqrts, (float32 src)) | |
| 63 | 63 | DEF_HELPER(void, helper_fsqrtd, (void)) |
| 64 | -DEF_HELPER(void, helper_fcmps, (void)) | |
| 64 | +DEF_HELPER(void, helper_fcmps, (float32 src1, float32 src2)) | |
| 65 | 65 | DEF_HELPER(void, helper_fcmpd, (void)) |
| 66 | -DEF_HELPER(void, helper_fcmpes, (void)) | |
| 66 | +DEF_HELPER(void, helper_fcmpes, (float32 src1, float32 src2)) | |
| 67 | 67 | DEF_HELPER(void, helper_fcmped, (void)) |
| 68 | 68 | DEF_HELPER(void, helper_fsqrtq, (void)) |
| 69 | 69 | DEF_HELPER(void, helper_fcmpq, (void)) |
| ... | ... | @@ -71,17 +71,17 @@ DEF_HELPER(void, helper_fcmpeq, (void)) |
| 71 | 71 | #ifdef TARGET_SPARC64 |
| 72 | 72 | DEF_HELPER(void, helper_ldxfsr, (uint64_t new_fsr)) |
| 73 | 73 | DEF_HELPER(void, helper_fabsd, (void)) |
| 74 | -DEF_HELPER(void, helper_fcmps_fcc1, (void)) | |
| 74 | +DEF_HELPER(void, helper_fcmps_fcc1, (float32 src1, float32 src2)) | |
| 75 | +DEF_HELPER(void, helper_fcmps_fcc2, (float32 src1, float32 src2)) | |
| 76 | +DEF_HELPER(void, helper_fcmps_fcc3, (float32 src1, float32 src2)) | |
| 75 | 77 | DEF_HELPER(void, helper_fcmpd_fcc1, (void)) |
| 76 | -DEF_HELPER(void, helper_fcmps_fcc2, (void)) | |
| 77 | 78 | DEF_HELPER(void, helper_fcmpd_fcc2, (void)) |
| 78 | -DEF_HELPER(void, helper_fcmps_fcc3, (void)) | |
| 79 | 79 | DEF_HELPER(void, helper_fcmpd_fcc3, (void)) |
| 80 | -DEF_HELPER(void, helper_fcmpes_fcc1, (void)) | |
| 80 | +DEF_HELPER(void, helper_fcmpes_fcc1, (float32 src1, float32 src2)) | |
| 81 | +DEF_HELPER(void, helper_fcmpes_fcc2, (float32 src1, float32 src2)) | |
| 82 | +DEF_HELPER(void, helper_fcmpes_fcc3, (float32 src1, float32 src2)) | |
| 81 | 83 | DEF_HELPER(void, helper_fcmped_fcc1, (void)) |
| 82 | -DEF_HELPER(void, helper_fcmpes_fcc2, (void)) | |
| 83 | 84 | DEF_HELPER(void, helper_fcmped_fcc2, (void)) |
| 84 | -DEF_HELPER(void, helper_fcmpes_fcc3, (void)) | |
| 85 | 85 | DEF_HELPER(void, helper_fcmped_fcc3, (void)) |
| 86 | 86 | DEF_HELPER(void, helper_fabsq, (void)) |
| 87 | 87 | DEF_HELPER(void, helper_fcmpq_fcc1, (void)) |
| ... | ... | @@ -97,17 +97,28 @@ DEF_HELPER(void, raise_exception, (int tt)) |
| 97 | 97 | F_HELPER_0_0(name ## s); \ |
| 98 | 98 | F_HELPER_0_0(name ## d); \ |
| 99 | 99 | F_HELPER_0_0(name ## q) |
| 100 | +#define F_HELPER_DQ_0_0(name) \ | |
| 101 | + F_HELPER_0_0(name ## d); \ | |
| 102 | + F_HELPER_0_0(name ## q) | |
| 103 | + | |
| 104 | +F_HELPER_DQ_0_0(add); | |
| 105 | +F_HELPER_DQ_0_0(sub); | |
| 106 | +F_HELPER_DQ_0_0(mul); | |
| 107 | +F_HELPER_DQ_0_0(div); | |
| 100 | 108 | |
| 101 | -F_HELPER_SDQ_0_0(add); | |
| 102 | -F_HELPER_SDQ_0_0(sub); | |
| 103 | -F_HELPER_SDQ_0_0(mul); | |
| 104 | -F_HELPER_SDQ_0_0(div); | |
| 109 | +DEF_HELPER(float32, helper_fadds, (float32 src1, float32 src2)) | |
| 110 | +DEF_HELPER(float32, helper_fsubs, (float32 src1, float32 src2)) | |
| 111 | +DEF_HELPER(float32, helper_fmuls, (float32 src1, float32 src2)) | |
| 112 | +DEF_HELPER(float32, helper_fdivs, (float32 src1, float32 src2)) | |
| 105 | 113 | |
| 106 | 114 | F_HELPER_0_0(smuld); |
| 107 | 115 | F_HELPER_0_0(dmulq); |
| 108 | 116 | |
| 109 | -DEF_HELPER(void, helper_fnegs, (void)) | |
| 110 | -F_HELPER_SDQ_0_0(ito); | |
| 117 | +DEF_HELPER(float32, helper_fnegs, (float32 src)) | |
| 118 | +F_HELPER_DQ_0_0(ito); | |
| 119 | + | |
| 120 | +DEF_HELPER(float32, helper_fitos, (int32_t src)) | |
| 121 | + | |
| 111 | 122 | #ifdef TARGET_SPARC64 |
| 112 | 123 | DEF_HELPER(void, helper_fnegd, (void)) |
| 113 | 124 | DEF_HELPER(void, helper_fnegq, (void)) |
| ... | ... | @@ -119,7 +130,7 @@ F_HELPER_0_0(qtos); |
| 119 | 130 | F_HELPER_0_0(stoq); |
| 120 | 131 | F_HELPER_0_0(qtod); |
| 121 | 132 | F_HELPER_0_0(dtoq); |
| 122 | -F_HELPER_0_0(stoi); | |
| 133 | +DEF_HELPER(int32_t, helper_fstoi, (float32 src)) | |
| 123 | 134 | F_HELPER_0_0(dtoi); |
| 124 | 135 | F_HELPER_0_0(qtoi); |
| 125 | 136 | #ifdef TARGET_SPARC64 |
| ... | ... | @@ -176,6 +187,6 @@ VIS_CMPHELPER(cmple); |
| 176 | 187 | VIS_CMPHELPER(cmpne); |
| 177 | 188 | #endif |
| 178 | 189 | #undef F_HELPER_0_0 |
| 179 | -#undef F_HELPER_SDQ_0_0 | |
| 190 | +#undef F_HELPER_DQ_0_0 | |
| 180 | 191 | #undef VIS_HELPER |
| 181 | 192 | #undef VIS_CMPHELPER | ... | ... |
target-sparc/op_helper.c
| ... | ... | @@ -87,9 +87,9 @@ void helper_check_align(target_ulong addr, uint32_t align) |
| 87 | 87 | #define F_HELPER(name, p) void helper_f##name##p(void) |
| 88 | 88 | |
| 89 | 89 | #define F_BINOP(name) \ |
| 90 | - F_HELPER(name, s) \ | |
| 90 | + float32 helper_f ## name ## s (float32 src1, float32 src2) \ | |
| 91 | 91 | { \ |
| 92 | - FT0 = float32_ ## name (FT0, FT1, &env->fp_status); \ | |
| 92 | + return float32_ ## name (src1, src2, &env->fp_status); \ | |
| 93 | 93 | } \ |
| 94 | 94 | F_HELPER(name, d) \ |
| 95 | 95 | { \ |
| ... | ... | @@ -120,9 +120,9 @@ void helper_fdmulq(void) |
| 120 | 120 | &env->fp_status); |
| 121 | 121 | } |
| 122 | 122 | |
| 123 | -F_HELPER(neg, s) | |
| 123 | +float32 helper_fnegs(float32 src) | |
| 124 | 124 | { |
| 125 | - FT0 = float32_chs(FT1); | |
| 125 | + return float32_chs(src); | |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | 128 | #ifdef TARGET_SPARC64 |
| ... | ... | @@ -138,9 +138,9 @@ F_HELPER(neg, q) |
| 138 | 138 | #endif |
| 139 | 139 | |
| 140 | 140 | /* Integer to float conversion. */ |
| 141 | -F_HELPER(ito, s) | |
| 141 | +float32 helper_fitos(int32_t src) | |
| 142 | 142 | { |
| 143 | - FT0 = int32_to_float32(*((int32_t *)&FT1), &env->fp_status); | |
| 143 | + return int32_to_float32(src, &env->fp_status); | |
| 144 | 144 | } |
| 145 | 145 | |
| 146 | 146 | F_HELPER(ito, d) |
| ... | ... | @@ -203,9 +203,9 @@ void helper_fdtoq(void) |
| 203 | 203 | } |
| 204 | 204 | |
| 205 | 205 | /* Float to integer conversion. */ |
| 206 | -void helper_fstoi(void) | |
| 206 | +int32_t helper_fstoi(float32 src) | |
| 207 | 207 | { |
| 208 | - *((int32_t *)&FT0) = float32_to_int32_round_to_zero(FT1, &env->fp_status); | |
| 208 | + return float32_to_int32_round_to_zero(src, &env->fp_status); | |
| 209 | 209 | } |
| 210 | 210 | |
| 211 | 211 | void helper_fdtoi(void) |
| ... | ... | @@ -714,9 +714,9 @@ void helper_clear_float_exceptions(void) |
| 714 | 714 | set_float_exception_flags(0, &env->fp_status); |
| 715 | 715 | } |
| 716 | 716 | |
| 717 | -void helper_fabss(void) | |
| 717 | +float32 helper_fabss(float32 src) | |
| 718 | 718 | { |
| 719 | - FT0 = float32_abs(FT1); | |
| 719 | + return float32_abs(src); | |
| 720 | 720 | } |
| 721 | 721 | |
| 722 | 722 | #ifdef TARGET_SPARC64 |
| ... | ... | @@ -731,9 +731,9 @@ void helper_fabsq(void) |
| 731 | 731 | } |
| 732 | 732 | #endif |
| 733 | 733 | |
| 734 | -void helper_fsqrts(void) | |
| 734 | +float32 helper_fsqrts(float32 src) | |
| 735 | 735 | { |
| 736 | - FT0 = float32_sqrt(FT1, &env->fp_status); | |
| 736 | + return float32_sqrt(src, &env->fp_status); | |
| 737 | 737 | } |
| 738 | 738 | |
| 739 | 739 | void helper_fsqrtd(void) |
| ... | ... | @@ -776,41 +776,72 @@ void helper_fsqrtq(void) |
| 776 | 776 | } \ |
| 777 | 777 | env->fsr |= new_fsr; \ |
| 778 | 778 | } |
| 779 | +#define GEN_FCMPS(name, size, FS, TRAP) \ | |
| 780 | + void glue(helper_, name)(float32 src1, float32 src2) \ | |
| 781 | + { \ | |
| 782 | + target_ulong new_fsr; \ | |
| 783 | + \ | |
| 784 | + env->fsr &= ~((FSR_FCC1 | FSR_FCC0) << FS); \ | |
| 785 | + switch (glue(size, _compare) (src1, src2, &env->fp_status)) { \ | |
| 786 | + case float_relation_unordered: \ | |
| 787 | + new_fsr = (FSR_FCC1 | FSR_FCC0) << FS; \ | |
| 788 | + if ((env->fsr & FSR_NVM) || TRAP) { \ | |
| 789 | + env->fsr |= new_fsr; \ | |
| 790 | + env->fsr |= FSR_NVC; \ | |
| 791 | + env->fsr |= FSR_FTT_IEEE_EXCP; \ | |
| 792 | + raise_exception(TT_FP_EXCP); \ | |
| 793 | + } else { \ | |
| 794 | + env->fsr |= FSR_NVA; \ | |
| 795 | + } \ | |
| 796 | + break; \ | |
| 797 | + case float_relation_less: \ | |
| 798 | + new_fsr = FSR_FCC0 << FS; \ | |
| 799 | + break; \ | |
| 800 | + case float_relation_greater: \ | |
| 801 | + new_fsr = FSR_FCC1 << FS; \ | |
| 802 | + break; \ | |
| 803 | + default: \ | |
| 804 | + new_fsr = 0; \ | |
| 805 | + break; \ | |
| 806 | + } \ | |
| 807 | + env->fsr |= new_fsr; \ | |
| 808 | + } | |
| 779 | 809 | |
| 780 | -GEN_FCMP(fcmps, float32, FT0, FT1, 0, 0); | |
| 810 | +GEN_FCMPS(fcmps, float32, 0, 0); | |
| 781 | 811 | GEN_FCMP(fcmpd, float64, DT0, DT1, 0, 0); |
| 782 | 812 | |
| 783 | -GEN_FCMP(fcmpes, float32, FT0, FT1, 0, 1); | |
| 813 | +GEN_FCMPS(fcmpes, float32, 0, 1); | |
| 784 | 814 | GEN_FCMP(fcmped, float64, DT0, DT1, 0, 1); |
| 785 | 815 | |
| 786 | 816 | GEN_FCMP(fcmpq, float128, QT0, QT1, 0, 0); |
| 787 | 817 | GEN_FCMP(fcmpeq, float128, QT0, QT1, 0, 1); |
| 788 | 818 | |
| 789 | 819 | #ifdef TARGET_SPARC64 |
| 790 | -GEN_FCMP(fcmps_fcc1, float32, FT0, FT1, 22, 0); | |
| 820 | +GEN_FCMPS(fcmps_fcc1, float32, 22, 0); | |
| 791 | 821 | GEN_FCMP(fcmpd_fcc1, float64, DT0, DT1, 22, 0); |
| 792 | 822 | GEN_FCMP(fcmpq_fcc1, float128, QT0, QT1, 22, 0); |
| 793 | 823 | |
| 794 | -GEN_FCMP(fcmps_fcc2, float32, FT0, FT1, 24, 0); | |
| 824 | +GEN_FCMPS(fcmps_fcc2, float32, 24, 0); | |
| 795 | 825 | GEN_FCMP(fcmpd_fcc2, float64, DT0, DT1, 24, 0); |
| 796 | 826 | GEN_FCMP(fcmpq_fcc2, float128, QT0, QT1, 24, 0); |
| 797 | 827 | |
| 798 | -GEN_FCMP(fcmps_fcc3, float32, FT0, FT1, 26, 0); | |
| 828 | +GEN_FCMPS(fcmps_fcc3, float32, 26, 0); | |
| 799 | 829 | GEN_FCMP(fcmpd_fcc3, float64, DT0, DT1, 26, 0); |
| 800 | 830 | GEN_FCMP(fcmpq_fcc3, float128, QT0, QT1, 26, 0); |
| 801 | 831 | |
| 802 | -GEN_FCMP(fcmpes_fcc1, float32, FT0, FT1, 22, 1); | |
| 832 | +GEN_FCMPS(fcmpes_fcc1, float32, 22, 1); | |
| 803 | 833 | GEN_FCMP(fcmped_fcc1, float64, DT0, DT1, 22, 1); |
| 804 | 834 | GEN_FCMP(fcmpeq_fcc1, float128, QT0, QT1, 22, 1); |
| 805 | 835 | |
| 806 | -GEN_FCMP(fcmpes_fcc2, float32, FT0, FT1, 24, 1); | |
| 836 | +GEN_FCMPS(fcmpes_fcc2, float32, 24, 1); | |
| 807 | 837 | GEN_FCMP(fcmped_fcc2, float64, DT0, DT1, 24, 1); |
| 808 | 838 | GEN_FCMP(fcmpeq_fcc2, float128, QT0, QT1, 24, 1); |
| 809 | 839 | |
| 810 | -GEN_FCMP(fcmpes_fcc3, float32, FT0, FT1, 26, 1); | |
| 840 | +GEN_FCMPS(fcmpes_fcc3, float32, 26, 1); | |
| 811 | 841 | GEN_FCMP(fcmped_fcc3, float64, DT0, DT1, 26, 1); |
| 812 | 842 | GEN_FCMP(fcmpeq_fcc3, float128, QT0, QT1, 26, 1); |
| 813 | 843 | #endif |
| 844 | +#undef GEN_FCMPS | |
| 814 | 845 | |
| 815 | 846 | #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) && \ |
| 816 | 847 | defined(DEBUG_MXCC) |
| ... | ... | @@ -2220,7 +2251,7 @@ void helper_ldf_asi(target_ulong addr, int asi, int size, int rd) |
| 2220 | 2251 | switch(size) { |
| 2221 | 2252 | default: |
| 2222 | 2253 | case 4: |
| 2223 | - *((uint32_t *)&FT0) = val; | |
| 2254 | + *((uint32_t *)&env->fpr[rd]) = val; | |
| 2224 | 2255 | break; |
| 2225 | 2256 | case 8: |
| 2226 | 2257 | *((int64_t *)&DT0) = val; |
| ... | ... | @@ -2261,7 +2292,7 @@ void helper_stf_asi(target_ulong addr, int asi, int size, int rd) |
| 2261 | 2292 | switch(size) { |
| 2262 | 2293 | default: |
| 2263 | 2294 | case 4: |
| 2264 | - val = *((uint32_t *)&FT0); | |
| 2295 | + val = *((uint32_t *)&env->fpr[rd]); | |
| 2265 | 2296 | break; |
| 2266 | 2297 | case 8: |
| 2267 | 2298 | val = *((int64_t *)&DT0); | ... | ... |
target-sparc/translate.c
| ... | ... | @@ -55,6 +55,8 @@ static TCGv cpu_wim; |
| 55 | 55 | #endif |
| 56 | 56 | /* local register indexes (only used inside old micro ops) */ |
| 57 | 57 | static TCGv cpu_tmp0, cpu_tmp32, cpu_tmp64; |
| 58 | +/* Floating point registers */ | |
| 59 | +static TCGv cpu_fpr[TARGET_FPREGS]; | |
| 58 | 60 | |
| 59 | 61 | #include "gen-icount.h" |
| 60 | 62 | |
| ... | ... | @@ -102,98 +104,77 @@ static int sign_extend(int x, int len) |
| 102 | 104 | /* floating point registers moves */ |
| 103 | 105 | static void gen_op_load_fpr_FT0(unsigned int src) |
| 104 | 106 | { |
| 105 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 106 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0)); | |
| 107 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, ft0)); | |
| 107 | 108 | } |
| 108 | 109 | |
| 109 | 110 | static void gen_op_load_fpr_FT1(unsigned int src) |
| 110 | 111 | { |
| 111 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 112 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft1)); | |
| 112 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, ft1)); | |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | 115 | static void gen_op_store_FT0_fpr(unsigned int dst) |
| 116 | 116 | { |
| 117 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, ft0)); | |
| 118 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); | |
| 117 | + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, ft0)); | |
| 119 | 118 | } |
| 120 | 119 | |
| 121 | 120 | static void gen_op_load_fpr_DT0(unsigned int src) |
| 122 | 121 | { |
| 123 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 124 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 122 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 125 | 123 | offsetof(CPU_DoubleU, l.upper)); |
| 126 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); | |
| 127 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 124 | + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 128 | 125 | offsetof(CPU_DoubleU, l.lower)); |
| 129 | 126 | } |
| 130 | 127 | |
| 131 | 128 | static void gen_op_load_fpr_DT1(unsigned int src) |
| 132 | 129 | { |
| 133 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 134 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + | |
| 130 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, dt1) + | |
| 135 | 131 | offsetof(CPU_DoubleU, l.upper)); |
| 136 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); | |
| 137 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt1) + | |
| 132 | + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, dt1) + | |
| 138 | 133 | offsetof(CPU_DoubleU, l.lower)); |
| 139 | 134 | } |
| 140 | 135 | |
| 141 | 136 | static void gen_op_store_DT0_fpr(unsigned int dst) |
| 142 | 137 | { |
| 143 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 138 | + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 144 | 139 | offsetof(CPU_DoubleU, l.upper)); |
| 145 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); | |
| 146 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 140 | + tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, dt0) + | |
| 147 | 141 | offsetof(CPU_DoubleU, l.lower)); |
| 148 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1])); | |
| 149 | 142 | } |
| 150 | 143 | |
| 151 | 144 | static void gen_op_load_fpr_QT0(unsigned int src) |
| 152 | 145 | { |
| 153 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 154 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 146 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 155 | 147 | offsetof(CPU_QuadU, l.upmost)); |
| 156 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); | |
| 157 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 148 | + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 158 | 149 | offsetof(CPU_QuadU, l.upper)); |
| 159 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2])); | |
| 160 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 150 | + tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 161 | 151 | offsetof(CPU_QuadU, l.lower)); |
| 162 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3])); | |
| 163 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 152 | + tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 164 | 153 | offsetof(CPU_QuadU, l.lowest)); |
| 165 | 154 | } |
| 166 | 155 | |
| 167 | 156 | static void gen_op_load_fpr_QT1(unsigned int src) |
| 168 | 157 | { |
| 169 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src])); | |
| 170 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 158 | + tcg_gen_st_i32(cpu_fpr[src], cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 171 | 159 | offsetof(CPU_QuadU, l.upmost)); |
| 172 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 1])); | |
| 173 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 160 | + tcg_gen_st_i32(cpu_fpr[src + 1], cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 174 | 161 | offsetof(CPU_QuadU, l.upper)); |
| 175 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 2])); | |
| 176 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 162 | + tcg_gen_st_i32(cpu_fpr[src + 2], cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 177 | 163 | offsetof(CPU_QuadU, l.lower)); |
| 178 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[src + 3])); | |
| 179 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 164 | + tcg_gen_st_i32(cpu_fpr[src + 3], cpu_env, offsetof(CPUSPARCState, qt1) + | |
| 180 | 165 | offsetof(CPU_QuadU, l.lowest)); |
| 181 | 166 | } |
| 182 | 167 | |
| 183 | 168 | static void gen_op_store_QT0_fpr(unsigned int dst) |
| 184 | 169 | { |
| 185 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 170 | + tcg_gen_ld_i32(cpu_fpr[dst], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 186 | 171 | offsetof(CPU_QuadU, l.upmost)); |
| 187 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst])); | |
| 188 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 172 | + tcg_gen_ld_i32(cpu_fpr[dst + 1], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 189 | 173 | offsetof(CPU_QuadU, l.upper)); |
| 190 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 1])); | |
| 191 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 174 | + tcg_gen_ld_i32(cpu_fpr[dst + 2], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 192 | 175 | offsetof(CPU_QuadU, l.lower)); |
| 193 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 2])); | |
| 194 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 176 | + tcg_gen_ld_i32(cpu_fpr[dst + 3], cpu_env, offsetof(CPUSPARCState, qt0) + | |
| 195 | 177 | offsetof(CPU_QuadU, l.lowest)); |
| 196 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, offsetof(CPUSPARCState, fpr[dst + 3])); | |
| 197 | 178 | } |
| 198 | 179 | |
| 199 | 180 | /* moves */ |
| ... | ... | @@ -1496,13 +1477,6 @@ static void do_branch_reg(DisasContext *dc, int32_t offset, uint32_t insn, |
| 1496 | 1477 | } |
| 1497 | 1478 | } |
| 1498 | 1479 | |
| 1499 | -static GenOpFunc * const gen_fcmps[4] = { | |
| 1500 | - helper_fcmps, | |
| 1501 | - helper_fcmps_fcc1, | |
| 1502 | - helper_fcmps_fcc2, | |
| 1503 | - helper_fcmps_fcc3, | |
| 1504 | -}; | |
| 1505 | - | |
| 1506 | 1480 | static GenOpFunc * const gen_fcmpd[4] = { |
| 1507 | 1481 | helper_fcmpd, |
| 1508 | 1482 | helper_fcmpd_fcc1, |
| ... | ... | @@ -1517,13 +1491,6 @@ static GenOpFunc * const gen_fcmpq[4] = { |
| 1517 | 1491 | helper_fcmpq_fcc3, |
| 1518 | 1492 | }; |
| 1519 | 1493 | |
| 1520 | -static GenOpFunc * const gen_fcmpes[4] = { | |
| 1521 | - helper_fcmpes, | |
| 1522 | - helper_fcmpes_fcc1, | |
| 1523 | - helper_fcmpes_fcc2, | |
| 1524 | - helper_fcmpes_fcc3, | |
| 1525 | -}; | |
| 1526 | - | |
| 1527 | 1494 | static GenOpFunc * const gen_fcmped[4] = { |
| 1528 | 1495 | helper_fcmped, |
| 1529 | 1496 | helper_fcmped_fcc1, |
| ... | ... | @@ -1538,9 +1505,22 @@ static GenOpFunc * const gen_fcmpeq[4] = { |
| 1538 | 1505 | helper_fcmpeq_fcc3, |
| 1539 | 1506 | }; |
| 1540 | 1507 | |
| 1541 | -static inline void gen_op_fcmps(int fccno) | |
| 1508 | +static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) | |
| 1542 | 1509 | { |
| 1543 | - tcg_gen_helper_0_0(gen_fcmps[fccno]); | |
| 1510 | + switch (fccno) { | |
| 1511 | + case 0: | |
| 1512 | + tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2); | |
| 1513 | + break; | |
| 1514 | + case 1: | |
| 1515 | + tcg_gen_helper_0_2(helper_fcmps_fcc1, r_rs1, r_rs2); | |
| 1516 | + break; | |
| 1517 | + case 2: | |
| 1518 | + tcg_gen_helper_0_2(helper_fcmps_fcc2, r_rs1, r_rs2); | |
| 1519 | + break; | |
| 1520 | + case 3: | |
| 1521 | + tcg_gen_helper_0_2(helper_fcmps_fcc3, r_rs1, r_rs2); | |
| 1522 | + break; | |
| 1523 | + } | |
| 1544 | 1524 | } |
| 1545 | 1525 | |
| 1546 | 1526 | static inline void gen_op_fcmpd(int fccno) |
| ... | ... | @@ -1553,9 +1533,22 @@ static inline void gen_op_fcmpq(int fccno) |
| 1553 | 1533 | tcg_gen_helper_0_0(gen_fcmpq[fccno]); |
| 1554 | 1534 | } |
| 1555 | 1535 | |
| 1556 | -static inline void gen_op_fcmpes(int fccno) | |
| 1536 | +static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) | |
| 1557 | 1537 | { |
| 1558 | - tcg_gen_helper_0_0(gen_fcmpes[fccno]); | |
| 1538 | + switch (fccno) { | |
| 1539 | + case 0: | |
| 1540 | + tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2); | |
| 1541 | + break; | |
| 1542 | + case 1: | |
| 1543 | + tcg_gen_helper_0_2(helper_fcmpes_fcc1, r_rs1, r_rs2); | |
| 1544 | + break; | |
| 1545 | + case 2: | |
| 1546 | + tcg_gen_helper_0_2(helper_fcmpes_fcc2, r_rs1, r_rs2); | |
| 1547 | + break; | |
| 1548 | + case 3: | |
| 1549 | + tcg_gen_helper_0_2(helper_fcmpes_fcc3, r_rs1, r_rs2); | |
| 1550 | + break; | |
| 1551 | + } | |
| 1559 | 1552 | } |
| 1560 | 1553 | |
| 1561 | 1554 | static inline void gen_op_fcmped(int fccno) |
| ... | ... | @@ -1570,9 +1563,9 @@ static inline void gen_op_fcmpeq(int fccno) |
| 1570 | 1563 | |
| 1571 | 1564 | #else |
| 1572 | 1565 | |
| 1573 | -static inline void gen_op_fcmps(int fccno) | |
| 1566 | +static inline void gen_op_fcmps(int fccno, TCGv r_rs1, TCGv r_rs2) | |
| 1574 | 1567 | { |
| 1575 | - tcg_gen_helper_0_0(helper_fcmps); | |
| 1568 | + tcg_gen_helper_0_2(helper_fcmps, r_rs1, r_rs2); | |
| 1576 | 1569 | } |
| 1577 | 1570 | |
| 1578 | 1571 | static inline void gen_op_fcmpd(int fccno) |
| ... | ... | @@ -1585,9 +1578,9 @@ static inline void gen_op_fcmpq(int fccno) |
| 1585 | 1578 | tcg_gen_helper_0_0(helper_fcmpq); |
| 1586 | 1579 | } |
| 1587 | 1580 | |
| 1588 | -static inline void gen_op_fcmpes(int fccno) | |
| 1581 | +static inline void gen_op_fcmpes(int fccno, TCGv r_rs1, TCGv r_rs2) | |
| 1589 | 1582 | { |
| 1590 | - tcg_gen_helper_0_0(helper_fcmpes); | |
| 1583 | + tcg_gen_helper_0_2(helper_fcmpes, r_rs1, r_rs2); | |
| 1591 | 1584 | } |
| 1592 | 1585 | |
| 1593 | 1586 | static inline void gen_op_fcmped(int fccno) |
| ... | ... | @@ -2349,26 +2342,23 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2349 | 2342 | xop = GET_FIELD(insn, 18, 26); |
| 2350 | 2343 | switch (xop) { |
| 2351 | 2344 | case 0x1: /* fmovs */ |
| 2352 | - gen_op_load_fpr_FT0(rs2); | |
| 2353 | - gen_op_store_FT0_fpr(rd); | |
| 2345 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); | |
| 2354 | 2346 | break; |
| 2355 | 2347 | case 0x5: /* fnegs */ |
| 2356 | - gen_op_load_fpr_FT1(rs2); | |
| 2357 | - tcg_gen_helper_0_0(helper_fnegs); | |
| 2358 | - gen_op_store_FT0_fpr(rd); | |
| 2348 | + tcg_gen_helper_1_1(helper_fnegs, cpu_fpr[rd], | |
| 2349 | + cpu_fpr[rs2]); | |
| 2359 | 2350 | break; |
| 2360 | 2351 | case 0x9: /* fabss */ |
| 2361 | - gen_op_load_fpr_FT1(rs2); | |
| 2362 | - tcg_gen_helper_0_0(helper_fabss); | |
| 2363 | - gen_op_store_FT0_fpr(rd); | |
| 2352 | + tcg_gen_helper_1_1(helper_fabss, cpu_fpr[rd], | |
| 2353 | + cpu_fpr[rs2]); | |
| 2364 | 2354 | break; |
| 2365 | 2355 | case 0x29: /* fsqrts */ |
| 2366 | 2356 | CHECK_FPU_FEATURE(dc, FSQRT); |
| 2367 | - gen_op_load_fpr_FT1(rs2); | |
| 2368 | 2357 | gen_clear_float_exceptions(); |
| 2369 | - tcg_gen_helper_0_0(helper_fsqrts); | |
| 2358 | + tcg_gen_helper_1_1(helper_fsqrts, cpu_tmp32, | |
| 2359 | + cpu_fpr[rs2]); | |
| 2370 | 2360 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2371 | - gen_op_store_FT0_fpr(rd); | |
| 2361 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2372 | 2362 | break; |
| 2373 | 2363 | case 0x2a: /* fsqrtd */ |
| 2374 | 2364 | CHECK_FPU_FEATURE(dc, FSQRT); |
| ... | ... | @@ -2386,13 +2376,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2386 | 2376 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2387 | 2377 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 2388 | 2378 | break; |
| 2389 | - case 0x41: | |
| 2390 | - gen_op_load_fpr_FT0(rs1); | |
| 2391 | - gen_op_load_fpr_FT1(rs2); | |
| 2379 | + case 0x41: /* fadds */ | |
| 2392 | 2380 | gen_clear_float_exceptions(); |
| 2393 | - tcg_gen_helper_0_0(helper_fadds); | |
| 2381 | + tcg_gen_helper_1_2(helper_fadds, cpu_tmp32, | |
| 2382 | + cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2394 | 2383 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2395 | - gen_op_store_FT0_fpr(rd); | |
| 2384 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2396 | 2385 | break; |
| 2397 | 2386 | case 0x42: |
| 2398 | 2387 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
| ... | ... | @@ -2411,13 +2400,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2411 | 2400 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2412 | 2401 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 2413 | 2402 | break; |
| 2414 | - case 0x45: | |
| 2415 | - gen_op_load_fpr_FT0(rs1); | |
| 2416 | - gen_op_load_fpr_FT1(rs2); | |
| 2403 | + case 0x45: /* fsubs */ | |
| 2417 | 2404 | gen_clear_float_exceptions(); |
| 2418 | - tcg_gen_helper_0_0(helper_fsubs); | |
| 2405 | + tcg_gen_helper_1_2(helper_fsubs, cpu_tmp32, | |
| 2406 | + cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2419 | 2407 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2420 | - gen_op_store_FT0_fpr(rd); | |
| 2408 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2421 | 2409 | break; |
| 2422 | 2410 | case 0x46: |
| 2423 | 2411 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
| ... | ... | @@ -2438,12 +2426,11 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2438 | 2426 | break; |
| 2439 | 2427 | case 0x49: /* fmuls */ |
| 2440 | 2428 | CHECK_FPU_FEATURE(dc, FMUL); |
| 2441 | - gen_op_load_fpr_FT0(rs1); | |
| 2442 | - gen_op_load_fpr_FT1(rs2); | |
| 2443 | 2429 | gen_clear_float_exceptions(); |
| 2444 | - tcg_gen_helper_0_0(helper_fmuls); | |
| 2430 | + tcg_gen_helper_1_2(helper_fmuls, cpu_tmp32, | |
| 2431 | + cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2445 | 2432 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2446 | - gen_op_store_FT0_fpr(rd); | |
| 2433 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2447 | 2434 | break; |
| 2448 | 2435 | case 0x4a: /* fmuld */ |
| 2449 | 2436 | CHECK_FPU_FEATURE(dc, FMUL); |
| ... | ... | @@ -2464,13 +2451,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2464 | 2451 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2465 | 2452 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 2466 | 2453 | break; |
| 2467 | - case 0x4d: | |
| 2468 | - gen_op_load_fpr_FT0(rs1); | |
| 2469 | - gen_op_load_fpr_FT1(rs2); | |
| 2454 | + case 0x4d: /* fdivs */ | |
| 2470 | 2455 | gen_clear_float_exceptions(); |
| 2471 | - tcg_gen_helper_0_0(helper_fdivs); | |
| 2456 | + tcg_gen_helper_1_2(helper_fdivs, cpu_tmp32, | |
| 2457 | + cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2472 | 2458 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2473 | - gen_op_store_FT0_fpr(rd); | |
| 2459 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2474 | 2460 | break; |
| 2475 | 2461 | case 0x4e: |
| 2476 | 2462 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
| ... | ... | @@ -2507,12 +2493,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2507 | 2493 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2508 | 2494 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 2509 | 2495 | break; |
| 2510 | - case 0xc4: | |
| 2511 | - gen_op_load_fpr_FT1(rs2); | |
| 2496 | + case 0xc4: /* fitos */ | |
| 2512 | 2497 | gen_clear_float_exceptions(); |
| 2513 | - tcg_gen_helper_0_0(helper_fitos); | |
| 2498 | + tcg_gen_helper_1_1(helper_fitos, cpu_tmp32, | |
| 2499 | + cpu_fpr[rs2]); | |
| 2514 | 2500 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2515 | - gen_op_store_FT0_fpr(rd); | |
| 2501 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2516 | 2502 | break; |
| 2517 | 2503 | case 0xc6: |
| 2518 | 2504 | gen_op_load_fpr_DT1(DFPREG(rs2)); |
| ... | ... | @@ -2565,12 +2551,12 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2565 | 2551 | tcg_gen_helper_0_0(helper_fdtoq); |
| 2566 | 2552 | gen_op_store_QT0_fpr(QFPREG(rd)); |
| 2567 | 2553 | break; |
| 2568 | - case 0xd1: | |
| 2569 | - gen_op_load_fpr_FT1(rs2); | |
| 2554 | + case 0xd1: /* fstoi */ | |
| 2570 | 2555 | gen_clear_float_exceptions(); |
| 2571 | - tcg_gen_helper_0_0(helper_fstoi); | |
| 2556 | + tcg_gen_helper_1_1(helper_fstoi, cpu_tmp32, | |
| 2557 | + cpu_fpr[rs2]); | |
| 2572 | 2558 | tcg_gen_helper_0_0(helper_check_ieee_exceptions); |
| 2573 | - gen_op_store_FT0_fpr(rd); | |
| 2559 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_tmp32); | |
| 2574 | 2560 | break; |
| 2575 | 2561 | case 0xd2: |
| 2576 | 2562 | gen_op_load_fpr_DT1(DFPREG(rs2)); |
| ... | ... | @@ -2589,13 +2575,21 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2589 | 2575 | break; |
| 2590 | 2576 | #ifdef TARGET_SPARC64 |
| 2591 | 2577 | case 0x2: /* V9 fmovd */ |
| 2592 | - gen_op_load_fpr_DT0(DFPREG(rs2)); | |
| 2593 | - gen_op_store_DT0_fpr(DFPREG(rd)); | |
| 2578 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], | |
| 2579 | + cpu_fpr[DFPREG(rs2)]); | |
| 2580 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], | |
| 2581 | + cpu_fpr[DFPREG(rs2) + 1]); | |
| 2594 | 2582 | break; |
| 2595 | 2583 | case 0x3: /* V9 fmovq */ |
| 2596 | 2584 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2597 | - gen_op_load_fpr_QT0(QFPREG(rs2)); | |
| 2598 | - gen_op_store_QT0_fpr(QFPREG(rd)); | |
| 2585 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], | |
| 2586 | + cpu_fpr[QFPREG(rs2)]); | |
| 2587 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], | |
| 2588 | + cpu_fpr[QFPREG(rs2) + 1]); | |
| 2589 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], | |
| 2590 | + cpu_fpr[QFPREG(rs2) + 2]); | |
| 2591 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], | |
| 2592 | + cpu_fpr[QFPREG(rs2) + 3]); | |
| 2599 | 2593 | break; |
| 2600 | 2594 | case 0x6: /* V9 fnegd */ |
| 2601 | 2595 | gen_op_load_fpr_DT1(DFPREG(rs2)); |
| ... | ... | @@ -2686,8 +2680,7 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2686 | 2680 | cpu_src1 = get_src1(insn, cpu_src1); |
| 2687 | 2681 | tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, |
| 2688 | 2682 | 0, l1); |
| 2689 | - gen_op_load_fpr_FT0(rs2); | |
| 2690 | - gen_op_store_FT0_fpr(rd); | |
| 2683 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); | |
| 2691 | 2684 | gen_set_label(l1); |
| 2692 | 2685 | break; |
| 2693 | 2686 | } else if ((xop & 0x11f) == 0x006) { // V9 fmovdr |
| ... | ... | @@ -2698,8 +2691,8 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2698 | 2691 | cpu_src1 = get_src1(insn, cpu_src1); |
| 2699 | 2692 | tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, |
| 2700 | 2693 | 0, l1); |
| 2701 | - gen_op_load_fpr_DT0(DFPREG(rs2)); | |
| 2702 | - gen_op_store_DT0_fpr(DFPREG(rd)); | |
| 2694 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], cpu_fpr[DFPREG(rs2)]); | |
| 2695 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], cpu_fpr[DFPREG(rs2) + 1]); | |
| 2703 | 2696 | gen_set_label(l1); |
| 2704 | 2697 | break; |
| 2705 | 2698 | } else if ((xop & 0x11f) == 0x007) { // V9 fmovqr |
| ... | ... | @@ -2711,15 +2704,17 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2711 | 2704 | cpu_src1 = get_src1(insn, cpu_src1); |
| 2712 | 2705 | tcg_gen_brcondi_tl(gen_tcg_cond_reg[cond], cpu_src1, |
| 2713 | 2706 | 0, l1); |
| 2714 | - gen_op_load_fpr_QT0(QFPREG(rs2)); | |
| 2715 | - gen_op_store_QT0_fpr(QFPREG(rd)); | |
| 2707 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], cpu_fpr[QFPREG(rs2)]); | |
| 2708 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], cpu_fpr[QFPREG(rs2) + 1]); | |
| 2709 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], cpu_fpr[QFPREG(rs2) + 2]); | |
| 2710 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], cpu_fpr[QFPREG(rs2) + 3]); | |
| 2716 | 2711 | gen_set_label(l1); |
| 2717 | 2712 | break; |
| 2718 | 2713 | } |
| 2719 | 2714 | #endif |
| 2720 | 2715 | switch (xop) { |
| 2721 | 2716 | #ifdef TARGET_SPARC64 |
| 2722 | -#define FMOVCC(size_FDQ, fcc) \ | |
| 2717 | +#define FMOVSCC(fcc) \ | |
| 2723 | 2718 | { \ |
| 2724 | 2719 | TCGv r_cond; \ |
| 2725 | 2720 | int l1; \ |
| ... | ... | @@ -2730,54 +2725,93 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2730 | 2725 | gen_fcond(r_cond, fcc, cond); \ |
| 2731 | 2726 | tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ |
| 2732 | 2727 | 0, l1); \ |
| 2733 | - glue(glue(gen_op_load_fpr_, size_FDQ), T0) \ | |
| 2734 | - (glue(size_FDQ, FPREG(rs2))); \ | |
| 2735 | - glue(glue(gen_op_store_, size_FDQ), T0_fpr) \ | |
| 2736 | - (glue(size_FDQ, FPREG(rd))); \ | |
| 2728 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ | |
| 2729 | + gen_set_label(l1); \ | |
| 2730 | + tcg_temp_free(r_cond); \ | |
| 2731 | + } | |
| 2732 | +#define FMOVDCC(fcc) \ | |
| 2733 | + { \ | |
| 2734 | + TCGv r_cond; \ | |
| 2735 | + int l1; \ | |
| 2736 | + \ | |
| 2737 | + l1 = gen_new_label(); \ | |
| 2738 | + r_cond = tcg_temp_new(TCG_TYPE_TL); \ | |
| 2739 | + cond = GET_FIELD_SP(insn, 14, 17); \ | |
| 2740 | + gen_fcond(r_cond, fcc, cond); \ | |
| 2741 | + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ | |
| 2742 | + 0, l1); \ | |
| 2743 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ | |
| 2744 | + cpu_fpr[DFPREG(rs2)]); \ | |
| 2745 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ | |
| 2746 | + cpu_fpr[DFPREG(rs2) + 1]); \ | |
| 2747 | + gen_set_label(l1); \ | |
| 2748 | + tcg_temp_free(r_cond); \ | |
| 2749 | + } | |
| 2750 | +#define FMOVQCC(fcc) \ | |
| 2751 | + { \ | |
| 2752 | + TCGv r_cond; \ | |
| 2753 | + int l1; \ | |
| 2754 | + \ | |
| 2755 | + l1 = gen_new_label(); \ | |
| 2756 | + r_cond = tcg_temp_new(TCG_TYPE_TL); \ | |
| 2757 | + cond = GET_FIELD_SP(insn, 14, 17); \ | |
| 2758 | + gen_fcond(r_cond, fcc, cond); \ | |
| 2759 | + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ | |
| 2760 | + 0, l1); \ | |
| 2761 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ | |
| 2762 | + cpu_fpr[QFPREG(rs2)]); \ | |
| 2763 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ | |
| 2764 | + cpu_fpr[QFPREG(rs2) + 1]); \ | |
| 2765 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ | |
| 2766 | + cpu_fpr[QFPREG(rs2) + 2]); \ | |
| 2767 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ | |
| 2768 | + cpu_fpr[QFPREG(rs2) + 3]); \ | |
| 2737 | 2769 | gen_set_label(l1); \ |
| 2738 | 2770 | tcg_temp_free(r_cond); \ |
| 2739 | 2771 | } |
| 2740 | 2772 | case 0x001: /* V9 fmovscc %fcc0 */ |
| 2741 | - FMOVCC(F, 0); | |
| 2773 | + FMOVSCC(0); | |
| 2742 | 2774 | break; |
| 2743 | 2775 | case 0x002: /* V9 fmovdcc %fcc0 */ |
| 2744 | - FMOVCC(D, 0); | |
| 2776 | + FMOVDCC(0); | |
| 2745 | 2777 | break; |
| 2746 | 2778 | case 0x003: /* V9 fmovqcc %fcc0 */ |
| 2747 | 2779 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2748 | - FMOVCC(Q, 0); | |
| 2780 | + FMOVQCC(0); | |
| 2749 | 2781 | break; |
| 2750 | 2782 | case 0x041: /* V9 fmovscc %fcc1 */ |
| 2751 | - FMOVCC(F, 1); | |
| 2783 | + FMOVSCC(1); | |
| 2752 | 2784 | break; |
| 2753 | 2785 | case 0x042: /* V9 fmovdcc %fcc1 */ |
| 2754 | - FMOVCC(D, 1); | |
| 2786 | + FMOVDCC(1); | |
| 2755 | 2787 | break; |
| 2756 | 2788 | case 0x043: /* V9 fmovqcc %fcc1 */ |
| 2757 | 2789 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2758 | - FMOVCC(Q, 1); | |
| 2790 | + FMOVQCC(1); | |
| 2759 | 2791 | break; |
| 2760 | 2792 | case 0x081: /* V9 fmovscc %fcc2 */ |
| 2761 | - FMOVCC(F, 2); | |
| 2793 | + FMOVSCC(2); | |
| 2762 | 2794 | break; |
| 2763 | 2795 | case 0x082: /* V9 fmovdcc %fcc2 */ |
| 2764 | - FMOVCC(D, 2); | |
| 2796 | + FMOVDCC(2); | |
| 2765 | 2797 | break; |
| 2766 | 2798 | case 0x083: /* V9 fmovqcc %fcc2 */ |
| 2767 | 2799 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2768 | - FMOVCC(Q, 2); | |
| 2800 | + FMOVQCC(2); | |
| 2769 | 2801 | break; |
| 2770 | 2802 | case 0x0c1: /* V9 fmovscc %fcc3 */ |
| 2771 | - FMOVCC(F, 3); | |
| 2803 | + FMOVSCC(3); | |
| 2772 | 2804 | break; |
| 2773 | 2805 | case 0x0c2: /* V9 fmovdcc %fcc3 */ |
| 2774 | - FMOVCC(D, 3); | |
| 2806 | + FMOVDCC(3); | |
| 2775 | 2807 | break; |
| 2776 | 2808 | case 0x0c3: /* V9 fmovqcc %fcc3 */ |
| 2777 | 2809 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2778 | - FMOVCC(Q, 3); | |
| 2810 | + FMOVQCC(3); | |
| 2779 | 2811 | break; |
| 2780 | -#undef FMOVCC | |
| 2812 | +#undef FMOVSCC | |
| 2813 | +#undef FMOVDCC | |
| 2814 | +#undef FMOVQCC | |
| 2781 | 2815 | #define FMOVCC(size_FDQ, icc) \ |
| 2782 | 2816 | { \ |
| 2783 | 2817 | TCGv r_cond; \ |
| ... | ... | @@ -2796,32 +2830,87 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2796 | 2830 | gen_set_label(l1); \ |
| 2797 | 2831 | tcg_temp_free(r_cond); \ |
| 2798 | 2832 | } |
| 2833 | +#define FMOVSCC(icc) \ | |
| 2834 | + { \ | |
| 2835 | + TCGv r_cond; \ | |
| 2836 | + int l1; \ | |
| 2837 | + \ | |
| 2838 | + l1 = gen_new_label(); \ | |
| 2839 | + r_cond = tcg_temp_new(TCG_TYPE_TL); \ | |
| 2840 | + cond = GET_FIELD_SP(insn, 14, 17); \ | |
| 2841 | + gen_cond(r_cond, icc, cond); \ | |
| 2842 | + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ | |
| 2843 | + 0, l1); \ | |
| 2844 | + tcg_gen_mov_i32(cpu_fpr[rd], cpu_fpr[rs2]); \ | |
| 2845 | + gen_set_label(l1); \ | |
| 2846 | + tcg_temp_free(r_cond); \ | |
| 2847 | + } | |
| 2848 | +#define FMOVDCC(icc) \ | |
| 2849 | + { \ | |
| 2850 | + TCGv r_cond; \ | |
| 2851 | + int l1; \ | |
| 2852 | + \ | |
| 2853 | + l1 = gen_new_label(); \ | |
| 2854 | + r_cond = tcg_temp_new(TCG_TYPE_TL); \ | |
| 2855 | + cond = GET_FIELD_SP(insn, 14, 17); \ | |
| 2856 | + gen_cond(r_cond, icc, cond); \ | |
| 2857 | + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ | |
| 2858 | + 0, l1); \ | |
| 2859 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd)], \ | |
| 2860 | + cpu_fpr[DFPREG(rs2)]); \ | |
| 2861 | + tcg_gen_mov_i32(cpu_fpr[DFPREG(rd) + 1], \ | |
| 2862 | + cpu_fpr[DFPREG(rs2) + 1]); \ | |
| 2863 | + gen_set_label(l1); \ | |
| 2864 | + tcg_temp_free(r_cond); \ | |
| 2865 | + } | |
| 2866 | +#define FMOVQCC(icc) \ | |
| 2867 | + { \ | |
| 2868 | + TCGv r_cond; \ | |
| 2869 | + int l1; \ | |
| 2870 | + \ | |
| 2871 | + l1 = gen_new_label(); \ | |
| 2872 | + r_cond = tcg_temp_new(TCG_TYPE_TL); \ | |
| 2873 | + cond = GET_FIELD_SP(insn, 14, 17); \ | |
| 2874 | + gen_cond(r_cond, icc, cond); \ | |
| 2875 | + tcg_gen_brcondi_tl(TCG_COND_EQ, r_cond, \ | |
| 2876 | + 0, l1); \ | |
| 2877 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd)], \ | |
| 2878 | + cpu_fpr[QFPREG(rs2)]); \ | |
| 2879 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 1], \ | |
| 2880 | + cpu_fpr[QFPREG(rs2) + 1]); \ | |
| 2881 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 2], \ | |
| 2882 | + cpu_fpr[QFPREG(rs2) + 2]); \ | |
| 2883 | + tcg_gen_mov_i32(cpu_fpr[QFPREG(rd) + 3], \ | |
| 2884 | + cpu_fpr[QFPREG(rs2) + 3]); \ | |
| 2885 | + gen_set_label(l1); \ | |
| 2886 | + tcg_temp_free(r_cond); \ | |
| 2887 | + } | |
| 2799 | 2888 | |
| 2800 | 2889 | case 0x101: /* V9 fmovscc %icc */ |
| 2801 | - FMOVCC(F, 0); | |
| 2890 | + FMOVSCC(0); | |
| 2802 | 2891 | break; |
| 2803 | 2892 | case 0x102: /* V9 fmovdcc %icc */ |
| 2804 | - FMOVCC(D, 0); | |
| 2893 | + FMOVDCC(0); | |
| 2805 | 2894 | case 0x103: /* V9 fmovqcc %icc */ |
| 2806 | 2895 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2807 | - FMOVCC(Q, 0); | |
| 2896 | + FMOVQCC(0); | |
| 2808 | 2897 | break; |
| 2809 | 2898 | case 0x181: /* V9 fmovscc %xcc */ |
| 2810 | - FMOVCC(F, 1); | |
| 2899 | + FMOVSCC(1); | |
| 2811 | 2900 | break; |
| 2812 | 2901 | case 0x182: /* V9 fmovdcc %xcc */ |
| 2813 | - FMOVCC(D, 1); | |
| 2902 | + FMOVDCC(1); | |
| 2814 | 2903 | break; |
| 2815 | 2904 | case 0x183: /* V9 fmovqcc %xcc */ |
| 2816 | 2905 | CHECK_FPU_FEATURE(dc, FLOAT128); |
| 2817 | - FMOVCC(Q, 1); | |
| 2906 | + FMOVQCC(1); | |
| 2818 | 2907 | break; |
| 2819 | -#undef FMOVCC | |
| 2908 | +#undef FMOVSCC | |
| 2909 | +#undef FMOVDCC | |
| 2910 | +#undef FMOVQCC | |
| 2820 | 2911 | #endif |
| 2821 | 2912 | case 0x51: /* fcmps, V9 %fcc */ |
| 2822 | - gen_op_load_fpr_FT0(rs1); | |
| 2823 | - gen_op_load_fpr_FT1(rs2); | |
| 2824 | - gen_op_fcmps(rd & 3); | |
| 2913 | + gen_op_fcmps(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2825 | 2914 | break; |
| 2826 | 2915 | case 0x52: /* fcmpd, V9 %fcc */ |
| 2827 | 2916 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
| ... | ... | @@ -2835,9 +2924,7 @@ static void disas_sparc_insn(DisasContext * dc) |
| 2835 | 2924 | gen_op_fcmpq(rd & 3); |
| 2836 | 2925 | break; |
| 2837 | 2926 | case 0x55: /* fcmpes, V9 %fcc */ |
| 2838 | - gen_op_load_fpr_FT0(rs1); | |
| 2839 | - gen_op_load_fpr_FT1(rs2); | |
| 2840 | - gen_op_fcmpes(rd & 3); | |
| 2927 | + gen_op_fcmpes(rd & 3, cpu_fpr[rs1], cpu_fpr[rs2]); | |
| 2841 | 2928 | break; |
| 2842 | 2929 | case 0x56: /* fcmped, V9 %fcc */ |
| 2843 | 2930 | gen_op_load_fpr_DT0(DFPREG(rs1)); |
| ... | ... | @@ -4364,9 +4451,7 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4364 | 4451 | switch (xop) { |
| 4365 | 4452 | case 0x20: /* load fpreg */ |
| 4366 | 4453 | gen_address_mask(dc, cpu_addr); |
| 4367 | - tcg_gen_qemu_ld32u(cpu_tmp32, cpu_addr, dc->mem_idx); | |
| 4368 | - tcg_gen_st_i32(cpu_tmp32, cpu_env, | |
| 4369 | - offsetof(CPUState, fpr[rd])); | |
| 4454 | + tcg_gen_qemu_ld32u(cpu_fpr[rd], cpu_addr, dc->mem_idx); | |
| 4370 | 4455 | break; |
| 4371 | 4456 | case 0x21: /* ldfsr, V9 ldxfsr */ |
| 4372 | 4457 | #ifdef TARGET_SPARC64 |
| ... | ... | @@ -4508,9 +4593,7 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4508 | 4593 | switch (xop) { |
| 4509 | 4594 | case 0x24: /* store fpreg */ |
| 4510 | 4595 | gen_address_mask(dc, cpu_addr); |
| 4511 | - tcg_gen_ld_i32(cpu_tmp32, cpu_env, | |
| 4512 | - offsetof(CPUState, fpr[rd])); | |
| 4513 | - tcg_gen_qemu_st32(cpu_tmp32, cpu_addr, dc->mem_idx); | |
| 4596 | + tcg_gen_qemu_st32(cpu_fpr[rd], cpu_addr, dc->mem_idx); | |
| 4514 | 4597 | break; |
| 4515 | 4598 | case 0x25: /* stfsr, V9 stxfsr */ |
| 4516 | 4599 | #ifdef TARGET_SPARC64 |
| ... | ... | @@ -4570,7 +4653,6 @@ static void disas_sparc_insn(DisasContext * dc) |
| 4570 | 4653 | switch (xop) { |
| 4571 | 4654 | #ifdef TARGET_SPARC64 |
| 4572 | 4655 | case 0x34: /* V9 stfa */ |
| 4573 | - gen_op_load_fpr_FT0(rd); | |
| 4574 | 4656 | gen_stf_asi(cpu_addr, insn, 4, rd); |
| 4575 | 4657 | break; |
| 4576 | 4658 | case 0x36: /* V9 stqfa */ |
| ... | ... | @@ -4858,6 +4940,16 @@ void gen_intermediate_code_init(CPUSPARCState *env) |
| 4858 | 4940 | "g6", |
| 4859 | 4941 | "g7", |
| 4860 | 4942 | }; |
| 4943 | + static const char * const fregnames[64] = { | |
| 4944 | + "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", | |
| 4945 | + "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", | |
| 4946 | + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", | |
| 4947 | + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", | |
| 4948 | + "f32", "f33", "f34", "f35", "f36", "f37", "f38", "f39", | |
| 4949 | + "f40", "f41", "f42", "f43", "f44", "f45", "f46", "f47", | |
| 4950 | + "f48", "f49", "f50", "f51", "f52", "f53", "f54", "f55", | |
| 4951 | + "f56", "f57", "f58", "f59", "f60", "f61", "f62", "f63", | |
| 4952 | + }; | |
| 4861 | 4953 | |
| 4862 | 4954 | /* init various static tables */ |
| 4863 | 4955 | if (!inited) { |
| ... | ... | @@ -4945,6 +5037,11 @@ void gen_intermediate_code_init(CPUSPARCState *env) |
| 4945 | 5037 | cpu_gregs[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0, |
| 4946 | 5038 | offsetof(CPUState, gregs[i]), |
| 4947 | 5039 | gregnames[i]); |
| 5040 | + for (i = 0; i < TARGET_FPREGS; i++) | |
| 5041 | + cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0, | |
| 5042 | + offsetof(CPUState, fpr[i]), | |
| 5043 | + fregnames[i]); | |
| 5044 | + | |
| 4948 | 5045 | /* register helpers */ |
| 4949 | 5046 | |
| 4950 | 5047 | #undef DEF_HELPER | ... | ... |