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); 58*2bf5629cSPeter Maydell /* For inf * 0 + NaN, return the input NaN */ 59*2bf5629cSPeter Maydell set_float_infzeronan_rule(float_infzeronan_dnan_never, &env->fp_status); 605c39f954SPhilippe Mathieu-Daudé } 615c39f954SPhilippe Mathieu-Daudé 625c39f954SPhilippe Mathieu-Daudé void cpu_hppa_loaded_fr0(CPUHPPAState *env) 635c39f954SPhilippe Mathieu-Daudé { 645c39f954SPhilippe Mathieu-Daudé helper_loaded_fr0(env); 655c39f954SPhilippe Mathieu-Daudé } 665c39f954SPhilippe Mathieu-Daudé 675c39f954SPhilippe Mathieu-Daudé #define CONVERT_BIT(X, SRC, DST) \ 68f33a22c1SRichard Henderson ((unsigned)(SRC) > (unsigned)(DST) \ 695c39f954SPhilippe Mathieu-Daudé ? (X) / ((SRC) / (DST)) & (DST) \ 705c39f954SPhilippe Mathieu-Daudé : ((X) & (SRC)) * ((DST) / (SRC))) 715c39f954SPhilippe Mathieu-Daudé 725c39f954SPhilippe Mathieu-Daudé static void update_fr0_op(CPUHPPAState *env, uintptr_t ra) 735c39f954SPhilippe Mathieu-Daudé { 745c39f954SPhilippe Mathieu-Daudé uint32_t soft_exp = get_float_exception_flags(&env->fp_status); 755c39f954SPhilippe Mathieu-Daudé uint32_t hard_exp = 0; 765c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr0_shadow; 775c39f954SPhilippe Mathieu-Daudé 785c39f954SPhilippe Mathieu-Daudé if (likely(soft_exp == 0)) { 795c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 805c39f954SPhilippe Mathieu-Daudé return; 815c39f954SPhilippe Mathieu-Daudé } 825c39f954SPhilippe Mathieu-Daudé set_float_exception_flags(0, &env->fp_status); 835c39f954SPhilippe Mathieu-Daudé 84f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_inexact, R_FPSR_ENA_I_MASK); 85f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_underflow, R_FPSR_ENA_U_MASK); 86f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_overflow, R_FPSR_ENA_O_MASK); 87f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_divbyzero, R_FPSR_ENA_Z_MASK); 88f33a22c1SRichard Henderson hard_exp |= CONVERT_BIT(soft_exp, float_flag_invalid, R_FPSR_ENA_V_MASK); 89f33a22c1SRichard Henderson shadow |= hard_exp << (R_FPSR_FLAGS_SHIFT - R_FPSR_ENABLES_SHIFT); 905c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 915c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 925c39f954SPhilippe Mathieu-Daudé 935c39f954SPhilippe Mathieu-Daudé if (hard_exp & shadow) { 945c39f954SPhilippe Mathieu-Daudé hppa_dynamic_excp(env, EXCP_ASSIST, ra); 955c39f954SPhilippe Mathieu-Daudé } 965c39f954SPhilippe Mathieu-Daudé } 975c39f954SPhilippe Mathieu-Daudé 985c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsqrt_s)(CPUHPPAState *env, float32 arg) 995c39f954SPhilippe Mathieu-Daudé { 1005c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sqrt(arg, &env->fp_status); 1015c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1025c39f954SPhilippe Mathieu-Daudé return ret; 1035c39f954SPhilippe Mathieu-Daudé } 1045c39f954SPhilippe Mathieu-Daudé 1055c39f954SPhilippe Mathieu-Daudé float32 HELPER(frnd_s)(CPUHPPAState *env, float32 arg) 1065c39f954SPhilippe Mathieu-Daudé { 1075c39f954SPhilippe Mathieu-Daudé float32 ret = float32_round_to_int(arg, &env->fp_status); 1085c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1095c39f954SPhilippe Mathieu-Daudé return ret; 1105c39f954SPhilippe Mathieu-Daudé } 1115c39f954SPhilippe Mathieu-Daudé 1125c39f954SPhilippe Mathieu-Daudé float32 HELPER(fadd_s)(CPUHPPAState *env, float32 a, float32 b) 1135c39f954SPhilippe Mathieu-Daudé { 1145c39f954SPhilippe Mathieu-Daudé float32 ret = float32_add(a, b, &env->fp_status); 1155c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 1165c39f954SPhilippe Mathieu-Daudé return ret; 1175c39f954SPhilippe Mathieu-Daudé } 1185c39f954SPhilippe Mathieu-Daudé 1195c39f954SPhilippe Mathieu-Daudé float32 HELPER(fsub_s)(CPUHPPAState *env, float32 a, float32 b) 1205c39f954SPhilippe Mathieu-Daudé { 1215c39f954SPhilippe Mathieu-Daudé float32 ret = float32_sub(a, b, &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(fmpy_s)(CPUHPPAState *env, float32 a, float32 b) 1275c39f954SPhilippe Mathieu-Daudé { 1285c39f954SPhilippe Mathieu-Daudé float32 ret = float32_mul(a, b, &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(fdiv_s)(CPUHPPAState *env, float32 a, float32 b) 1345c39f954SPhilippe Mathieu-Daudé { 1355c39f954SPhilippe Mathieu-Daudé float32 ret = float32_div(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é float64 HELPER(fsqrt_d)(CPUHPPAState *env, float64 arg) 1415c39f954SPhilippe Mathieu-Daudé { 1425c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sqrt(arg, &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é float64 HELPER(frnd_d)(CPUHPPAState *env, float64 arg) 1485c39f954SPhilippe Mathieu-Daudé { 1495c39f954SPhilippe Mathieu-Daudé float64 ret = float64_round_to_int(arg, &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é float64 HELPER(fadd_d)(CPUHPPAState *env, float64 a, float64 b) 1555c39f954SPhilippe Mathieu-Daudé { 1565c39f954SPhilippe Mathieu-Daudé float64 ret = float64_add(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(fsub_d)(CPUHPPAState *env, float64 a, float64 b) 1625c39f954SPhilippe Mathieu-Daudé { 1635c39f954SPhilippe Mathieu-Daudé float64 ret = float64_sub(a, b, &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(fmpy_d)(CPUHPPAState *env, float64 a, float64 b) 1695c39f954SPhilippe Mathieu-Daudé { 1705c39f954SPhilippe Mathieu-Daudé float64 ret = float64_mul(a, b, &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(fdiv_d)(CPUHPPAState *env, float64 a, float64 b) 1765c39f954SPhilippe Mathieu-Daudé { 1775c39f954SPhilippe Mathieu-Daudé float64 ret = float64_div(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(fcnv_s_d)(CPUHPPAState *env, float32 arg) 1835c39f954SPhilippe Mathieu-Daudé { 1845c39f954SPhilippe Mathieu-Daudé float64 ret = float32_to_float64(arg, &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é float32 HELPER(fcnv_d_s)(CPUHPPAState *env, float64 arg) 1905c39f954SPhilippe Mathieu-Daudé { 1915c39f954SPhilippe Mathieu-Daudé float32 ret = float64_to_float32(arg, &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é float32 HELPER(fcnv_w_s)(CPUHPPAState *env, int32_t arg) 1975c39f954SPhilippe Mathieu-Daudé { 1985c39f954SPhilippe Mathieu-Daudé float32 ret = int32_to_float32(arg, &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é float32 HELPER(fcnv_dw_s)(CPUHPPAState *env, int64_t arg) 2045c39f954SPhilippe Mathieu-Daudé { 2055c39f954SPhilippe Mathieu-Daudé float32 ret = int64_to_float32(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é float64 HELPER(fcnv_w_d)(CPUHPPAState *env, int32_t arg) 2115c39f954SPhilippe Mathieu-Daudé { 2125c39f954SPhilippe Mathieu-Daudé float64 ret = int32_to_float64(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é float64 HELPER(fcnv_dw_d)(CPUHPPAState *env, int64_t arg) 2185c39f954SPhilippe Mathieu-Daudé { 2195c39f954SPhilippe Mathieu-Daudé float64 ret = int64_to_float64(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é int32_t HELPER(fcnv_s_w)(CPUHPPAState *env, float32 arg) 2255c39f954SPhilippe Mathieu-Daudé { 2265c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32(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é int32_t HELPER(fcnv_d_w)(CPUHPPAState *env, float64 arg) 2325c39f954SPhilippe Mathieu-Daudé { 2335c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32(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é int64_t HELPER(fcnv_s_dw)(CPUHPPAState *env, float32 arg) 2395c39f954SPhilippe Mathieu-Daudé { 2405c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64(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é int64_t HELPER(fcnv_d_dw)(CPUHPPAState *env, float64 arg) 2465c39f954SPhilippe Mathieu-Daudé { 2475c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64(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_t_s_w)(CPUHPPAState *env, float32 arg) 2535c39f954SPhilippe Mathieu-Daudé { 2545c39f954SPhilippe Mathieu-Daudé int32_t ret = float32_to_int32_round_to_zero(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é int32_t HELPER(fcnv_t_d_w)(CPUHPPAState *env, float64 arg) 2605c39f954SPhilippe Mathieu-Daudé { 2615c39f954SPhilippe Mathieu-Daudé int32_t ret = float64_to_int32_round_to_zero(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_t_s_dw)(CPUHPPAState *env, float32 arg) 2675c39f954SPhilippe Mathieu-Daudé { 2685c39f954SPhilippe Mathieu-Daudé int64_t ret = float32_to_int64_round_to_zero(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é int64_t HELPER(fcnv_t_d_dw)(CPUHPPAState *env, float64 arg) 2745c39f954SPhilippe Mathieu-Daudé { 2755c39f954SPhilippe Mathieu-Daudé int64_t ret = float64_to_int64_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é float32 HELPER(fcnv_uw_s)(CPUHPPAState *env, uint32_t arg) 2815c39f954SPhilippe Mathieu-Daudé { 2825c39f954SPhilippe Mathieu-Daudé float32 ret = uint32_to_float32(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é float32 HELPER(fcnv_udw_s)(CPUHPPAState *env, uint64_t arg) 2885c39f954SPhilippe Mathieu-Daudé { 2895c39f954SPhilippe Mathieu-Daudé float32 ret = uint64_to_float32(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é float64 HELPER(fcnv_uw_d)(CPUHPPAState *env, uint32_t arg) 2955c39f954SPhilippe Mathieu-Daudé { 2965c39f954SPhilippe Mathieu-Daudé float64 ret = uint32_to_float64(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é float64 HELPER(fcnv_udw_d)(CPUHPPAState *env, uint64_t arg) 3025c39f954SPhilippe Mathieu-Daudé { 3035c39f954SPhilippe Mathieu-Daudé float64 ret = uint64_to_float64(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é uint32_t HELPER(fcnv_s_uw)(CPUHPPAState *env, float32 arg) 3095c39f954SPhilippe Mathieu-Daudé { 3105c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32(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é uint32_t HELPER(fcnv_d_uw)(CPUHPPAState *env, float64 arg) 3165c39f954SPhilippe Mathieu-Daudé { 3175c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32(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é uint64_t HELPER(fcnv_s_udw)(CPUHPPAState *env, float32 arg) 3235c39f954SPhilippe Mathieu-Daudé { 3245c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64(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é uint64_t HELPER(fcnv_d_udw)(CPUHPPAState *env, float64 arg) 3305c39f954SPhilippe Mathieu-Daudé { 3315c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64(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_t_s_uw)(CPUHPPAState *env, float32 arg) 3375c39f954SPhilippe Mathieu-Daudé { 3385c39f954SPhilippe Mathieu-Daudé uint32_t ret = float32_to_uint32_round_to_zero(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é uint32_t HELPER(fcnv_t_d_uw)(CPUHPPAState *env, float64 arg) 3445c39f954SPhilippe Mathieu-Daudé { 3455c39f954SPhilippe Mathieu-Daudé uint32_t ret = float64_to_uint32_round_to_zero(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_t_s_udw)(CPUHPPAState *env, float32 arg) 3515c39f954SPhilippe Mathieu-Daudé { 3525c39f954SPhilippe Mathieu-Daudé uint64_t ret = float32_to_uint64_round_to_zero(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é uint64_t HELPER(fcnv_t_d_udw)(CPUHPPAState *env, float64 arg) 3585c39f954SPhilippe Mathieu-Daudé { 3595c39f954SPhilippe Mathieu-Daudé uint64_t ret = float64_to_uint64_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é static void update_fr0_cmp(CPUHPPAState *env, uint32_t y, 3655c39f954SPhilippe Mathieu-Daudé uint32_t c, FloatRelation r) 3665c39f954SPhilippe Mathieu-Daudé { 3675c39f954SPhilippe Mathieu-Daudé uint32_t shadow = env->fr0_shadow; 3685c39f954SPhilippe Mathieu-Daudé 3695c39f954SPhilippe Mathieu-Daudé switch (r) { 3705c39f954SPhilippe Mathieu-Daudé case float_relation_greater: 3715c39f954SPhilippe Mathieu-Daudé c = extract32(c, 4, 1); 3725c39f954SPhilippe Mathieu-Daudé break; 3735c39f954SPhilippe Mathieu-Daudé case float_relation_less: 3745c39f954SPhilippe Mathieu-Daudé c = extract32(c, 3, 1); 3755c39f954SPhilippe Mathieu-Daudé break; 3765c39f954SPhilippe Mathieu-Daudé case float_relation_equal: 3775c39f954SPhilippe Mathieu-Daudé c = extract32(c, 2, 1); 3785c39f954SPhilippe Mathieu-Daudé break; 3795c39f954SPhilippe Mathieu-Daudé case float_relation_unordered: 3805c39f954SPhilippe Mathieu-Daudé c = extract32(c, 1, 1); 3815c39f954SPhilippe Mathieu-Daudé break; 3825c39f954SPhilippe Mathieu-Daudé default: 3835c39f954SPhilippe Mathieu-Daudé g_assert_not_reached(); 3845c39f954SPhilippe Mathieu-Daudé } 3855c39f954SPhilippe Mathieu-Daudé 3865c39f954SPhilippe Mathieu-Daudé if (y) { 3875c39f954SPhilippe Mathieu-Daudé /* targeted comparison */ 3885c39f954SPhilippe Mathieu-Daudé /* set fpsr[ca[y - 1]] to current compare */ 389f33a22c1SRichard Henderson shadow = deposit32(shadow, R_FPSR_CA0_SHIFT - (y - 1), 1, c); 3905c39f954SPhilippe Mathieu-Daudé } else { 3915c39f954SPhilippe Mathieu-Daudé /* queued comparison */ 3925c39f954SPhilippe Mathieu-Daudé /* shift cq right by one place */ 393f33a22c1SRichard Henderson shadow = (shadow & ~R_FPSR_CQ_MASK) | ((shadow >> 1) & R_FPSR_CQ_MASK); 3945c39f954SPhilippe Mathieu-Daudé /* move fpsr[c] to fpsr[cq[0]] */ 395f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, CQ0, FIELD_EX32(shadow, FPSR, C)); 3965c39f954SPhilippe Mathieu-Daudé /* set fpsr[c] to current compare */ 397f33a22c1SRichard Henderson shadow = FIELD_DP32(shadow, FPSR, C, c); 3985c39f954SPhilippe Mathieu-Daudé } 3995c39f954SPhilippe Mathieu-Daudé 4005c39f954SPhilippe Mathieu-Daudé env->fr0_shadow = shadow; 4015c39f954SPhilippe Mathieu-Daudé env->fr[0] = (uint64_t)shadow << 32; 4025c39f954SPhilippe Mathieu-Daudé } 4035c39f954SPhilippe Mathieu-Daudé 4045c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_s)(CPUHPPAState *env, float32 a, float32 b, 4055c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4065c39f954SPhilippe Mathieu-Daudé { 4075c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4085c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4095c39f954SPhilippe Mathieu-Daudé r = float32_compare(a, b, &env->fp_status); 4105c39f954SPhilippe Mathieu-Daudé } else { 4115c39f954SPhilippe Mathieu-Daudé r = float32_compare_quiet(a, b, &env->fp_status); 4125c39f954SPhilippe Mathieu-Daudé } 4135c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4145c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4155c39f954SPhilippe Mathieu-Daudé } 4165c39f954SPhilippe Mathieu-Daudé 4175c39f954SPhilippe Mathieu-Daudé void HELPER(fcmp_d)(CPUHPPAState *env, float64 a, float64 b, 4185c39f954SPhilippe Mathieu-Daudé uint32_t y, uint32_t c) 4195c39f954SPhilippe Mathieu-Daudé { 4205c39f954SPhilippe Mathieu-Daudé FloatRelation r; 4215c39f954SPhilippe Mathieu-Daudé if (c & 1) { 4225c39f954SPhilippe Mathieu-Daudé r = float64_compare(a, b, &env->fp_status); 4235c39f954SPhilippe Mathieu-Daudé } else { 4245c39f954SPhilippe Mathieu-Daudé r = float64_compare_quiet(a, b, &env->fp_status); 4255c39f954SPhilippe Mathieu-Daudé } 4265c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4275c39f954SPhilippe Mathieu-Daudé update_fr0_cmp(env, y, c, r); 4285c39f954SPhilippe Mathieu-Daudé } 4295c39f954SPhilippe Mathieu-Daudé 4305c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpyfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4315c39f954SPhilippe Mathieu-Daudé { 4325c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, 0, &env->fp_status); 4335c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4345c39f954SPhilippe Mathieu-Daudé return ret; 4355c39f954SPhilippe Mathieu-Daudé } 4365c39f954SPhilippe Mathieu-Daudé 4375c39f954SPhilippe Mathieu-Daudé float32 HELPER(fmpynfadd_s)(CPUHPPAState *env, float32 a, float32 b, float32 c) 4385c39f954SPhilippe Mathieu-Daudé { 4395c39f954SPhilippe Mathieu-Daudé float32 ret = float32_muladd(a, b, c, float_muladd_negate_product, 4405c39f954SPhilippe Mathieu-Daudé &env->fp_status); 4415c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4425c39f954SPhilippe Mathieu-Daudé return ret; 4435c39f954SPhilippe Mathieu-Daudé } 4445c39f954SPhilippe Mathieu-Daudé 4455c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpyfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4465c39f954SPhilippe Mathieu-Daudé { 4475c39f954SPhilippe Mathieu-Daudé float64 ret = float64_muladd(a, b, c, 0, &env->fp_status); 4485c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4495c39f954SPhilippe Mathieu-Daudé return ret; 4505c39f954SPhilippe Mathieu-Daudé } 4515c39f954SPhilippe Mathieu-Daudé 4525c39f954SPhilippe Mathieu-Daudé float64 HELPER(fmpynfadd_d)(CPUHPPAState *env, float64 a, float64 b, float64 c) 4535c39f954SPhilippe Mathieu-Daudé { 4545c39f954SPhilippe Mathieu-Daudé float64 ret = float64_muladd(a, b, c, float_muladd_negate_product, 4555c39f954SPhilippe Mathieu-Daudé &env->fp_status); 4565c39f954SPhilippe Mathieu-Daudé update_fr0_op(env, GETPC()); 4575c39f954SPhilippe Mathieu-Daudé return ret; 4585c39f954SPhilippe Mathieu-Daudé } 459