15c39f954SPhilippe Mathieu-Daudé /* 25c39f954SPhilippe Mathieu-Daudé * Helpers for HPPA FPU instructions. 35c39f954SPhilippe Mathieu-Daudé * 45c39f954SPhilippe Mathieu-Daudé * Copyright (c) 2016 Richard Henderson <rth@twiddle.net> 55c39f954SPhilippe Mathieu-Daudé * 65c39f954SPhilippe Mathieu-Daudé * This library is free software; you can redistribute it and/or 75c39f954SPhilippe Mathieu-Daudé * modify it under the terms of the GNU Lesser General Public 85c39f954SPhilippe Mathieu-Daudé * License as published by the Free Software Foundation; either 95c39f954SPhilippe Mathieu-Daudé * version 2.1 of the License, or (at your option) any later version. 105c39f954SPhilippe Mathieu-Daudé * 115c39f954SPhilippe Mathieu-Daudé * This library is distributed in the hope that it will be useful, 125c39f954SPhilippe Mathieu-Daudé * but WITHOUT ANY WARRANTY; without even the implied warranty of 135c39f954SPhilippe Mathieu-Daudé * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 145c39f954SPhilippe Mathieu-Daudé * Lesser General Public License for more details. 155c39f954SPhilippe Mathieu-Daudé * 165c39f954SPhilippe Mathieu-Daudé * You should have received a copy of the GNU Lesser General Public 175c39f954SPhilippe Mathieu-Daudé * License along with this library; if not, see <http://www.gnu.org/licenses/>. 185c39f954SPhilippe Mathieu-Daudé */ 195c39f954SPhilippe Mathieu-Daudé 205c39f954SPhilippe Mathieu-Daudé #include "qemu/osdep.h" 215c39f954SPhilippe Mathieu-Daudé #include "cpu.h" 225c39f954SPhilippe Mathieu-Daudé #include "exec/exec-all.h" 235c39f954SPhilippe Mathieu-Daudé #include "exec/helper-proto.h" 245c39f954SPhilippe Mathieu-Daudé #include "fpu/softfloat.h" 255c39f954SPhilippe Mathieu-Daudé 265c39f954SPhilippe Mathieu-Daudé void HELPER(loaded_fr0)(CPUHPPAState *env) 275c39f954SPhilippe Mathieu-Daudé { 285c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr[0] >> 32; 295c39f954SPhilippe Mathieu-Daudé int rm, d; 305c39f954SPhilippe Mathieu-Daudé 315c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 325c39f954SPhilippe Mathieu-Daudé 33f33a22c1SRichard Henderson switch (FIELD_EX32(shadow, FPSR, RM)) { 345c39f954SPhilippe Mathieu-Daudé default: 355c39f954SPhilippe Mathieu-Daudé rm = float_round_nearest_even; 365c39f954SPhilippe Mathieu-Daudé break; 375c39f954SPhilippe Mathieu-Daudé case 1: 385c39f954SPhilippe Mathieu-Daudé rm = float_round_to_zero; 395c39f954SPhilippe Mathieu-Daudé break; 405c39f954SPhilippe Mathieu-Daudé case 2: 415c39f954SPhilippe Mathieu-Daudé rm = float_round_up; 425c39f954SPhilippe Mathieu-Daudé break; 435c39f954SPhilippe Mathieu-Daudé case 3: 445c39f954SPhilippe Mathieu-Daudé rm = float_round_down; 455c39f954SPhilippe Mathieu-Daudé break; 465c39f954SPhilippe Mathieu-Daudé } 475c39f954SPhilippe Mathieu-Daudé set_float_rounding_mode(rm, &env->fp_status); 485c39f954SPhilippe Mathieu-Daudé 49f33a22c1SRichard Henderson d = FIELD_EX32(shadow, FPSR, D); 505c39f954SPhilippe Mathieu-Daudé set_flush_to_zero(d, &env->fp_status); 515c39f954SPhilippe Mathieu-Daudé set_flush_inputs_to_zero(d, &env->fp_status); 522915876eSPeter Maydell 532915876eSPeter Maydell /* 542915876eSPeter Maydell * TODO: we only need to do this at CPU reset, but currently 552915876eSPeter Maydell * HPPA does note implement a CPU reset method at all... 562915876eSPeter Maydell */ 572915876eSPeter Maydell set_float_2nan_prop_rule(float_2nan_prop_s_ab, &env->fp_status); 58f8023791SPeter Maydell /* 59f8023791SPeter Maydell * TODO: The HPPA architecture reference only documents its NaN 60f8023791SPeter Maydell * propagation rule for 2-operand operations. Testing on real hardware 61f8023791SPeter Maydell * might be necessary to confirm whether this order for muladd is correct. 62f8023791SPeter Maydell * Not preferring the SNaN is almost certainly incorrect as it diverges 63f8023791SPeter Maydell * from the documented rules for 2-operand operations. 64f8023791SPeter Maydell */ 65f8023791SPeter Maydell set_float_3nan_prop_rule(float_3nan_prop_abc, &env->fp_status); 662bf5629cSPeter Maydell /* For inf * 0 + NaN, return the input NaN */ 672bf5629cSPeter Maydell set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status); 68e19d721cSPeter Maydell /* Default NaN: sign bit clear, msb-1 frac bit set */ 69e19d721cSPeter Maydell set_float_default_nan_pattern(0b00100000, &env->fp_status); 703abed4d0SPeter Maydell set_snan_bit_is_one(true, &env->fp_status); 7128f13bccSPeter Maydell /* 7228f13bccSPeter Maydell * "PA-RISC 2.0 Architecture" says it is IMPDEF whether the flushing 7328f13bccSPeter Maydell * enabled by FPSR.D happens before or after rounding. We pick "before" 7428f13bccSPeter Maydell * for consistency with tininess detection. 7528f13bccSPeter Maydell */ 7628f13bccSPeter Maydell set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); 7728f13bccSPeter Maydell /* 7828f13bccSPeter Maydell * TODO: "PA-RISC 2.0 Architecture" chapter 10 says that we should 7928f13bccSPeter Maydell * detect tininess before rounding, but we don't set that here so we 8028f13bccSPeter Maydell * get the default tininess after rounding. 8128f13bccSPeter Maydell */ 825c39f954SPhilippe Mathieu-Daudé } 835c39f954SPhilippe Mathieu-Daudé 845c39f954SPhilippe Mathieu-Daudé void cpu_hppa_loaded_fr0(CPUHPPAState *env) 855c39f954SPhilippe Mathieu-Daudé { 865c39f954SPhilippe Mathieu-Daudé helper_loaded_fr0(env); 875c39f954SPhilippe Mathieu-Daudé } 885c39f954SPhilippe Mathieu-Daudé 895c39f954SPhilippe Mathieu-Daudé #define CONVERT_BIT(X, SRC, DST) \ 90f33a22c1SRichard Henderson ((unsigned)(SRC) > (unsigned)(DST) \ 915c39f954SPhilippe Mathieu-Daudé ? (X) / ((SRC) / (DST)) & (DST) \ 925c39f954SPhilippe Mathieu-Daudé : ((X) & (SRC)) * ((DST) / (SRC))) 935c39f954SPhilippe Mathieu-Daudé 945c39f954SPhilippe Mathieu-Daudé static void update_fr0_op(CPUHPPAState *env, uintptr_t ra) 955c39f954SPhilippe Mathieu-Daudé { 965c39f954SPhilippe Mathieu-Daudé uint32_t soft_exp = get_float_exception_flags(&env->fp_status); 975c39f954SPhilippe Mathieu-Daudé uint32_t hard_exp = 0; 98*ebd39494SHelge Deller uint32_t shadow = env->fr0_shadow & 0x3ffffff; 99*ebd39494SHelge Deller uint32_t fr1 = 0; 1005c39f954SPhilippe Mathieu-Daudé 1015c39f954SPhilippe Mathieu-Daudé if (likely(soft_exp == 0)) { 1025c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 1035c39f954SPhilippe Mathieu-Daudé return; 1045c39f954SPhilippe Mathieu-Daudé } 1055c39f954SPhilippe Mathieu-Daudé set_float_exception_flags(0, &env->fp_status); 1065c39f954SPhilippe Mathieu-Daudé 107f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact, R_FPSR_ENA_I_MASK); 108f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, R_FPSR_ENA_U_MASK); 109f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, R_FPSR_ENA_O_MASK); 110f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, R_FPSR_ENA_Z_MASK); 111f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, R_FPSR_ENA_V_MASK); 112*ebd39494SHelge Deller if (hard_exp & shadow) { 113*ebd39494SHelge Deller shadow = FIELD_DP32(shadow, FPSR, T, 1); 114*ebd39494SHelge Deller /* fill exception register #1, which is lower 32-bits of fr[0] */ 115*ebd39494SHelge Deller #if !defined(CONFIG_USER_ONLY) 116*ebd39494SHelge Deller if (hard_exp & (R_FPSR_ENA_O_MASK | R_FPSR_ENA_U_MASK)) { 117*ebd39494SHelge Deller /* over- and underflow both set overflow flag only */ 118*ebd39494SHelge Deller fr1 = FIELD_DP32(fr1, FPSR, C, 1); 119*ebd39494SHelge Deller fr1 = FIELD_DP32(fr1, FPSR, FLG_O, 1); 120*ebd39494SHelge Deller } else 121*ebd39494SHelge Deller #endif 122*ebd39494SHelge Deller { 123*ebd39494SHelge Deller fr1 |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT); 124*ebd39494SHelge Deller } 125*ebd39494SHelge Deller } 1265c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 127*ebd39494SHelge Deller env->fr[0] = (uint64_t)shadow << 32 | fr1; 1285c39f954SPhilippe Mathieu-Daudé 1295c39f954SPhilippe Mathieu-Daudé if (hard_exp & shadow) { 1305c39f954SPhilippe Mathieu-Daudé hppa_dynamic_excp(env, EXCP_ASSIST, ra); 1315c39f954SPhilippe Mathieu-Daudé } 1325c39f954SPhilippe Mathieu-Daudé } 1335c39f954SPhilippe Mathieu-Daudé 1345c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg) 1355c39f954SPhilippe Mathieu-Daudé { 1365c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sqrt(arg, &env->fp_status); 1375c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1385c39f954SPhilippe Mathieu-Daudé return ret; 1395c39f954SPhilippe Mathieu-Daudé } 1405c39f954SPhilippe Mathieu-Daudé 1415c39f954SPhilippe Mathieu-Daudé float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg) 1425c39f954SPhilippe Mathieu-Daudé { 1435c39f954SPhilippe Mathieu-Daudé float32 ret = float32_round_to_int(arg, &env->fp_status); 1445c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1455c39f954SPhilippe Mathieu-Daudé return ret; 1465c39f954SPhilippe Mathieu-Daudé } 1475c39f954SPhilippe Mathieu-Daudé 1485c39f954SPhilippe Mathieu-Daudé float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b) 1495c39f954SPhilippe Mathieu-Daudé { 1505c39f954SPhilippe Mathieu-Daudé float32 ret = float32_add(a, b, &env->fp_status); 1515c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1525c39f954SPhilippe Mathieu-Daudé return ret; 1535c39f954SPhilippe Mathieu-Daudé } 1545c39f954SPhilippe Mathieu-Daudé 1555c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b) 1565c39f954SPhilippe Mathieu-Daudé { 1575c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sub(a, b, &env->fp_status); 1585c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1595c39f954SPhilippe Mathieu-Daudé return ret; 1605c39f954SPhilippe Mathieu-Daudé } 1615c39f954SPhilippe Mathieu-Daudé 1625c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpy_s)(CPUHPPAState *env, float32 a, float32 b) 1635c39f954SPhilippe Mathieu-Daudé { 1645c39f954SPhilippe Mathieu-Daudé float32 ret = float32_mul(a, b, &env->fp_status); 1655c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1665c39f954SPhilippe Mathieu-Daudé return ret; 1675c39f954SPhilippe Mathieu-Daudé } 1685c39f954SPhilippe Mathieu-Daudé 1695c39f954SPhilippe Mathieu-Daudé float32 HELPER(fdiv_s)(CPUHPPAState *env, float32 a, float32 b) 1705c39f954SPhilippe Mathieu-Daudé { 1715c39f954SPhilippe Mathieu-Daudé float32 ret = float32_div(a, b, &env->fp_status); 1725c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1735c39f954SPhilippe Mathieu-Daudé return ret; 1745c39f954SPhilippe Mathieu-Daudé } 1755c39f954SPhilippe Mathieu-Daudé 1765c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg) 1775c39f954SPhilippe Mathieu-Daudé { 1785c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sqrt(arg, &env->fp_status); 1795c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1805c39f954SPhilippe Mathieu-Daudé return ret; 1815c39f954SPhilippe Mathieu-Daudé } 1825c39f954SPhilippe Mathieu-Daudé 1835c39f954SPhilippe Mathieu-Daudé float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg) 1845c39f954SPhilippe Mathieu-Daudé { 1855c39f954SPhilippe Mathieu-Daudé float64 ret = float64_round_to_int(arg, &env->fp_status); 1865c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1875c39f954SPhilippe Mathieu-Daudé return ret; 1885c39f954SPhilippe Mathieu-Daudé } 1895c39f954SPhilippe Mathieu-Daudé 1905c39f954SPhilippe Mathieu-Daudé float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b) 1915c39f954SPhilippe Mathieu-Daudé { 1925c39f954SPhilippe Mathieu-Daudé float64 ret = float64_add(a, b, &env->fp_status); 1935c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1945c39f954SPhilippe Mathieu-Daudé return ret; 1955c39f954SPhilippe Mathieu-Daudé } 1965c39f954SPhilippe Mathieu-Daudé 1975c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsub_d)(CPUHPPAState *env, float64 a, float64 b) 1985c39f954SPhilippe Mathieu-Daudé { 1995c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sub(a, b, &env->fp_status); 2005c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2015c39f954SPhilippe Mathieu-Daudé return ret; 2025c39f954SPhilippe Mathieu-Daudé } 2035c39f954SPhilippe Mathieu-Daudé 2045c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpy_d)(CPUHPPAState *env, float64 a, float64 b) 2055c39f954SPhilippe Mathieu-Daudé { 2065c39f954SPhilippe Mathieu-Daudé float64 ret = float64_mul(a, b, &env->fp_status); 2075c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2085c39f954SPhilippe Mathieu-Daudé return ret; 2095c39f954SPhilippe Mathieu-Daudé } 2105c39f954SPhilippe Mathieu-Daudé 2115c39f954SPhilippe Mathieu-Daudé float64 HELPER(fdiv_d)(CPUHPPAState *env, float64 a, float64 b) 2125c39f954SPhilippe Mathieu-Daudé { 2135c39f954SPhilippe Mathieu-Daudé float64 ret = float64_div(a, b, &env->fp_status); 2145c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2155c39f954SPhilippe Mathieu-Daudé return ret; 2165c39f954SPhilippe Mathieu-Daudé } 2175c39f954SPhilippe Mathieu-Daudé 2185c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_s_d)(CPUHPPAState *env, float32 arg) 2195c39f954SPhilippe Mathieu-Daudé { 2205c39f954SPhilippe Mathieu-Daudé float64 ret = float32_to_float64(arg, &env->fp_status); 2215c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2225c39f954SPhilippe Mathieu-Daudé return ret; 2235c39f954SPhilippe Mathieu-Daudé } 2245c39f954SPhilippe Mathieu-Daudé 2255c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg) 2265c39f954SPhilippe Mathieu-Daudé { 2275c39f954SPhilippe Mathieu-Daudé float32 ret = float64_to_float32(arg, &env->fp_status); 2285c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2295c39f954SPhilippe Mathieu-Daudé return ret; 2305c39f954SPhilippe Mathieu-Daudé } 2315c39f954SPhilippe Mathieu-Daudé 2325c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg) 2335c39f954SPhilippe Mathieu-Daudé { 2345c39f954SPhilippe Mathieu-Daudé float32 ret = int32_to_float32(arg, &env->fp_status); 2355c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2365c39f954SPhilippe Mathieu-Daudé return ret; 2375c39f954SPhilippe Mathieu-Daudé } 2385c39f954SPhilippe Mathieu-Daudé 2395c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg) 2405c39f954SPhilippe Mathieu-Daudé { 2415c39f954SPhilippe Mathieu-Daudé float32 ret = int64_to_float32(arg, &env->fp_status); 2425c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2435c39f954SPhilippe Mathieu-Daudé return ret; 2445c39f954SPhilippe Mathieu-Daudé } 2455c39f954SPhilippe Mathieu-Daudé 2465c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg) 2475c39f954SPhilippe Mathieu-Daudé { 2485c39f954SPhilippe Mathieu-Daudé float64 ret = int32_to_float64(arg, &env->fp_status); 2495c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2505c39f954SPhilippe Mathieu-Daudé return ret; 2515c39f954SPhilippe Mathieu-Daudé } 2525c39f954SPhilippe Mathieu-Daudé 2535c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg) 2545c39f954SPhilippe Mathieu-Daudé { 2555c39f954SPhilippe Mathieu-Daudé float64 ret = int64_to_float64(arg, &env->fp_status); 2565c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2575c39f954SPhilippe Mathieu-Daudé return ret; 2585c39f954SPhilippe Mathieu-Daudé } 2595c39f954SPhilippe Mathieu-Daudé 2605c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg) 2615c39f954SPhilippe Mathieu-Daudé { 2625c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32(arg, &env->fp_status); 2635c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2645c39f954SPhilippe Mathieu-Daudé return ret; 2655c39f954SPhilippe Mathieu-Daudé } 2665c39f954SPhilippe Mathieu-Daudé 2675c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg) 2685c39f954SPhilippe Mathieu-Daudé { 2695c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32(arg, &env->fp_status); 2705c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2715c39f954SPhilippe Mathieu-Daudé return ret; 2725c39f954SPhilippe Mathieu-Daudé } 2735c39f954SPhilippe Mathieu-Daudé 2745c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg) 2755c39f954SPhilippe Mathieu-Daudé { 2765c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64(arg, &env->fp_status); 2775c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2785c39f954SPhilippe Mathieu-Daudé return ret; 2795c39f954SPhilippe Mathieu-Daudé } 2805c39f954SPhilippe Mathieu-Daudé 2815c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg) 2825c39f954SPhilippe Mathieu-Daudé { 2835c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64(arg, &env->fp_status); 2845c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2855c39f954SPhilippe Mathieu-Daudé return ret; 2865c39f954SPhilippe Mathieu-Daudé } 2875c39f954SPhilippe Mathieu-Daudé 2885c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_s_w)(CPUHPPAState *env, float32 arg) 2895c39f954SPhilippe Mathieu-Daudé { 2905c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32_round_to_zero(arg, &env->fp_status); 2915c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2925c39f954SPhilippe Mathieu-Daudé return ret; 2935c39f954SPhilippe Mathieu-Daudé } 2945c39f954SPhilippe Mathieu-Daudé 2955c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg) 2965c39f954SPhilippe Mathieu-Daudé { 2975c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32_round_to_zero(arg, &env->fp_status); 2985c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2995c39f954SPhilippe Mathieu-Daudé return ret; 3005c39f954SPhilippe Mathieu-Daudé } 3015c39f954SPhilippe Mathieu-Daudé 3025c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_s_dw)(CPUHPPAState *env, float32 arg) 3035c39f954SPhilippe Mathieu-Daudé { 3045c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64_round_to_zero(arg, &env->fp_status); 3055c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3065c39f954SPhilippe Mathieu-Daudé return ret; 3075c39f954SPhilippe Mathieu-Daudé } 3085c39f954SPhilippe Mathieu-Daudé 3095c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg) 3105c39f954SPhilippe Mathieu-Daudé { 3115c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64_round_to_zero(arg, &env->fp_status); 3125c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3135c39f954SPhilippe Mathieu-Daudé return ret; 3145c39f954SPhilippe Mathieu-Daudé } 3155c39f954SPhilippe Mathieu-Daudé 3165c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg) 3175c39f954SPhilippe Mathieu-Daudé { 3185c39f954SPhilippe Mathieu-Daudé float32 ret = uint32_to_float32(arg, &env->fp_status); 3195c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3205c39f954SPhilippe Mathieu-Daudé return ret; 3215c39f954SPhilippe Mathieu-Daudé } 3225c39f954SPhilippe Mathieu-Daudé 3235c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg) 3245c39f954SPhilippe Mathieu-Daudé { 3255c39f954SPhilippe Mathieu-Daudé float32 ret = uint64_to_float32(arg, &env->fp_status); 3265c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3275c39f954SPhilippe Mathieu-Daudé return ret; 3285c39f954SPhilippe Mathieu-Daudé } 3295c39f954SPhilippe Mathieu-Daudé 3305c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg) 3315c39f954SPhilippe Mathieu-Daudé { 3325c39f954SPhilippe Mathieu-Daudé float64 ret = uint32_to_float64(arg, &env->fp_status); 3335c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3345c39f954SPhilippe Mathieu-Daudé return ret; 3355c39f954SPhilippe Mathieu-Daudé } 3365c39f954SPhilippe Mathieu-Daudé 3375c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg) 3385c39f954SPhilippe Mathieu-Daudé { 3395c39f954SPhilippe Mathieu-Daudé float64 ret = uint64_to_float64(arg, &env->fp_status); 3405c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3415c39f954SPhilippe Mathieu-Daudé return ret; 3425c39f954SPhilippe Mathieu-Daudé } 3435c39f954SPhilippe Mathieu-Daudé 3445c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg) 3455c39f954SPhilippe Mathieu-Daudé { 3465c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32(arg, &env->fp_status); 3475c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3485c39f954SPhilippe Mathieu-Daudé return ret; 3495c39f954SPhilippe Mathieu-Daudé } 3505c39f954SPhilippe Mathieu-Daudé 3515c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg) 3525c39f954SPhilippe Mathieu-Daudé { 3535c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32(arg, &env->fp_status); 3545c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3555c39f954SPhilippe Mathieu-Daudé return ret; 3565c39f954SPhilippe Mathieu-Daudé } 3575c39f954SPhilippe Mathieu-Daudé 3585c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg) 3595c39f954SPhilippe Mathieu-Daudé { 3605c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64(arg, &env->fp_status); 3615c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3625c39f954SPhilippe Mathieu-Daudé return ret; 3635c39f954SPhilippe Mathieu-Daudé } 3645c39f954SPhilippe Mathieu-Daudé 3655c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg) 3665c39f954SPhilippe Mathieu-Daudé { 3675c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64(arg, &env->fp_status); 3685c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3695c39f954SPhilippe Mathieu-Daudé return ret; 3705c39f954SPhilippe Mathieu-Daudé } 3715c39f954SPhilippe Mathieu-Daudé 3725c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_s_uw)(CPUHPPAState *env, float32 arg) 3735c39f954SPhilippe Mathieu-Daudé { 3745c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32_round_to_zero(arg, &env->fp_status); 3755c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3765c39f954SPhilippe Mathieu-Daudé return ret; 3775c39f954SPhilippe Mathieu-Daudé } 3785c39f954SPhilippe Mathieu-Daudé 3795c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg) 3805c39f954SPhilippe Mathieu-Daudé { 3815c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32_round_to_zero(arg, &env->fp_status); 3825c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3835c39f954SPhilippe Mathieu-Daudé return ret; 3845c39f954SPhilippe Mathieu-Daudé } 3855c39f954SPhilippe Mathieu-Daudé 3865c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_s_udw)(CPUHPPAState *env, float32 arg) 3875c39f954SPhilippe Mathieu-Daudé { 3885c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64_round_to_zero(arg, &env->fp_status); 3895c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3905c39f954SPhilippe Mathieu-Daudé return ret; 3915c39f954SPhilippe Mathieu-Daudé } 3925c39f954SPhilippe Mathieu-Daudé 3935c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg) 3945c39f954SPhilippe Mathieu-Daudé { 3955c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64_round_to_zero(arg, &env->fp_status); 3965c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3975c39f954SPhilippe Mathieu-Daudé return ret; 3985c39f954SPhilippe Mathieu-Daudé } 3995c39f954SPhilippe Mathieu-Daudé 4005c39f954SPhilippe Mathieu-Daudé static void update_fr0_cmp(CPUHPPAState *env, uint32_t y, 4015c39f954SPhilippe Mathieu-Daudé uint32_t c, FloatRelation r) 4025c39f954SPhilippe Mathieu-Daudé { 4035c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr0_shadow; 4045c39f954SPhilippe Mathieu-Daudé 4055c39f954SPhilippe Mathieu-Daudé switch (r) { 4065c39f954SPhilippe Mathieu-Daudé case float_relation_greater: 4075c39f954SPhilippe Mathieu-Daudé c = extract32(c, 4, 1); 4085c39f954SPhilippe Mathieu-Daudé break; 4095c39f954SPhilippe Mathieu-Daudé case float_relation_less: 4105c39f954SPhilippe Mathieu-Daudé c = extract32(c, 3, 1); 4115c39f954SPhilippe Mathieu-Daudé break; 4125c39f954SPhilippe Mathieu-Daudé case float_relation_equal: 4135c39f954SPhilippe Mathieu-Daudé c = extract32(c, 2, 1); 4145c39f954SPhilippe Mathieu-Daudé break; 4155c39f954SPhilippe Mathieu-Daudé case float_relation_unordered: 4165c39f954SPhilippe Mathieu-Daudé c = extract32(c, 1, 1); 4175c39f954SPhilippe Mathieu-Daudé break; 4185c39f954SPhilippe Mathieu-Daudé default: 4195c39f954SPhilippe Mathieu-Daudé g_assert_not_reached(); 4205c39f954SPhilippe Mathieu-Daudé } 4215c39f954SPhilippe Mathieu-Daudé 4225c39f954SPhilippe Mathieu-Daudé if (y) { 4235c39f954SPhilippe Mathieu-Daudé /* targeted comparison */ 4245c39f954SPhilippe Mathieu-Daudé /* set fpsr[ca[y - 1]] to current compare */ 425f33a22c1SRichard Henderson shadow = deposit32(shadow, R_FPSR_CA0_SHIFT - (y - 1), 1, c); 4265c39f954SPhilippe Mathieu-Daudé } else { 4275c39f954SPhilippe Mathieu-Daudé /* queued comparison */ 4285c39f954SPhilippe Mathieu-Daudé /* shift cq right by one place */ 429f33a22c1SRichard Henderson shadow = (shadow & ~R_FPSR_CQ_MASK) | ((shadow >> 1) & R_FPSR_CQ_MASK); 4305c39f954SPhilippe Mathieu-Daudé /* move fpsr[c] to fpsr[cq[0]] */ 431f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, CQ0, FIELD_EX32(shadow, FPSR, C)); 4325c39f954SPhilippe Mathieu-Daudé /* set fpsr[c] to current compare */ 433f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, C, c); 4345c39f954SPhilippe Mathieu-Daudé } 4355c39f954SPhilippe Mathieu-Daudé 4365c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 4375c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 4385c39f954SPhilippe Mathieu-Daudé } 4395c39f954SPhilippe Mathieu-Daudé 4405c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b, 4415c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4425c39f954SPhilippe Mathieu-Daudé { 4435c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4445c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4455c39f954SPhilippe Mathieu-Daudé r = float32_compare(a, b, &env->fp_status); 4465c39f954SPhilippe Mathieu-Daudé } else { 4475c39f954SPhilippe Mathieu-Daudé r = float32_compare_quiet(a, b, &env->fp_status); 4485c39f954SPhilippe Mathieu-Daudé } 4495c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4505c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4515c39f954SPhilippe Mathieu-Daudé } 4525c39f954SPhilippe Mathieu-Daudé 4535c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b, 4545c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4555c39f954SPhilippe Mathieu-Daudé { 4565c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4575c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4585c39f954SPhilippe Mathieu-Daudé r = float64_compare(a, b, &env->fp_status); 4595c39f954SPhilippe Mathieu-Daudé } else { 4605c39f954SPhilippe Mathieu-Daudé r = float64_compare_quiet(a, b, &env->fp_status); 4615c39f954SPhilippe Mathieu-Daudé } 4625c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4635c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4645c39f954SPhilippe Mathieu-Daudé } 4655c39f954SPhilippe Mathieu-Daudé 4665c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4675c39f954SPhilippe Mathieu-Daudé { 4685c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, 0, &env->fp_status); 4695c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4705c39f954SPhilippe Mathieu-Daudé return ret; 4715c39f954SPhilippe Mathieu-Daudé } 4725c39f954SPhilippe Mathieu-Daudé 4735c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4745c39f954SPhilippe Mathieu-Daudé { 4755c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, float_muladd_negate_product, 4765c39f954SPhilippe Mathieu-Daudé &env->fp_status); 4775c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4785c39f954SPhilippe Mathieu-Daudé return ret; 4795c39f954SPhilippe Mathieu-Daudé } 4805c39f954SPhilippe Mathieu-Daudé 4815c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4825c39f954SPhilippe Mathieu-Daudé { 4835c39f954SPhilippe Mathieu-Daudé float64 ret = float64_muladd(a, b, c, 0, &env->fp_status); 4845c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4855c39f954SPhilippe Mathieu-Daudé return ret; 4865c39f954SPhilippe Mathieu-Daudé } 4875c39f954SPhilippe Mathieu-Daudé 4885c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4895c39f954SPhilippe Mathieu-Daudé { 4905c39f954SPhilippe Mathieu-Daudé float64 ret = float64_muladd(a, b, c, float_muladd_negate_product, 4915c39f954SPhilippe Mathieu-Daudé &env->fp_status); 4925c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4935c39f954SPhilippe Mathieu-Daudé return ret; 4945c39f954SPhilippe Mathieu-Daudé } 495