1*f798f1e2SMichael Clark /* 2*f798f1e2SMichael Clark * RISC-V FPU Emulation Helpers for QEMU. 3*f798f1e2SMichael Clark * 4*f798f1e2SMichael Clark * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 5*f798f1e2SMichael Clark * 6*f798f1e2SMichael Clark * This program is free software; you can redistribute it and/or modify it 7*f798f1e2SMichael Clark * under the terms and conditions of the GNU General Public License, 8*f798f1e2SMichael Clark * version 2 or later, as published by the Free Software Foundation. 9*f798f1e2SMichael Clark * 10*f798f1e2SMichael Clark * This program is distributed in the hope it will be useful, but WITHOUT 11*f798f1e2SMichael Clark * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12*f798f1e2SMichael Clark * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13*f798f1e2SMichael Clark * more details. 14*f798f1e2SMichael Clark * 15*f798f1e2SMichael Clark * You should have received a copy of the GNU General Public License along with 16*f798f1e2SMichael Clark * this program. If not, see <http://www.gnu.org/licenses/>. 17*f798f1e2SMichael Clark */ 18*f798f1e2SMichael Clark 19*f798f1e2SMichael Clark #include "qemu/osdep.h" 20*f798f1e2SMichael Clark #include <stdlib.h> 21*f798f1e2SMichael Clark #include "cpu.h" 22*f798f1e2SMichael Clark #include "qemu/host-utils.h" 23*f798f1e2SMichael Clark #include "exec/exec-all.h" 24*f798f1e2SMichael Clark #include "exec/helper-proto.h" 25*f798f1e2SMichael Clark 26*f798f1e2SMichael Clark target_ulong cpu_riscv_get_fflags(CPURISCVState *env) 27*f798f1e2SMichael Clark { 28*f798f1e2SMichael Clark int soft = get_float_exception_flags(&env->fp_status); 29*f798f1e2SMichael Clark target_ulong hard = 0; 30*f798f1e2SMichael Clark 31*f798f1e2SMichael Clark hard |= (soft & float_flag_inexact) ? FPEXC_NX : 0; 32*f798f1e2SMichael Clark hard |= (soft & float_flag_underflow) ? FPEXC_UF : 0; 33*f798f1e2SMichael Clark hard |= (soft & float_flag_overflow) ? FPEXC_OF : 0; 34*f798f1e2SMichael Clark hard |= (soft & float_flag_divbyzero) ? FPEXC_DZ : 0; 35*f798f1e2SMichael Clark hard |= (soft & float_flag_invalid) ? FPEXC_NV : 0; 36*f798f1e2SMichael Clark 37*f798f1e2SMichael Clark return hard; 38*f798f1e2SMichael Clark } 39*f798f1e2SMichael Clark 40*f798f1e2SMichael Clark void cpu_riscv_set_fflags(CPURISCVState *env, target_ulong hard) 41*f798f1e2SMichael Clark { 42*f798f1e2SMichael Clark int soft = 0; 43*f798f1e2SMichael Clark 44*f798f1e2SMichael Clark soft |= (hard & FPEXC_NX) ? float_flag_inexact : 0; 45*f798f1e2SMichael Clark soft |= (hard & FPEXC_UF) ? float_flag_underflow : 0; 46*f798f1e2SMichael Clark soft |= (hard & FPEXC_OF) ? float_flag_overflow : 0; 47*f798f1e2SMichael Clark soft |= (hard & FPEXC_DZ) ? float_flag_divbyzero : 0; 48*f798f1e2SMichael Clark soft |= (hard & FPEXC_NV) ? float_flag_invalid : 0; 49*f798f1e2SMichael Clark 50*f798f1e2SMichael Clark set_float_exception_flags(soft, &env->fp_status); 51*f798f1e2SMichael Clark } 52*f798f1e2SMichael Clark 53*f798f1e2SMichael Clark void helper_set_rounding_mode(CPURISCVState *env, uint32_t rm) 54*f798f1e2SMichael Clark { 55*f798f1e2SMichael Clark int softrm; 56*f798f1e2SMichael Clark 57*f798f1e2SMichael Clark if (rm == 7) { 58*f798f1e2SMichael Clark rm = env->frm; 59*f798f1e2SMichael Clark } 60*f798f1e2SMichael Clark switch (rm) { 61*f798f1e2SMichael Clark case 0: 62*f798f1e2SMichael Clark softrm = float_round_nearest_even; 63*f798f1e2SMichael Clark break; 64*f798f1e2SMichael Clark case 1: 65*f798f1e2SMichael Clark softrm = float_round_to_zero; 66*f798f1e2SMichael Clark break; 67*f798f1e2SMichael Clark case 2: 68*f798f1e2SMichael Clark softrm = float_round_down; 69*f798f1e2SMichael Clark break; 70*f798f1e2SMichael Clark case 3: 71*f798f1e2SMichael Clark softrm = float_round_up; 72*f798f1e2SMichael Clark break; 73*f798f1e2SMichael Clark case 4: 74*f798f1e2SMichael Clark softrm = float_round_ties_away; 75*f798f1e2SMichael Clark break; 76*f798f1e2SMichael Clark default: 77*f798f1e2SMichael Clark do_raise_exception_err(env, RISCV_EXCP_ILLEGAL_INST, GETPC()); 78*f798f1e2SMichael Clark } 79*f798f1e2SMichael Clark 80*f798f1e2SMichael Clark set_float_rounding_mode(softrm, &env->fp_status); 81*f798f1e2SMichael Clark } 82*f798f1e2SMichael Clark 83*f798f1e2SMichael Clark uint64_t helper_fmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 84*f798f1e2SMichael Clark uint64_t frs3) 85*f798f1e2SMichael Clark { 86*f798f1e2SMichael Clark return float32_muladd(frs1, frs2, frs3, 0, &env->fp_status); 87*f798f1e2SMichael Clark } 88*f798f1e2SMichael Clark 89*f798f1e2SMichael Clark uint64_t helper_fmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 90*f798f1e2SMichael Clark uint64_t frs3) 91*f798f1e2SMichael Clark { 92*f798f1e2SMichael Clark return float64_muladd(frs1, frs2, frs3, 0, &env->fp_status); 93*f798f1e2SMichael Clark } 94*f798f1e2SMichael Clark 95*f798f1e2SMichael Clark uint64_t helper_fmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 96*f798f1e2SMichael Clark uint64_t frs3) 97*f798f1e2SMichael Clark { 98*f798f1e2SMichael Clark return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c, 99*f798f1e2SMichael Clark &env->fp_status); 100*f798f1e2SMichael Clark } 101*f798f1e2SMichael Clark 102*f798f1e2SMichael Clark uint64_t helper_fmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 103*f798f1e2SMichael Clark uint64_t frs3) 104*f798f1e2SMichael Clark { 105*f798f1e2SMichael Clark return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c, 106*f798f1e2SMichael Clark &env->fp_status); 107*f798f1e2SMichael Clark } 108*f798f1e2SMichael Clark 109*f798f1e2SMichael Clark uint64_t helper_fnmsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 110*f798f1e2SMichael Clark uint64_t frs3) 111*f798f1e2SMichael Clark { 112*f798f1e2SMichael Clark return float32_muladd(frs1, frs2, frs3, float_muladd_negate_product, 113*f798f1e2SMichael Clark &env->fp_status); 114*f798f1e2SMichael Clark } 115*f798f1e2SMichael Clark 116*f798f1e2SMichael Clark uint64_t helper_fnmsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 117*f798f1e2SMichael Clark uint64_t frs3) 118*f798f1e2SMichael Clark { 119*f798f1e2SMichael Clark return float64_muladd(frs1, frs2, frs3, float_muladd_negate_product, 120*f798f1e2SMichael Clark &env->fp_status); 121*f798f1e2SMichael Clark } 122*f798f1e2SMichael Clark 123*f798f1e2SMichael Clark uint64_t helper_fnmadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 124*f798f1e2SMichael Clark uint64_t frs3) 125*f798f1e2SMichael Clark { 126*f798f1e2SMichael Clark return float32_muladd(frs1, frs2, frs3, float_muladd_negate_c | 127*f798f1e2SMichael Clark float_muladd_negate_product, &env->fp_status); 128*f798f1e2SMichael Clark } 129*f798f1e2SMichael Clark 130*f798f1e2SMichael Clark uint64_t helper_fnmadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2, 131*f798f1e2SMichael Clark uint64_t frs3) 132*f798f1e2SMichael Clark { 133*f798f1e2SMichael Clark return float64_muladd(frs1, frs2, frs3, float_muladd_negate_c | 134*f798f1e2SMichael Clark float_muladd_negate_product, &env->fp_status); 135*f798f1e2SMichael Clark } 136*f798f1e2SMichael Clark 137*f798f1e2SMichael Clark uint64_t helper_fadd_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 138*f798f1e2SMichael Clark { 139*f798f1e2SMichael Clark return float32_add(frs1, frs2, &env->fp_status); 140*f798f1e2SMichael Clark } 141*f798f1e2SMichael Clark 142*f798f1e2SMichael Clark uint64_t helper_fsub_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 143*f798f1e2SMichael Clark { 144*f798f1e2SMichael Clark return float32_sub(frs1, frs2, &env->fp_status); 145*f798f1e2SMichael Clark } 146*f798f1e2SMichael Clark 147*f798f1e2SMichael Clark uint64_t helper_fmul_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 148*f798f1e2SMichael Clark { 149*f798f1e2SMichael Clark return float32_mul(frs1, frs2, &env->fp_status); 150*f798f1e2SMichael Clark } 151*f798f1e2SMichael Clark 152*f798f1e2SMichael Clark uint64_t helper_fdiv_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 153*f798f1e2SMichael Clark { 154*f798f1e2SMichael Clark return float32_div(frs1, frs2, &env->fp_status); 155*f798f1e2SMichael Clark } 156*f798f1e2SMichael Clark 157*f798f1e2SMichael Clark uint64_t helper_fmin_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 158*f798f1e2SMichael Clark { 159*f798f1e2SMichael Clark return float32_minnum(frs1, frs2, &env->fp_status); 160*f798f1e2SMichael Clark } 161*f798f1e2SMichael Clark 162*f798f1e2SMichael Clark uint64_t helper_fmax_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 163*f798f1e2SMichael Clark { 164*f798f1e2SMichael Clark return float32_maxnum(frs1, frs2, &env->fp_status); 165*f798f1e2SMichael Clark } 166*f798f1e2SMichael Clark 167*f798f1e2SMichael Clark uint64_t helper_fsqrt_s(CPURISCVState *env, uint64_t frs1) 168*f798f1e2SMichael Clark { 169*f798f1e2SMichael Clark return float32_sqrt(frs1, &env->fp_status); 170*f798f1e2SMichael Clark } 171*f798f1e2SMichael Clark 172*f798f1e2SMichael Clark target_ulong helper_fle_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 173*f798f1e2SMichael Clark { 174*f798f1e2SMichael Clark return float32_le(frs1, frs2, &env->fp_status); 175*f798f1e2SMichael Clark } 176*f798f1e2SMichael Clark 177*f798f1e2SMichael Clark target_ulong helper_flt_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 178*f798f1e2SMichael Clark { 179*f798f1e2SMichael Clark return float32_lt(frs1, frs2, &env->fp_status); 180*f798f1e2SMichael Clark } 181*f798f1e2SMichael Clark 182*f798f1e2SMichael Clark target_ulong helper_feq_s(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 183*f798f1e2SMichael Clark { 184*f798f1e2SMichael Clark return float32_eq_quiet(frs1, frs2, &env->fp_status); 185*f798f1e2SMichael Clark } 186*f798f1e2SMichael Clark 187*f798f1e2SMichael Clark target_ulong helper_fcvt_w_s(CPURISCVState *env, uint64_t frs1) 188*f798f1e2SMichael Clark { 189*f798f1e2SMichael Clark return float32_to_int32(frs1, &env->fp_status); 190*f798f1e2SMichael Clark } 191*f798f1e2SMichael Clark 192*f798f1e2SMichael Clark target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t frs1) 193*f798f1e2SMichael Clark { 194*f798f1e2SMichael Clark return (int32_t)float32_to_uint32(frs1, &env->fp_status); 195*f798f1e2SMichael Clark } 196*f798f1e2SMichael Clark 197*f798f1e2SMichael Clark #if defined(TARGET_RISCV64) 198*f798f1e2SMichael Clark uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t frs1) 199*f798f1e2SMichael Clark { 200*f798f1e2SMichael Clark return float32_to_int64(frs1, &env->fp_status); 201*f798f1e2SMichael Clark } 202*f798f1e2SMichael Clark 203*f798f1e2SMichael Clark uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t frs1) 204*f798f1e2SMichael Clark { 205*f798f1e2SMichael Clark return float32_to_uint64(frs1, &env->fp_status); 206*f798f1e2SMichael Clark } 207*f798f1e2SMichael Clark #endif 208*f798f1e2SMichael Clark 209*f798f1e2SMichael Clark uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1) 210*f798f1e2SMichael Clark { 211*f798f1e2SMichael Clark return int32_to_float32((int32_t)rs1, &env->fp_status); 212*f798f1e2SMichael Clark } 213*f798f1e2SMichael Clark 214*f798f1e2SMichael Clark uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1) 215*f798f1e2SMichael Clark { 216*f798f1e2SMichael Clark return uint32_to_float32((uint32_t)rs1, &env->fp_status); 217*f798f1e2SMichael Clark } 218*f798f1e2SMichael Clark 219*f798f1e2SMichael Clark #if defined(TARGET_RISCV64) 220*f798f1e2SMichael Clark uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1) 221*f798f1e2SMichael Clark { 222*f798f1e2SMichael Clark return int64_to_float32(rs1, &env->fp_status); 223*f798f1e2SMichael Clark } 224*f798f1e2SMichael Clark 225*f798f1e2SMichael Clark uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1) 226*f798f1e2SMichael Clark { 227*f798f1e2SMichael Clark return uint64_to_float32(rs1, &env->fp_status); 228*f798f1e2SMichael Clark } 229*f798f1e2SMichael Clark #endif 230*f798f1e2SMichael Clark 231*f798f1e2SMichael Clark target_ulong helper_fclass_s(uint64_t frs1) 232*f798f1e2SMichael Clark { 233*f798f1e2SMichael Clark float32 f = frs1; 234*f798f1e2SMichael Clark bool sign = float32_is_neg(f); 235*f798f1e2SMichael Clark 236*f798f1e2SMichael Clark if (float32_is_infinity(f)) { 237*f798f1e2SMichael Clark return sign ? 1 << 0 : 1 << 7; 238*f798f1e2SMichael Clark } else if (float32_is_zero(f)) { 239*f798f1e2SMichael Clark return sign ? 1 << 3 : 1 << 4; 240*f798f1e2SMichael Clark } else if (float32_is_zero_or_denormal(f)) { 241*f798f1e2SMichael Clark return sign ? 1 << 2 : 1 << 5; 242*f798f1e2SMichael Clark } else if (float32_is_any_nan(f)) { 243*f798f1e2SMichael Clark float_status s = { }; /* for snan_bit_is_one */ 244*f798f1e2SMichael Clark return float32_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; 245*f798f1e2SMichael Clark } else { 246*f798f1e2SMichael Clark return sign ? 1 << 1 : 1 << 6; 247*f798f1e2SMichael Clark } 248*f798f1e2SMichael Clark } 249*f798f1e2SMichael Clark 250*f798f1e2SMichael Clark uint64_t helper_fadd_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 251*f798f1e2SMichael Clark { 252*f798f1e2SMichael Clark return float64_add(frs1, frs2, &env->fp_status); 253*f798f1e2SMichael Clark } 254*f798f1e2SMichael Clark 255*f798f1e2SMichael Clark uint64_t helper_fsub_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 256*f798f1e2SMichael Clark { 257*f798f1e2SMichael Clark return float64_sub(frs1, frs2, &env->fp_status); 258*f798f1e2SMichael Clark } 259*f798f1e2SMichael Clark 260*f798f1e2SMichael Clark uint64_t helper_fmul_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 261*f798f1e2SMichael Clark { 262*f798f1e2SMichael Clark return float64_mul(frs1, frs2, &env->fp_status); 263*f798f1e2SMichael Clark } 264*f798f1e2SMichael Clark 265*f798f1e2SMichael Clark uint64_t helper_fdiv_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 266*f798f1e2SMichael Clark { 267*f798f1e2SMichael Clark return float64_div(frs1, frs2, &env->fp_status); 268*f798f1e2SMichael Clark } 269*f798f1e2SMichael Clark 270*f798f1e2SMichael Clark uint64_t helper_fmin_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 271*f798f1e2SMichael Clark { 272*f798f1e2SMichael Clark return float64_minnum(frs1, frs2, &env->fp_status); 273*f798f1e2SMichael Clark } 274*f798f1e2SMichael Clark 275*f798f1e2SMichael Clark uint64_t helper_fmax_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 276*f798f1e2SMichael Clark { 277*f798f1e2SMichael Clark return float64_maxnum(frs1, frs2, &env->fp_status); 278*f798f1e2SMichael Clark } 279*f798f1e2SMichael Clark 280*f798f1e2SMichael Clark uint64_t helper_fcvt_s_d(CPURISCVState *env, uint64_t rs1) 281*f798f1e2SMichael Clark { 282*f798f1e2SMichael Clark rs1 = float64_to_float32(rs1, &env->fp_status); 283*f798f1e2SMichael Clark return float32_maybe_silence_nan(rs1, &env->fp_status); 284*f798f1e2SMichael Clark } 285*f798f1e2SMichael Clark 286*f798f1e2SMichael Clark uint64_t helper_fcvt_d_s(CPURISCVState *env, uint64_t rs1) 287*f798f1e2SMichael Clark { 288*f798f1e2SMichael Clark rs1 = float32_to_float64(rs1, &env->fp_status); 289*f798f1e2SMichael Clark return float64_maybe_silence_nan(rs1, &env->fp_status); 290*f798f1e2SMichael Clark } 291*f798f1e2SMichael Clark 292*f798f1e2SMichael Clark uint64_t helper_fsqrt_d(CPURISCVState *env, uint64_t frs1) 293*f798f1e2SMichael Clark { 294*f798f1e2SMichael Clark return float64_sqrt(frs1, &env->fp_status); 295*f798f1e2SMichael Clark } 296*f798f1e2SMichael Clark 297*f798f1e2SMichael Clark target_ulong helper_fle_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 298*f798f1e2SMichael Clark { 299*f798f1e2SMichael Clark return float64_le(frs1, frs2, &env->fp_status); 300*f798f1e2SMichael Clark } 301*f798f1e2SMichael Clark 302*f798f1e2SMichael Clark target_ulong helper_flt_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 303*f798f1e2SMichael Clark { 304*f798f1e2SMichael Clark return float64_lt(frs1, frs2, &env->fp_status); 305*f798f1e2SMichael Clark } 306*f798f1e2SMichael Clark 307*f798f1e2SMichael Clark target_ulong helper_feq_d(CPURISCVState *env, uint64_t frs1, uint64_t frs2) 308*f798f1e2SMichael Clark { 309*f798f1e2SMichael Clark return float64_eq_quiet(frs1, frs2, &env->fp_status); 310*f798f1e2SMichael Clark } 311*f798f1e2SMichael Clark 312*f798f1e2SMichael Clark target_ulong helper_fcvt_w_d(CPURISCVState *env, uint64_t frs1) 313*f798f1e2SMichael Clark { 314*f798f1e2SMichael Clark return float64_to_int32(frs1, &env->fp_status); 315*f798f1e2SMichael Clark } 316*f798f1e2SMichael Clark 317*f798f1e2SMichael Clark target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1) 318*f798f1e2SMichael Clark { 319*f798f1e2SMichael Clark return (int32_t)float64_to_uint32(frs1, &env->fp_status); 320*f798f1e2SMichael Clark } 321*f798f1e2SMichael Clark 322*f798f1e2SMichael Clark #if defined(TARGET_RISCV64) 323*f798f1e2SMichael Clark uint64_t helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1) 324*f798f1e2SMichael Clark { 325*f798f1e2SMichael Clark return float64_to_int64(frs1, &env->fp_status); 326*f798f1e2SMichael Clark } 327*f798f1e2SMichael Clark 328*f798f1e2SMichael Clark uint64_t helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1) 329*f798f1e2SMichael Clark { 330*f798f1e2SMichael Clark return float64_to_uint64(frs1, &env->fp_status); 331*f798f1e2SMichael Clark } 332*f798f1e2SMichael Clark #endif 333*f798f1e2SMichael Clark 334*f798f1e2SMichael Clark uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1) 335*f798f1e2SMichael Clark { 336*f798f1e2SMichael Clark return int32_to_float64((int32_t)rs1, &env->fp_status); 337*f798f1e2SMichael Clark } 338*f798f1e2SMichael Clark 339*f798f1e2SMichael Clark uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1) 340*f798f1e2SMichael Clark { 341*f798f1e2SMichael Clark return uint32_to_float64((uint32_t)rs1, &env->fp_status); 342*f798f1e2SMichael Clark } 343*f798f1e2SMichael Clark 344*f798f1e2SMichael Clark #if defined(TARGET_RISCV64) 345*f798f1e2SMichael Clark uint64_t helper_fcvt_d_l(CPURISCVState *env, uint64_t rs1) 346*f798f1e2SMichael Clark { 347*f798f1e2SMichael Clark return int64_to_float64(rs1, &env->fp_status); 348*f798f1e2SMichael Clark } 349*f798f1e2SMichael Clark 350*f798f1e2SMichael Clark uint64_t helper_fcvt_d_lu(CPURISCVState *env, uint64_t rs1) 351*f798f1e2SMichael Clark { 352*f798f1e2SMichael Clark return uint64_to_float64(rs1, &env->fp_status); 353*f798f1e2SMichael Clark } 354*f798f1e2SMichael Clark #endif 355*f798f1e2SMichael Clark 356*f798f1e2SMichael Clark target_ulong helper_fclass_d(uint64_t frs1) 357*f798f1e2SMichael Clark { 358*f798f1e2SMichael Clark float64 f = frs1; 359*f798f1e2SMichael Clark bool sign = float64_is_neg(f); 360*f798f1e2SMichael Clark 361*f798f1e2SMichael Clark if (float64_is_infinity(f)) { 362*f798f1e2SMichael Clark return sign ? 1 << 0 : 1 << 7; 363*f798f1e2SMichael Clark } else if (float64_is_zero(f)) { 364*f798f1e2SMichael Clark return sign ? 1 << 3 : 1 << 4; 365*f798f1e2SMichael Clark } else if (float64_is_zero_or_denormal(f)) { 366*f798f1e2SMichael Clark return sign ? 1 << 2 : 1 << 5; 367*f798f1e2SMichael Clark } else if (float64_is_any_nan(f)) { 368*f798f1e2SMichael Clark float_status s = { }; /* for snan_bit_is_one */ 369*f798f1e2SMichael Clark return float64_is_quiet_nan(f, &s) ? 1 << 9 : 1 << 8; 370*f798f1e2SMichael Clark } else { 371*f798f1e2SMichael Clark return sign ? 1 << 1 : 1 << 6; 372*f798f1e2SMichael Clark } 373*f798f1e2SMichael Clark } 374