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); 70*28f13bccSPeter Maydell /* 71*28f13bccSPeter Maydell * "PA-RISC 2.0 Architecture" says it is IMPDEF whether the flushing 72*28f13bccSPeter Maydell * enabled by FPSR.D happens before or after rounding. We pick "before" 73*28f13bccSPeter Maydell * for consistency with tininess detection. 74*28f13bccSPeter Maydell */ 75*28f13bccSPeter Maydell set_float_ftz_detection(float_ftz_before_rounding, &env->fp_status); 76*28f13bccSPeter Maydell /* 77*28f13bccSPeter Maydell * TODO: "PA-RISC 2.0 Architecture" chapter 10 says that we should 78*28f13bccSPeter Maydell * detect tininess before rounding, but we don't set that here so we 79*28f13bccSPeter Maydell * get the default tininess after rounding. 80*28f13bccSPeter Maydell */ 815c39f954SPhilippe Mathieu-Daudé } 825c39f954SPhilippe Mathieu-Daudé 835c39f954SPhilippe Mathieu-Daudé void cpu_hppa_loaded_fr0(CPUHPPAState *env) 845c39f954SPhilippe Mathieu-Daudé { 855c39f954SPhilippe Mathieu-Daudé helper_loaded_fr0(env); 865c39f954SPhilippe Mathieu-Daudé } 875c39f954SPhilippe Mathieu-Daudé 885c39f954SPhilippe Mathieu-Daudé #define CONVERT_BIT(X, SRC, DST) \ 89f33a22c1SRichard Henderson ((unsigned)(SRC) > (unsigned)(DST) \ 905c39f954SPhilippe Mathieu-Daudé ? (X) / ((SRC) / (DST)) & (DST) \ 915c39f954SPhilippe Mathieu-Daudé : ((X) & (SRC)) * ((DST) / (SRC))) 925c39f954SPhilippe Mathieu-Daudé 935c39f954SPhilippe Mathieu-Daudé static void update_fr0_op(CPUHPPAState *env, uintptr_t ra) 945c39f954SPhilippe Mathieu-Daudé { 955c39f954SPhilippe Mathieu-Daudé uint32_t soft_exp = get_float_exception_flags(&env->fp_status); 965c39f954SPhilippe Mathieu-Daudé uint32_t hard_exp = 0; 975c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr0_shadow; 985c39f954SPhilippe Mathieu-Daudé 995c39f954SPhilippe Mathieu-Daudé if (likely(soft_exp == 0)) { 1005c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 1015c39f954SPhilippe Mathieu-Daudé return; 1025c39f954SPhilippe Mathieu-Daudé } 1035c39f954SPhilippe Mathieu-Daudé set_float_exception_flags(0, &env->fp_status); 1045c39f954SPhilippe Mathieu-Daudé 105f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact, R_FPSR_ENA_I_MASK); 106f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, R_FPSR_ENA_U_MASK); 107f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, R_FPSR_ENA_O_MASK); 108f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, R_FPSR_ENA_Z_MASK); 109f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, R_FPSR_ENA_V_MASK); 110f33a22c1SRichard Henderson shadow |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT); 1115c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 1125c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 1135c39f954SPhilippe Mathieu-Daudé 1145c39f954SPhilippe Mathieu-Daudé if (hard_exp & shadow) { 1155c39f954SPhilippe Mathieu-Daudé hppa_dynamic_excp(env, EXCP_ASSIST, ra); 1165c39f954SPhilippe Mathieu-Daudé } 1175c39f954SPhilippe Mathieu-Daudé } 1185c39f954SPhilippe Mathieu-Daudé 1195c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg) 1205c39f954SPhilippe Mathieu-Daudé { 1215c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sqrt(arg, &env->fp_status); 1225c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1235c39f954SPhilippe Mathieu-Daudé return ret; 1245c39f954SPhilippe Mathieu-Daudé } 1255c39f954SPhilippe Mathieu-Daudé 1265c39f954SPhilippe Mathieu-Daudé float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg) 1275c39f954SPhilippe Mathieu-Daudé { 1285c39f954SPhilippe Mathieu-Daudé float32 ret = float32_round_to_int(arg, &env->fp_status); 1295c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1305c39f954SPhilippe Mathieu-Daudé return ret; 1315c39f954SPhilippe Mathieu-Daudé } 1325c39f954SPhilippe Mathieu-Daudé 1335c39f954SPhilippe Mathieu-Daudé float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b) 1345c39f954SPhilippe Mathieu-Daudé { 1355c39f954SPhilippe Mathieu-Daudé float32 ret = float32_add(a, b, &env->fp_status); 1365c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1375c39f954SPhilippe Mathieu-Daudé return ret; 1385c39f954SPhilippe Mathieu-Daudé } 1395c39f954SPhilippe Mathieu-Daudé 1405c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b) 1415c39f954SPhilippe Mathieu-Daudé { 1425c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sub(a, b, &env->fp_status); 1435c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1445c39f954SPhilippe Mathieu-Daudé return ret; 1455c39f954SPhilippe Mathieu-Daudé } 1465c39f954SPhilippe Mathieu-Daudé 1475c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpy_s)(CPUHPPAState *env, float32 a, float32 b) 1485c39f954SPhilippe Mathieu-Daudé { 1495c39f954SPhilippe Mathieu-Daudé float32 ret = float32_mul(a, b, &env->fp_status); 1505c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1515c39f954SPhilippe Mathieu-Daudé return ret; 1525c39f954SPhilippe Mathieu-Daudé } 1535c39f954SPhilippe Mathieu-Daudé 1545c39f954SPhilippe Mathieu-Daudé float32 HELPER(fdiv_s)(CPUHPPAState *env, float32 a, float32 b) 1555c39f954SPhilippe Mathieu-Daudé { 1565c39f954SPhilippe Mathieu-Daudé float32 ret = float32_div(a, b, &env->fp_status); 1575c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1585c39f954SPhilippe Mathieu-Daudé return ret; 1595c39f954SPhilippe Mathieu-Daudé } 1605c39f954SPhilippe Mathieu-Daudé 1615c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg) 1625c39f954SPhilippe Mathieu-Daudé { 1635c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sqrt(arg, &env->fp_status); 1645c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1655c39f954SPhilippe Mathieu-Daudé return ret; 1665c39f954SPhilippe Mathieu-Daudé } 1675c39f954SPhilippe Mathieu-Daudé 1685c39f954SPhilippe Mathieu-Daudé float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg) 1695c39f954SPhilippe Mathieu-Daudé { 1705c39f954SPhilippe Mathieu-Daudé float64 ret = float64_round_to_int(arg, &env->fp_status); 1715c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1725c39f954SPhilippe Mathieu-Daudé return ret; 1735c39f954SPhilippe Mathieu-Daudé } 1745c39f954SPhilippe Mathieu-Daudé 1755c39f954SPhilippe Mathieu-Daudé float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b) 1765c39f954SPhilippe Mathieu-Daudé { 1775c39f954SPhilippe Mathieu-Daudé float64 ret = float64_add(a, b, &env->fp_status); 1785c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1795c39f954SPhilippe Mathieu-Daudé return ret; 1805c39f954SPhilippe Mathieu-Daudé } 1815c39f954SPhilippe Mathieu-Daudé 1825c39f954SPhilippe Mathieu-Daudé float64 HELPER(fsub_d)(CPUHPPAState *env, float64 a, float64 b) 1835c39f954SPhilippe Mathieu-Daudé { 1845c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sub(a, b, &env->fp_status); 1855c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1865c39f954SPhilippe Mathieu-Daudé return ret; 1875c39f954SPhilippe Mathieu-Daudé } 1885c39f954SPhilippe Mathieu-Daudé 1895c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpy_d)(CPUHPPAState *env, float64 a, float64 b) 1905c39f954SPhilippe Mathieu-Daudé { 1915c39f954SPhilippe Mathieu-Daudé float64 ret = float64_mul(a, b, &env->fp_status); 1925c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1935c39f954SPhilippe Mathieu-Daudé return ret; 1945c39f954SPhilippe Mathieu-Daudé } 1955c39f954SPhilippe Mathieu-Daudé 1965c39f954SPhilippe Mathieu-Daudé float64 HELPER(fdiv_d)(CPUHPPAState *env, float64 a, float64 b) 1975c39f954SPhilippe Mathieu-Daudé { 1985c39f954SPhilippe Mathieu-Daudé float64 ret = float64_div(a, b, &env->fp_status); 1995c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2005c39f954SPhilippe Mathieu-Daudé return ret; 2015c39f954SPhilippe Mathieu-Daudé } 2025c39f954SPhilippe Mathieu-Daudé 2035c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_s_d)(CPUHPPAState *env, float32 arg) 2045c39f954SPhilippe Mathieu-Daudé { 2055c39f954SPhilippe Mathieu-Daudé float64 ret = float32_to_float64(arg, &env->fp_status); 2065c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2075c39f954SPhilippe Mathieu-Daudé return ret; 2085c39f954SPhilippe Mathieu-Daudé } 2095c39f954SPhilippe Mathieu-Daudé 2105c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg) 2115c39f954SPhilippe Mathieu-Daudé { 2125c39f954SPhilippe Mathieu-Daudé float32 ret = float64_to_float32(arg, &env->fp_status); 2135c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2145c39f954SPhilippe Mathieu-Daudé return ret; 2155c39f954SPhilippe Mathieu-Daudé } 2165c39f954SPhilippe Mathieu-Daudé 2175c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg) 2185c39f954SPhilippe Mathieu-Daudé { 2195c39f954SPhilippe Mathieu-Daudé float32 ret = int32_to_float32(arg, &env->fp_status); 2205c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2215c39f954SPhilippe Mathieu-Daudé return ret; 2225c39f954SPhilippe Mathieu-Daudé } 2235c39f954SPhilippe Mathieu-Daudé 2245c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg) 2255c39f954SPhilippe Mathieu-Daudé { 2265c39f954SPhilippe Mathieu-Daudé float32 ret = int64_to_float32(arg, &env->fp_status); 2275c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2285c39f954SPhilippe Mathieu-Daudé return ret; 2295c39f954SPhilippe Mathieu-Daudé } 2305c39f954SPhilippe Mathieu-Daudé 2315c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg) 2325c39f954SPhilippe Mathieu-Daudé { 2335c39f954SPhilippe Mathieu-Daudé float64 ret = int32_to_float64(arg, &env->fp_status); 2345c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2355c39f954SPhilippe Mathieu-Daudé return ret; 2365c39f954SPhilippe Mathieu-Daudé } 2375c39f954SPhilippe Mathieu-Daudé 2385c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg) 2395c39f954SPhilippe Mathieu-Daudé { 2405c39f954SPhilippe Mathieu-Daudé float64 ret = int64_to_float64(arg, &env->fp_status); 2415c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2425c39f954SPhilippe Mathieu-Daudé return ret; 2435c39f954SPhilippe Mathieu-Daudé } 2445c39f954SPhilippe Mathieu-Daudé 2455c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg) 2465c39f954SPhilippe Mathieu-Daudé { 2475c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32(arg, &env->fp_status); 2485c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2495c39f954SPhilippe Mathieu-Daudé return ret; 2505c39f954SPhilippe Mathieu-Daudé } 2515c39f954SPhilippe Mathieu-Daudé 2525c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg) 2535c39f954SPhilippe Mathieu-Daudé { 2545c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32(arg, &env->fp_status); 2555c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2565c39f954SPhilippe Mathieu-Daudé return ret; 2575c39f954SPhilippe Mathieu-Daudé } 2585c39f954SPhilippe Mathieu-Daudé 2595c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg) 2605c39f954SPhilippe Mathieu-Daudé { 2615c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64(arg, &env->fp_status); 2625c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2635c39f954SPhilippe Mathieu-Daudé return ret; 2645c39f954SPhilippe Mathieu-Daudé } 2655c39f954SPhilippe Mathieu-Daudé 2665c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg) 2675c39f954SPhilippe Mathieu-Daudé { 2685c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64(arg, &env->fp_status); 2695c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2705c39f954SPhilippe Mathieu-Daudé return ret; 2715c39f954SPhilippe Mathieu-Daudé } 2725c39f954SPhilippe Mathieu-Daudé 2735c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_s_w)(CPUHPPAState *env, float32 arg) 2745c39f954SPhilippe Mathieu-Daudé { 2755c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32_round_to_zero(arg, &env->fp_status); 2765c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2775c39f954SPhilippe Mathieu-Daudé return ret; 2785c39f954SPhilippe Mathieu-Daudé } 2795c39f954SPhilippe Mathieu-Daudé 2805c39f954SPhilippe Mathieu-Daudé int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg) 2815c39f954SPhilippe Mathieu-Daudé { 2825c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32_round_to_zero(arg, &env->fp_status); 2835c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2845c39f954SPhilippe Mathieu-Daudé return ret; 2855c39f954SPhilippe Mathieu-Daudé } 2865c39f954SPhilippe Mathieu-Daudé 2875c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_s_dw)(CPUHPPAState *env, float32 arg) 2885c39f954SPhilippe Mathieu-Daudé { 2895c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64_round_to_zero(arg, &env->fp_status); 2905c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2915c39f954SPhilippe Mathieu-Daudé return ret; 2925c39f954SPhilippe Mathieu-Daudé } 2935c39f954SPhilippe Mathieu-Daudé 2945c39f954SPhilippe Mathieu-Daudé int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg) 2955c39f954SPhilippe Mathieu-Daudé { 2965c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64_round_to_zero(arg, &env->fp_status); 2975c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 2985c39f954SPhilippe Mathieu-Daudé return ret; 2995c39f954SPhilippe Mathieu-Daudé } 3005c39f954SPhilippe Mathieu-Daudé 3015c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg) 3025c39f954SPhilippe Mathieu-Daudé { 3035c39f954SPhilippe Mathieu-Daudé float32 ret = uint32_to_float32(arg, &env->fp_status); 3045c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3055c39f954SPhilippe Mathieu-Daudé return ret; 3065c39f954SPhilippe Mathieu-Daudé } 3075c39f954SPhilippe Mathieu-Daudé 3085c39f954SPhilippe Mathieu-Daudé float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg) 3095c39f954SPhilippe Mathieu-Daudé { 3105c39f954SPhilippe Mathieu-Daudé float32 ret = uint64_to_float32(arg, &env->fp_status); 3115c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3125c39f954SPhilippe Mathieu-Daudé return ret; 3135c39f954SPhilippe Mathieu-Daudé } 3145c39f954SPhilippe Mathieu-Daudé 3155c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg) 3165c39f954SPhilippe Mathieu-Daudé { 3175c39f954SPhilippe Mathieu-Daudé float64 ret = uint32_to_float64(arg, &env->fp_status); 3185c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3195c39f954SPhilippe Mathieu-Daudé return ret; 3205c39f954SPhilippe Mathieu-Daudé } 3215c39f954SPhilippe Mathieu-Daudé 3225c39f954SPhilippe Mathieu-Daudé float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg) 3235c39f954SPhilippe Mathieu-Daudé { 3245c39f954SPhilippe Mathieu-Daudé float64 ret = uint64_to_float64(arg, &env->fp_status); 3255c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3265c39f954SPhilippe Mathieu-Daudé return ret; 3275c39f954SPhilippe Mathieu-Daudé } 3285c39f954SPhilippe Mathieu-Daudé 3295c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg) 3305c39f954SPhilippe Mathieu-Daudé { 3315c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32(arg, &env->fp_status); 3325c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3335c39f954SPhilippe Mathieu-Daudé return ret; 3345c39f954SPhilippe Mathieu-Daudé } 3355c39f954SPhilippe Mathieu-Daudé 3365c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg) 3375c39f954SPhilippe Mathieu-Daudé { 3385c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32(arg, &env->fp_status); 3395c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3405c39f954SPhilippe Mathieu-Daudé return ret; 3415c39f954SPhilippe Mathieu-Daudé } 3425c39f954SPhilippe Mathieu-Daudé 3435c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg) 3445c39f954SPhilippe Mathieu-Daudé { 3455c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64(arg, &env->fp_status); 3465c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3475c39f954SPhilippe Mathieu-Daudé return ret; 3485c39f954SPhilippe Mathieu-Daudé } 3495c39f954SPhilippe Mathieu-Daudé 3505c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg) 3515c39f954SPhilippe Mathieu-Daudé { 3525c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64(arg, &env->fp_status); 3535c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3545c39f954SPhilippe Mathieu-Daudé return ret; 3555c39f954SPhilippe Mathieu-Daudé } 3565c39f954SPhilippe Mathieu-Daudé 3575c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_s_uw)(CPUHPPAState *env, float32 arg) 3585c39f954SPhilippe Mathieu-Daudé { 3595c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32_round_to_zero(arg, &env->fp_status); 3605c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3615c39f954SPhilippe Mathieu-Daudé return ret; 3625c39f954SPhilippe Mathieu-Daudé } 3635c39f954SPhilippe Mathieu-Daudé 3645c39f954SPhilippe Mathieu-Daudé uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg) 3655c39f954SPhilippe Mathieu-Daudé { 3665c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32_round_to_zero(arg, &env->fp_status); 3675c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3685c39f954SPhilippe Mathieu-Daudé return ret; 3695c39f954SPhilippe Mathieu-Daudé } 3705c39f954SPhilippe Mathieu-Daudé 3715c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_s_udw)(CPUHPPAState *env, float32 arg) 3725c39f954SPhilippe Mathieu-Daudé { 3735c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64_round_to_zero(arg, &env->fp_status); 3745c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3755c39f954SPhilippe Mathieu-Daudé return ret; 3765c39f954SPhilippe Mathieu-Daudé } 3775c39f954SPhilippe Mathieu-Daudé 3785c39f954SPhilippe Mathieu-Daudé uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg) 3795c39f954SPhilippe Mathieu-Daudé { 3805c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64_round_to_zero(arg, &env->fp_status); 3815c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 3825c39f954SPhilippe Mathieu-Daudé return ret; 3835c39f954SPhilippe Mathieu-Daudé } 3845c39f954SPhilippe Mathieu-Daudé 3855c39f954SPhilippe Mathieu-Daudé static void update_fr0_cmp(CPUHPPAState *env, uint32_t y, 3865c39f954SPhilippe Mathieu-Daudé uint32_t c, FloatRelation r) 3875c39f954SPhilippe Mathieu-Daudé { 3885c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr0_shadow; 3895c39f954SPhilippe Mathieu-Daudé 3905c39f954SPhilippe Mathieu-Daudé switch (r) { 3915c39f954SPhilippe Mathieu-Daudé case float_relation_greater: 3925c39f954SPhilippe Mathieu-Daudé c = extract32(c, 4, 1); 3935c39f954SPhilippe Mathieu-Daudé break; 3945c39f954SPhilippe Mathieu-Daudé case float_relation_less: 3955c39f954SPhilippe Mathieu-Daudé c = extract32(c, 3, 1); 3965c39f954SPhilippe Mathieu-Daudé break; 3975c39f954SPhilippe Mathieu-Daudé case float_relation_equal: 3985c39f954SPhilippe Mathieu-Daudé c = extract32(c, 2, 1); 3995c39f954SPhilippe Mathieu-Daudé break; 4005c39f954SPhilippe Mathieu-Daudé case float_relation_unordered: 4015c39f954SPhilippe Mathieu-Daudé c = extract32(c, 1, 1); 4025c39f954SPhilippe Mathieu-Daudé break; 4035c39f954SPhilippe Mathieu-Daudé default: 4045c39f954SPhilippe Mathieu-Daudé g_assert_not_reached(); 4055c39f954SPhilippe Mathieu-Daudé } 4065c39f954SPhilippe Mathieu-Daudé 4075c39f954SPhilippe Mathieu-Daudé if (y) { 4085c39f954SPhilippe Mathieu-Daudé /* targeted comparison */ 4095c39f954SPhilippe Mathieu-Daudé /* set fpsr[ca[y - 1]] to current compare */ 410f33a22c1SRichard Henderson shadow = deposit32(shadow, R_FPSR_CA0_SHIFT - (y - 1), 1, c); 4115c39f954SPhilippe Mathieu-Daudé } else { 4125c39f954SPhilippe Mathieu-Daudé /* queued comparison */ 4135c39f954SPhilippe Mathieu-Daudé /* shift cq right by one place */ 414f33a22c1SRichard Henderson shadow = (shadow & ~R_FPSR_CQ_MASK) | ((shadow >> 1) & R_FPSR_CQ_MASK); 4155c39f954SPhilippe Mathieu-Daudé /* move fpsr[c] to fpsr[cq[0]] */ 416f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, CQ0, FIELD_EX32(shadow, FPSR, C)); 4175c39f954SPhilippe Mathieu-Daudé /* set fpsr[c] to current compare */ 418f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, C, c); 4195c39f954SPhilippe Mathieu-Daudé } 4205c39f954SPhilippe Mathieu-Daudé 4215c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 4225c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 4235c39f954SPhilippe Mathieu-Daudé } 4245c39f954SPhilippe Mathieu-Daudé 4255c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b, 4265c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4275c39f954SPhilippe Mathieu-Daudé { 4285c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4295c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4305c39f954SPhilippe Mathieu-Daudé r = float32_compare(a, b, &env->fp_status); 4315c39f954SPhilippe Mathieu-Daudé } else { 4325c39f954SPhilippe Mathieu-Daudé r = float32_compare_quiet(a, b, &env->fp_status); 4335c39f954SPhilippe Mathieu-Daudé } 4345c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4355c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4365c39f954SPhilippe Mathieu-Daudé } 4375c39f954SPhilippe Mathieu-Daudé 4385c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b, 4395c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4405c39f954SPhilippe Mathieu-Daudé { 4415c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4425c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4435c39f954SPhilippe Mathieu-Daudé r = float64_compare(a, b, &env->fp_status); 4445c39f954SPhilippe Mathieu-Daudé } else { 4455c39f954SPhilippe Mathieu-Daudé r = float64_compare_quiet(a, b, &env->fp_status); 4465c39f954SPhilippe Mathieu-Daudé } 4475c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4485c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4495c39f954SPhilippe Mathieu-Daudé } 4505c39f954SPhilippe Mathieu-Daudé 4515c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4525c39f954SPhilippe Mathieu-Daudé { 4535c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, 0, &env->fp_status); 4545c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4555c39f954SPhilippe Mathieu-Daudé return ret; 4565c39f954SPhilippe Mathieu-Daudé } 4575c39f954SPhilippe Mathieu-Daudé 4585c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4595c39f954SPhilippe Mathieu-Daudé { 4605c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, float_muladd_negate_product, 4615c39f954SPhilippe Mathieu-Daudé &env->fp_status); 4625c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4635c39f954SPhilippe Mathieu-Daudé return ret; 4645c39f954SPhilippe Mathieu-Daudé } 4655c39f954SPhilippe Mathieu-Daudé 4665c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4675c39f954SPhilippe Mathieu-Daudé { 4685c39f954SPhilippe Mathieu-Daudé float64 ret = float64_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é float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4745c39f954SPhilippe Mathieu-Daudé { 4755c39f954SPhilippe Mathieu-Daudé float64 ret = float64_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é } 480