1 /* RISC-V softfloat definitions 2 Copyright (C) 2017-2021 Free Software Foundation, Inc. 3 4 This file is part of the GNU C Library. 5 6 The GNU C Library is free software; you can redistribute it and/or 7 modify it under the terms of the GNU Lesser General Public 8 License as published by the Free Software Foundation; either 9 version 2.1 of the License, or (at your option) any later version. 10 11 The GNU C Library is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 Lesser General Public License for more details. 15 16 You should have received a copy of the GNU Lesser General Public 17 License along with the GNU C Library. If not, see 18 <https://www.gnu.org/licenses/>. */ 19 20 #include <fenv.h> 21 #include <fpu_control.h> 22 23 #if __riscv_xlen == 32 24 25 # define _FP_W_TYPE_SIZE 32 26 # define _FP_W_TYPE unsigned long 27 # define _FP_WS_TYPE signed long 28 # define _FP_I_TYPE long 29 30 # define _FP_MUL_MEAT_S(R, X, Y) \ 31 _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_S, R, X, Y, umul_ppmm) 32 # define _FP_MUL_MEAT_D(R, X, Y) \ 33 _FP_MUL_MEAT_2_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) 34 # define _FP_MUL_MEAT_Q(R, X, Y) \ 35 _FP_MUL_MEAT_4_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) 36 37 # define _FP_MUL_MEAT_DW_S(R, X, Y) \ 38 _FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_S, R, X, Y, umul_ppmm) 39 # define _FP_MUL_MEAT_DW_D(R, X, Y) \ 40 _FP_MUL_MEAT_DW_2_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) 41 # define _FP_MUL_MEAT_DW_Q(R, X, Y) \ 42 _FP_MUL_MEAT_DW_4_wide (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) 43 44 # define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (S, R, X, Y) 45 # define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_2_udiv (D, R, X, Y) 46 # define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_4_udiv (Q, R, X, Y) 47 48 # define _FP_NANFRAC_S _FP_QNANBIT_S 49 # define _FP_NANFRAC_D _FP_QNANBIT_D, 0 50 # define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0 51 52 #else 53 54 # define _FP_W_TYPE_SIZE 64 55 # define _FP_W_TYPE unsigned long long 56 # define _FP_WS_TYPE signed long long 57 # define _FP_I_TYPE long long 58 59 # define _FP_MUL_MEAT_S(R, X, Y) \ 60 _FP_MUL_MEAT_1_imm (_FP_WFRACBITS_S, R, X, Y) 61 # define _FP_MUL_MEAT_D(R, X, Y) \ 62 _FP_MUL_MEAT_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) 63 # define _FP_MUL_MEAT_Q(R, X, Y) \ 64 _FP_MUL_MEAT_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) 65 66 # define _FP_MUL_MEAT_DW_S(R, X, Y) \ 67 _FP_MUL_MEAT_DW_1_imm (_FP_WFRACBITS_S, R, X, Y) 68 # define _FP_MUL_MEAT_DW_D(R, X, Y) \ 69 _FP_MUL_MEAT_DW_1_wide (_FP_WFRACBITS_D, R, X, Y, umul_ppmm) 70 # define _FP_MUL_MEAT_DW_Q(R, X, Y) \ 71 _FP_MUL_MEAT_DW_2_wide_3mul (_FP_WFRACBITS_Q, R, X, Y, umul_ppmm) 72 73 # define _FP_DIV_MEAT_S(R, X, Y) _FP_DIV_MEAT_1_imm (S, R, X, Y, _FP_DIV_HELP_imm) 74 # define _FP_DIV_MEAT_D(R, X, Y) _FP_DIV_MEAT_1_udiv_norm (D, R, X, Y) 75 # define _FP_DIV_MEAT_Q(R, X, Y) _FP_DIV_MEAT_2_udiv (Q, R, X, Y) 76 77 # define _FP_NANFRAC_S _FP_QNANBIT_S 78 # define _FP_NANFRAC_D _FP_QNANBIT_D 79 # define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0 80 81 #endif 82 83 #define _FP_NANSIGN_S 0 84 #define _FP_NANSIGN_D 0 85 #define _FP_NANSIGN_Q 0 86 87 #define _FP_KEEPNANFRACP 0 88 #define _FP_QNANNEGATEDP 0 89 90 #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ 91 do { \ 92 R##_s = _FP_NANSIGN_##fs; \ 93 _FP_FRAC_SET_##wc (R, _FP_NANFRAC_##fs); \ 94 R##_c = FP_CLS_NAN; \ 95 } while (0) 96 97 #define _FP_DECL_EX int _frm __attribute__ ((unused)); 98 #define FP_ROUNDMODE _frm 99 100 #define FP_RND_NEAREST FE_TONEAREST 101 #define FP_RND_ZERO FE_TOWARDZERO 102 #define FP_RND_PINF FE_UPWARD 103 #define FP_RND_MINF FE_DOWNWARD 104 105 #define FP_EX_INVALID FE_INVALID 106 #define FP_EX_OVERFLOW FE_OVERFLOW 107 #define FP_EX_UNDERFLOW FE_UNDERFLOW 108 #define FP_EX_DIVZERO FE_DIVBYZERO 109 #define FP_EX_INEXACT FE_INEXACT 110 111 #define _FP_TININESS_AFTER_ROUNDING 1 112 113 #ifdef __riscv_flen 114 # define FP_INIT_ROUNDMODE \ 115 do { \ 116 __asm__ volatile ("frrm %0" : "=r" (_frm)); \ 117 } while (0) 118 119 # define FP_HANDLE_EXCEPTIONS \ 120 do { \ 121 if (__builtin_expect (_fex, 0)) \ 122 __asm__ volatile ("csrs fflags, %0" : : "rK" (_fex)); \ 123 } while (0) 124 #else 125 # define FP_INIT_ROUNDMODE _frm = FP_RND_NEAREST 126 #endif 127