1 1.26 isaki /* $NetBSD: fpu_emulate.h,v 1.26 2016/12/06 05:58:19 isaki Exp $ */ 2 1.1 briggs 3 1.1 briggs /* 4 1.1 briggs * Copyright (c) 1995 Gordon Ross 5 1.1 briggs * Copyright (c) 1995 Ken Nakata 6 1.1 briggs * All rights reserved. 7 1.1 briggs * 8 1.1 briggs * Redistribution and use in source and binary forms, with or without 9 1.1 briggs * modification, are permitted provided that the following conditions 10 1.1 briggs * are met: 11 1.1 briggs * 1. Redistributions of source code must retain the above copyright 12 1.1 briggs * notice, this list of conditions and the following disclaimer. 13 1.1 briggs * 2. Redistributions in binary form must reproduce the above copyright 14 1.1 briggs * notice, this list of conditions and the following disclaimer in the 15 1.1 briggs * documentation and/or other materials provided with the distribution. 16 1.1 briggs * 3. The name of the author may not be used to endorse or promote products 17 1.1 briggs * derived from this software without specific prior written permission. 18 1.1 briggs * 4. All advertising materials mentioning features or use of this software 19 1.1 briggs * must display the following acknowledgement: 20 1.1 briggs * This product includes software developed by Gordon Ross 21 1.1 briggs * 22 1.1 briggs * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 1.1 briggs * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 1.1 briggs * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 1.1 briggs * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 1.1 briggs * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 1.1 briggs * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 1.1 briggs * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 1.1 briggs * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 1.1 briggs * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 1.1 briggs * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 1.1 briggs */ 33 1.1 briggs 34 1.1 briggs #ifndef _FPU_EMULATE_H_ 35 1.1 briggs #define _FPU_EMULATE_H_ 36 1.1 briggs 37 1.1 briggs #include <sys/types.h> 38 1.10 cl #include <sys/signal.h> 39 1.11 he #include <sys/time.h> 40 1.10 cl #include <sys/signalvar.h> 41 1.10 cl #include <sys/siginfo.h> 42 1.14 martin #include <m68k/fpreg.h> 43 1.1 briggs 44 1.1 briggs /* 45 1.1 briggs * Floating point emulator (tailored for SPARC/modified for m68k, but 46 1.1 briggs * structurally machine-independent). 47 1.1 briggs * 48 1.1 briggs * Floating point numbers are carried around internally in an `expanded' 49 1.1 briggs * or `unpacked' form consisting of: 50 1.1 briggs * - sign 51 1.1 briggs * - unbiased exponent 52 1.7 is * - mantissa (`1.' + 80-bit fraction + guard + round) 53 1.1 briggs * - sticky bit 54 1.7 is * Any implied `1' bit is inserted, giving a 81-bit mantissa that is 55 1.1 briggs * always nonzero. Additional low-order `guard' and `round' bits are 56 1.7 is * scrunched in, making the entire mantissa 83 bits long. This is divided 57 1.6 minoura * into three 32-bit words, with `spare' bits left over in the upper part 58 1.1 briggs * of the top word (the high bits of fp_mant[0]). An internal `exploded' 59 1.1 briggs * number is thus kept within the half-open interval [1.0,2.0) (but see 60 1.1 briggs * the `number classes' below). This holds even for denormalized numbers: 61 1.1 briggs * when we explode an external denorm, we normalize it, introducing low-order 62 1.1 briggs * zero bits, so that the rest of the code always sees normalized values. 63 1.1 briggs * 64 1.1 briggs * Note that a number of our algorithms use the `spare' bits at the top. 65 1.1 briggs * The most demanding algorithm---the one for sqrt---depends on two such 66 1.1 briggs * bits, so that it can represent values up to (but not including) 8.0, 67 1.1 briggs * and then it needs a carry on top of that, so that we need three `spares'. 68 1.1 briggs * 69 1.1 briggs * The sticky-word is 32 bits so that we can use `OR' operators to goosh 70 1.1 briggs * whole words from the mantissa into it. 71 1.1 briggs * 72 1.1 briggs * All operations are done in this internal extended precision. According 73 1.1 briggs * to Hennesey & Patterson, Appendix A, rounding can be repeated---that is, 74 1.1 briggs * it is OK to do a+b in extended precision and then round the result to 75 1.1 briggs * single precision---provided single, double, and extended precisions are 76 1.1 briggs * `far enough apart' (they always are), but we will try to avoid any such 77 1.1 briggs * extra work where possible. 78 1.1 briggs */ 79 1.1 briggs struct fpn { 80 1.1 briggs int fp_class; /* see below */ 81 1.1 briggs int fp_sign; /* 0 => positive, 1 => negative */ 82 1.1 briggs int fp_exp; /* exponent (unbiased) */ 83 1.1 briggs int fp_sticky; /* nonzero bits lost at right end */ 84 1.22 isaki uint32_t fp_mant[3]; /* 83-bit mantissa */ 85 1.1 briggs }; 86 1.1 briggs 87 1.7 is #define FP_NMANT 83 /* total bits in mantissa (incl g,r) */ 88 1.1 briggs #define FP_NG 2 /* number of low-order guard bits */ 89 1.1 briggs #define FP_LG ((FP_NMANT - 1) & 31) /* log2(1.0) for fp_mant[0] */ 90 1.1 briggs #define FP_QUIETBIT (1 << (FP_LG - 1)) /* Quiet bit in NaNs (0.5) */ 91 1.1 briggs #define FP_1 (1 << FP_LG) /* 1.0 in fp_mant[0] */ 92 1.1 briggs #define FP_2 (1 << (FP_LG + 1)) /* 2.0 in fp_mant[0] */ 93 1.1 briggs 94 1.19 tsutsui static inline void CPYFPN(struct fpn *, const struct fpn *); 95 1.17 tsutsui 96 1.17 tsutsui static inline void 97 1.19 tsutsui CPYFPN(struct fpn *dst, const struct fpn *src) 98 1.17 tsutsui { 99 1.17 tsutsui 100 1.17 tsutsui if (dst != src) { 101 1.17 tsutsui *dst = *src; 102 1.17 tsutsui } 103 1.1 briggs } 104 1.1 briggs 105 1.1 briggs /* 106 1.1 briggs * Number classes. Since zero, Inf, and NaN cannot be represented using 107 1.1 briggs * the above layout, we distinguish these from other numbers via a class. 108 1.1 briggs */ 109 1.1 briggs #define FPC_SNAN -2 /* signalling NaN (sign irrelevant) */ 110 1.1 briggs #define FPC_QNAN -1 /* quiet NaN (sign irrelevant) */ 111 1.1 briggs #define FPC_ZERO 0 /* zero (sign matters) */ 112 1.1 briggs #define FPC_NUM 1 /* number (sign matters) */ 113 1.1 briggs #define FPC_INF 2 /* infinity (sign matters) */ 114 1.1 briggs 115 1.1 briggs #define ISNAN(fp) ((fp)->fp_class < 0) 116 1.1 briggs #define ISZERO(fp) ((fp)->fp_class == 0) 117 1.1 briggs #define ISINF(fp) ((fp)->fp_class == FPC_INF) 118 1.1 briggs 119 1.1 briggs /* 120 1.1 briggs * ORDER(x,y) `sorts' a pair of `fpn *'s so that the right operand (y) points 121 1.1 briggs * to the `more significant' operand for our purposes. Appendix N says that 122 1.1 briggs * the result of a computation involving two numbers are: 123 1.1 briggs * 124 1.1 briggs * If both are SNaN: operand 2, converted to Quiet 125 1.1 briggs * If only one is SNaN: the SNaN operand, converted to Quiet 126 1.1 briggs * If both are QNaN: operand 2 127 1.1 briggs * If only one is QNaN: the QNaN operand 128 1.1 briggs * 129 1.1 briggs * In addition, in operations with an Inf operand, the result is usually 130 1.1 briggs * Inf. The class numbers are carefully arranged so that if 131 1.1 briggs * (unsigned)class(op1) > (unsigned)class(op2) 132 1.1 briggs * then op1 is the one we want; otherwise op2 is the one we want. 133 1.1 briggs */ 134 1.1 briggs #define ORDER(x, y) { \ 135 1.22 isaki if ((uint32_t)(x)->fp_class > (uint32_t)(y)->fp_class) \ 136 1.1 briggs SWAP(x, y); \ 137 1.1 briggs } 138 1.1 briggs #define SWAP(x, y) { \ 139 1.20 isaki struct fpn *swap; \ 140 1.1 briggs swap = (x), (x) = (y), (y) = swap; \ 141 1.1 briggs } 142 1.1 briggs 143 1.1 briggs /* 144 1.1 briggs * Emulator state. 145 1.1 briggs */ 146 1.1 briggs struct fpemu { 147 1.16 isaki struct frame *fe_frame; /* integer regs, etc */ 148 1.16 isaki struct fpframe *fe_fpframe; /* FP registers, etc */ 149 1.22 isaki uint32_t fe_fpsr; /* fpsr copy (modified during op) */ 150 1.22 isaki uint32_t fe_fpcr; /* fpcr copy */ 151 1.16 isaki struct fpn fe_f1; /* operand 1 */ 152 1.16 isaki struct fpn fe_f2; /* operand 2, if required */ 153 1.16 isaki struct fpn fe_f3; /* available storage for result */ 154 1.1 briggs }; 155 1.1 briggs 156 1.1 briggs /***************************************************************************** 157 1.1 briggs * End of definitions derived from Sparc FPE 158 1.1 briggs *****************************************************************************/ 159 1.1 briggs 160 1.1 briggs /* 161 1.1 briggs * Internal info about a decoded effective address. 162 1.1 briggs */ 163 1.1 briggs struct insn_ea { 164 1.16 isaki int ea_regnum; 165 1.16 isaki int ea_ext[3]; /* extension words if any */ 166 1.16 isaki int ea_flags; /* flags == 0 means mode 2: An@ */ 167 1.1 briggs #define EA_DIRECT 0x001 /* mode [01]: Dn or An */ 168 1.1 briggs #define EA_PREDECR 0x002 /* mode 4: An@- */ 169 1.1 briggs #define EA_POSTINCR 0x004 /* mode 3: An@+ */ 170 1.1 briggs #define EA_OFFSET 0x008 /* mode 5 or (7,2): APC@(d16) */ 171 1.1 briggs #define EA_INDEXED 0x010 /* mode 6 or (7,3): APC@(Xn:*:*,d8) etc */ 172 1.1 briggs #define EA_ABS 0x020 /* mode (7,[01]): abs */ 173 1.1 briggs #define EA_PC_REL 0x040 /* mode (7,[23]): PC@(d16) etc */ 174 1.1 briggs #define EA_IMMED 0x080 /* mode (7,4): #immed */ 175 1.1 briggs #define EA_MEM_INDIR 0x100 /* mode 6 or (7,3): APC@(Xn:*:*,*)@(*) etc */ 176 1.1 briggs #define EA_BASE_SUPPRSS 0x200 /* mode 6 or (7,3): base register suppressed */ 177 1.5 briggs #define EA_FRAME_EA 0x400 /* MC68LC040 only: precalculated EA from 178 1.5 briggs format 4 stack frame */ 179 1.16 isaki int ea_moffs; /* offset used for fmoveMulti */ 180 1.1 briggs }; 181 1.1 briggs 182 1.1 briggs #define ea_offset ea_ext[0] /* mode 5: offset word */ 183 1.1 briggs #define ea_absaddr ea_ext[0] /* mode (7,[01]): absolute address */ 184 1.1 briggs #define ea_immed ea_ext /* mode (7,4): immediate value */ 185 1.1 briggs #define ea_basedisp ea_ext[0] /* mode 6: base displacement */ 186 1.1 briggs #define ea_outerdisp ea_ext[1] /* mode 6: outer displacement */ 187 1.1 briggs #define ea_idxreg ea_ext[2] /* mode 6: index register number */ 188 1.5 briggs #define ea_fea ea_ext[0] /* MC68LC040 only: frame EA */ 189 1.1 briggs 190 1.1 briggs struct instruction { 191 1.22 isaki uint32_t is_pc; /* insn's address */ 192 1.22 isaki uint32_t is_nextpc; /* next PC */ 193 1.16 isaki int is_advance; /* length of instruction */ 194 1.16 isaki int is_datasize; /* size of memory operand */ 195 1.16 isaki int is_opcode; /* opcode word */ 196 1.16 isaki int is_word1; /* second word */ 197 1.16 isaki struct insn_ea is_ea; /* decoded effective address mode */ 198 1.1 briggs }; 199 1.1 briggs 200 1.1 briggs /* 201 1.1 briggs * FP data types 202 1.1 briggs */ 203 1.1 briggs #define FTYPE_LNG 0 /* Long Word Integer */ 204 1.1 briggs #define FTYPE_SNG 1 /* Single Prec */ 205 1.1 briggs #define FTYPE_EXT 2 /* Extended Prec */ 206 1.1 briggs #define FTYPE_BCD 3 /* Packed BCD */ 207 1.1 briggs #define FTYPE_WRD 4 /* Word Integer */ 208 1.1 briggs #define FTYPE_DBL 5 /* Double Prec */ 209 1.1 briggs #define FTYPE_BYT 6 /* Byte Integer */ 210 1.1 briggs 211 1.1 briggs /* 212 1.1 briggs * Other functions. 213 1.1 briggs */ 214 1.1 briggs 215 1.1 briggs /* Build a new Quiet NaN (sign=0, frac=all 1's). */ 216 1.19 tsutsui struct fpn *fpu_newnan(struct fpemu *); 217 1.1 briggs 218 1.1 briggs /* 219 1.1 briggs * Shift a number right some number of bits, taking care of round/sticky. 220 1.1 briggs * Note that the result is probably not a well-formed number (it will lack 221 1.1 briggs * the normal 1-bit mant[0]&FP_1). 222 1.1 briggs */ 223 1.19 tsutsui int fpu_shr(struct fpn *, int); 224 1.1 briggs /* 225 1.1 briggs * Round a number according to the round mode in FPCR 226 1.1 briggs */ 227 1.20 isaki int fpu_round(struct fpemu *, struct fpn *); 228 1.1 briggs 229 1.1 briggs /* type conversion */ 230 1.22 isaki void fpu_explode(struct fpemu *, struct fpn *, int t, const uint32_t *); 231 1.22 isaki void fpu_implode(struct fpemu *, struct fpn *, int t, uint32_t *); 232 1.1 briggs 233 1.1 briggs /* 234 1.1 briggs * non-static emulation functions 235 1.1 briggs */ 236 1.1 briggs /* type 0 */ 237 1.19 tsutsui int fpu_emul_fmovecr(struct fpemu *, struct instruction *); 238 1.19 tsutsui int fpu_emul_fstore(struct fpemu *, struct instruction *); 239 1.19 tsutsui int fpu_emul_fscale(struct fpemu *, struct instruction *); 240 1.1 briggs 241 1.1 briggs /* 242 1.1 briggs * include function declarations of those which are called by fpu_emul_arith() 243 1.1 briggs */ 244 1.1 briggs #include "fpu_arith_proto.h" 245 1.1 briggs 246 1.19 tsutsui int fpu_emulate(struct frame *, struct fpframe *, ksiginfo_t *); 247 1.18 tsutsui struct fpn *fpu_cmp(struct fpemu *); 248 1.18 tsutsui 249 1.24 isaki /* fpu_cordic.c */ 250 1.24 isaki extern const struct fpn fpu_cordic_inv_gain1; 251 1.24 isaki void fpu_cordit1(struct fpemu *, 252 1.24 isaki struct fpn *, struct fpn *, struct fpn *, const struct fpn *); 253 1.4 briggs 254 1.1 briggs /* 255 1.1 briggs * "helper" functions 256 1.1 briggs */ 257 1.1 briggs /* return values from constant rom */ 258 1.22 isaki struct fpn *fpu_const(struct fpn *, uint32_t); 259 1.23 isaki #define FPU_CONST_PI (0x00) /* pi */ 260 1.24 isaki #define FPU_CONST_0 (0x0f) /* 0.0 */ 261 1.23 isaki #define FPU_CONST_LN_2 (0x30) /* ln(2) */ 262 1.23 isaki #define FPU_CONST_LN_10 (0x31) /* ln(10) */ 263 1.23 isaki #define FPU_CONST_1 (0x32) /* 1.0 */ 264 1.23 isaki 265 1.1 briggs /* update exceptions and FPSR */ 266 1.19 tsutsui int fpu_upd_excp(struct fpemu *); 267 1.22 isaki uint32_t fpu_upd_fpsr(struct fpemu *, struct fpn *); 268 1.1 briggs 269 1.1 briggs /* address mode decoder, and load/store */ 270 1.19 tsutsui int fpu_decode_ea(struct frame *, struct instruction *, 271 1.19 tsutsui struct insn_ea *, int); 272 1.19 tsutsui int fpu_load_ea(struct frame *, struct instruction *, 273 1.19 tsutsui struct insn_ea *, char *); 274 1.19 tsutsui int fpu_store_ea(struct frame *, struct instruction *, 275 1.19 tsutsui struct insn_ea *, char *); 276 1.4 briggs 277 1.4 briggs /* fpu_subr.c */ 278 1.20 isaki void fpu_norm(struct fpn *); 279 1.1 briggs 280 1.5 briggs #if !defined(FPE_DEBUG) 281 1.5 briggs # define FPE_DEBUG 0 282 1.5 briggs #endif 283 1.1 briggs 284 1.1 briggs #endif /* _FPU_EMULATE_H_ */ 285