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