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