| 1 | /* CGEN fpu support |
| 2 | Copyright (C) 1999 Cygnus Solutions. |
| 3 | Copyright (C) 2010 Doug Evans. */ |
| 4 | |
| 5 | #ifndef CGEN_FPU_H |
| 6 | #define CGEN_FPU_H |
| 7 | |
| 8 | /* Floating point support is a little more complicated. |
| 9 | We want to support using either host fp insns or an accurate fp library. |
| 10 | We also want to support easily added variants (e.g. modified ieee). |
| 11 | This is done by vectoring all calls through a table. */ |
| 12 | |
| 13 | typedef USI SF; |
| 14 | typedef UDI DF; |
| 15 | typedef struct { SI parts[3]; } XF; |
| 16 | typedef struct { SI parts[4]; } TF; |
| 17 | |
| 18 | #ifndef TARGET_EXT_FP_WORDS |
| 19 | #define TARGET_EXT_FP_WORDS 4 |
| 20 | #endif |
| 21 | |
| 22 | /* Supported floating point conversion kinds (rounding modes). |
| 23 | FIXME: The IEEE rounding modes need to be implemented. */ |
| 24 | |
| 25 | typedef enum { |
| 26 | FPCONV_DEFAULT = 0, |
| 27 | FPCONV_TIES_TO_EVEN = 1, |
| 28 | FPCONV_TIES_TO_AWAY = 2, |
| 29 | FPCONV_TOWARD_ZERO = 3, |
| 30 | FPCONV_TOWARD_POSITIVE = 4, |
| 31 | FPCONV_TOWARD_NEGATIVE = 5 |
| 32 | } CGEN_FPCONV_KIND; |
| 33 | |
| 34 | /* forward decl */ |
| 35 | typedef struct cgen_fp_ops CGEN_FP_OPS; |
| 36 | |
| 37 | /* Instance of an fpu. */ |
| 38 | |
| 39 | typedef struct { |
| 40 | /* Usually a pointer back to the SIM_CPU struct. */ |
| 41 | void* owner; |
| 42 | /* Pointer to ops struct, rather than copy of it, to avoid bloating |
| 43 | SIM_CPU struct. */ |
| 44 | CGEN_FP_OPS* ops; |
| 45 | } CGEN_FPU; |
| 46 | |
| 47 | /* result of cmp */ |
| 48 | |
| 49 | typedef enum { |
| 50 | /* ??? May wish to distinguish qnan/snan here. */ |
| 51 | FP_CMP_EQ, FP_CMP_LT, FP_CMP_GT, FP_CMP_NAN |
| 52 | } CGEN_FP_CMP; |
| 53 | |
| 54 | /* error handler */ |
| 55 | |
| 56 | typedef void (CGEN_FPU_ERROR_FN) (CGEN_FPU*, int); |
| 57 | |
| 58 | /* fpu operation table */ |
| 59 | |
| 60 | struct cgen_fp_ops { |
| 61 | |
| 62 | /* error (e.g. signalling nan) handler, supplied by owner */ |
| 63 | |
| 64 | CGEN_FPU_ERROR_FN *error; |
| 65 | |
| 66 | /* basic SF ops */ |
| 67 | |
| 68 | SF (*addsf) (CGEN_FPU*, SF, SF); |
| 69 | SF (*subsf) (CGEN_FPU*, SF, SF); |
| 70 | SF (*mulsf) (CGEN_FPU*, SF, SF); |
| 71 | SF (*divsf) (CGEN_FPU*, SF, SF); |
| 72 | SF (*negsf) (CGEN_FPU*, SF); |
| 73 | SF (*abssf) (CGEN_FPU*, SF); |
| 74 | SF (*sqrtsf) (CGEN_FPU*, SF); |
| 75 | SF (*invsf) (CGEN_FPU*, SF); |
| 76 | SF (*cossf) (CGEN_FPU*, SF); |
| 77 | SF (*sinsf) (CGEN_FPU*, SF); |
| 78 | SF (*minsf) (CGEN_FPU*, SF, SF); |
| 79 | SF (*maxsf) (CGEN_FPU*, SF, SF); |
| 80 | |
| 81 | /* ??? to be revisited */ |
| 82 | CGEN_FP_CMP (*cmpsf) (CGEN_FPU*, SF, SF); |
| 83 | int (*eqsf) (CGEN_FPU*, SF, SF); |
| 84 | int (*nesf) (CGEN_FPU*, SF, SF); |
| 85 | int (*ltsf) (CGEN_FPU*, SF, SF); |
| 86 | int (*lesf) (CGEN_FPU*, SF, SF); |
| 87 | int (*gtsf) (CGEN_FPU*, SF, SF); |
| 88 | int (*gesf) (CGEN_FPU*, SF, SF); |
| 89 | |
| 90 | /* basic DF ops */ |
| 91 | |
| 92 | DF (*adddf) (CGEN_FPU*, DF, DF); |
| 93 | DF (*subdf) (CGEN_FPU*, DF, DF); |
| 94 | DF (*muldf) (CGEN_FPU*, DF, DF); |
| 95 | DF (*divdf) (CGEN_FPU*, DF, DF); |
| 96 | DF (*negdf) (CGEN_FPU*, DF); |
| 97 | DF (*absdf) (CGEN_FPU*, DF); |
| 98 | DF (*sqrtdf) (CGEN_FPU*, DF); |
| 99 | DF (*invdf) (CGEN_FPU*, DF); |
| 100 | DF (*cosdf) (CGEN_FPU*, DF); |
| 101 | DF (*sindf) (CGEN_FPU*, DF); |
| 102 | DF (*mindf) (CGEN_FPU*, DF, DF); |
| 103 | DF (*maxdf) (CGEN_FPU*, DF, DF); |
| 104 | |
| 105 | /* ??? to be revisited */ |
| 106 | CGEN_FP_CMP (*cmpdf) (CGEN_FPU*, DF, DF); |
| 107 | int (*eqdf) (CGEN_FPU*, DF, DF); |
| 108 | int (*nedf) (CGEN_FPU*, DF, DF); |
| 109 | int (*ltdf) (CGEN_FPU*, DF, DF); |
| 110 | int (*ledf) (CGEN_FPU*, DF, DF); |
| 111 | int (*gtdf) (CGEN_FPU*, DF, DF); |
| 112 | int (*gedf) (CGEN_FPU*, DF, DF); |
| 113 | |
| 114 | /* SF/DF conversion ops */ |
| 115 | |
| 116 | DF (*fextsfdf) (CGEN_FPU*, int, SF); |
| 117 | SF (*ftruncdfsf) (CGEN_FPU*, int, DF); |
| 118 | |
| 119 | SF (*floatsisf) (CGEN_FPU*, int, SI); |
| 120 | SF (*floatdisf) (CGEN_FPU*, int, DI); |
| 121 | SF (*ufloatsisf) (CGEN_FPU*, int, USI); |
| 122 | SF (*ufloatdisf) (CGEN_FPU*, int, UDI); |
| 123 | |
| 124 | SI (*fixsfsi) (CGEN_FPU*, int, SF); |
| 125 | DI (*fixsfdi) (CGEN_FPU*, int, SF); |
| 126 | USI (*ufixsfsi) (CGEN_FPU*, int, SF); |
| 127 | UDI (*ufixsfdi) (CGEN_FPU*, int, SF); |
| 128 | |
| 129 | DF (*floatsidf) (CGEN_FPU*, int, SI); |
| 130 | DF (*floatdidf) (CGEN_FPU*, int, DI); |
| 131 | DF (*ufloatsidf) (CGEN_FPU*, int, USI); |
| 132 | DF (*ufloatdidf) (CGEN_FPU*, int, UDI); |
| 133 | |
| 134 | SI (*fixdfsi) (CGEN_FPU*, int, DF); |
| 135 | DI (*fixdfdi) (CGEN_FPU*, int, DF); |
| 136 | USI (*ufixdfsi) (CGEN_FPU*, int, DF); |
| 137 | UDI (*ufixdfdi) (CGEN_FPU*, int, DF); |
| 138 | |
| 139 | /* XF mode support (kept separate 'cus not always present) */ |
| 140 | |
| 141 | XF (*addxf) (CGEN_FPU*, XF, XF); |
| 142 | XF (*subxf) (CGEN_FPU*, XF, XF); |
| 143 | XF (*mulxf) (CGEN_FPU*, XF, XF); |
| 144 | XF (*divxf) (CGEN_FPU*, XF, XF); |
| 145 | XF (*negxf) (CGEN_FPU*, XF); |
| 146 | XF (*absxf) (CGEN_FPU*, XF); |
| 147 | XF (*sqrtxf) (CGEN_FPU*, XF); |
| 148 | XF (*invxf) (CGEN_FPU*, XF); |
| 149 | XF (*cosxf) (CGEN_FPU*, XF); |
| 150 | XF (*sinxf) (CGEN_FPU*, XF); |
| 151 | XF (*minxf) (CGEN_FPU*, XF, XF); |
| 152 | XF (*maxxf) (CGEN_FPU*, XF, XF); |
| 153 | |
| 154 | CGEN_FP_CMP (*cmpxf) (CGEN_FPU*, XF, XF); |
| 155 | int (*eqxf) (CGEN_FPU*, XF, XF); |
| 156 | int (*nexf) (CGEN_FPU*, XF, XF); |
| 157 | int (*ltxf) (CGEN_FPU*, XF, XF); |
| 158 | int (*lexf) (CGEN_FPU*, XF, XF); |
| 159 | int (*gtxf) (CGEN_FPU*, XF, XF); |
| 160 | int (*gexf) (CGEN_FPU*, XF, XF); |
| 161 | |
| 162 | XF (*extsfxf) (CGEN_FPU*, int, SF); |
| 163 | XF (*extdfxf) (CGEN_FPU*, int, DF); |
| 164 | SF (*truncxfsf) (CGEN_FPU*, int, XF); |
| 165 | DF (*truncxfdf) (CGEN_FPU*, int, XF); |
| 166 | |
| 167 | XF (*floatsixf) (CGEN_FPU*, int, SI); |
| 168 | XF (*floatdixf) (CGEN_FPU*, int, DI); |
| 169 | XF (*ufloatsixf) (CGEN_FPU*, int, USI); |
| 170 | XF (*ufloatdixf) (CGEN_FPU*, int, UDI); |
| 171 | |
| 172 | SI (*fixxfsi) (CGEN_FPU*, int, XF); |
| 173 | DI (*fixxfdi) (CGEN_FPU*, int, XF); |
| 174 | USI (*ufixxfsi) (CGEN_FPU*, int, XF); |
| 175 | UDI (*ufixxfdi) (CGEN_FPU*, int, XF); |
| 176 | |
| 177 | /* TF mode support (kept separate 'cus not always present) */ |
| 178 | |
| 179 | TF (*addtf) (CGEN_FPU*, TF, TF); |
| 180 | TF (*subtf) (CGEN_FPU*, TF, TF); |
| 181 | TF (*multf) (CGEN_FPU*, TF, TF); |
| 182 | TF (*divtf) (CGEN_FPU*, TF, TF); |
| 183 | TF (*negtf) (CGEN_FPU*, TF); |
| 184 | TF (*abstf) (CGEN_FPU*, TF); |
| 185 | TF (*sqrttf) (CGEN_FPU*, TF); |
| 186 | TF (*invtf) (CGEN_FPU*, TF); |
| 187 | TF (*costf) (CGEN_FPU*, TF); |
| 188 | TF (*sintf) (CGEN_FPU*, TF); |
| 189 | TF (*mintf) (CGEN_FPU*, TF, TF); |
| 190 | TF (*maxtf) (CGEN_FPU*, TF, TF); |
| 191 | |
| 192 | CGEN_FP_CMP (*cmptf) (CGEN_FPU*, TF, TF); |
| 193 | int (*eqtf) (CGEN_FPU*, TF, TF); |
| 194 | int (*netf) (CGEN_FPU*, TF, TF); |
| 195 | int (*lttf) (CGEN_FPU*, TF, TF); |
| 196 | int (*letf) (CGEN_FPU*, TF, TF); |
| 197 | int (*gttf) (CGEN_FPU*, TF, TF); |
| 198 | int (*getf) (CGEN_FPU*, TF, TF); |
| 199 | |
| 200 | TF (*extsftf) (CGEN_FPU*, int, SF); |
| 201 | TF (*extdftf) (CGEN_FPU*, int, DF); |
| 202 | SF (*trunctfsf) (CGEN_FPU*, int, TF); |
| 203 | DF (*trunctfdf) (CGEN_FPU*, int, TF); |
| 204 | |
| 205 | TF (*floatsitf) (CGEN_FPU*, int, SI); |
| 206 | TF (*floatditf) (CGEN_FPU*, int, DI); |
| 207 | TF (*ufloatsitf) (CGEN_FPU*, int, USI); |
| 208 | TF (*ufloatditf) (CGEN_FPU*, int, UDI); |
| 209 | |
| 210 | SI (*fixtfsi) (CGEN_FPU*, int, TF); |
| 211 | DI (*fixtfdi) (CGEN_FPU*, int, TF); |
| 212 | USI (*ufixtfsi) (CGEN_FPU*, int, TF); |
| 213 | UDI (*ufixtfdi) (CGEN_FPU*, int, TF); |
| 214 | |
| 215 | }; |
| 216 | |
| 217 | extern void cgen_init_accurate_fpu (SIM_CPU*, CGEN_FPU*, CGEN_FPU_ERROR_FN*); |
| 218 | |
| 219 | BI cgen_sf_snan_p (CGEN_FPU*, SF); |
| 220 | BI cgen_df_snan_p (CGEN_FPU*, DF); |
| 221 | |
| 222 | /* no-op fp error handler */ |
| 223 | extern CGEN_FPU_ERROR_FN cgen_fpu_ignore_errors; |
| 224 | |
| 225 | #endif /* CGEN_FPU_H */ |