fpu_emu.h revision 230193
191174Stmm/* 291174Stmm * Copyright (c) 1992, 1993 391174Stmm * The Regents of the University of California. All rights reserved. 491174Stmm * 591174Stmm * This software was developed by the Computer Systems Engineering group 691174Stmm * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and 791174Stmm * contributed to Berkeley. 891174Stmm * 991174Stmm * Redistribution and use in source and binary forms, with or without 1091174Stmm * modification, are permitted provided that the following conditions 1191174Stmm * are met: 1291174Stmm * 1. Redistributions of source code must retain the above copyright 1391174Stmm * notice, this list of conditions and the following disclaimer. 1491174Stmm * 2. Redistributions in binary form must reproduce the above copyright 1591174Stmm * notice, this list of conditions and the following disclaimer in the 1691174Stmm * documentation and/or other materials provided with the distribution. 1791174Stmm * 4. Neither the name of the University nor the names of its contributors 1891174Stmm * may be used to endorse or promote products derived from this software 1991174Stmm * without specific prior written permission. 2091174Stmm * 2191174Stmm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2291174Stmm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2391174Stmm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2491174Stmm * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2591174Stmm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2691174Stmm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2791174Stmm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2891174Stmm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2991174Stmm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3091174Stmm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3191174Stmm * SUCH DAMAGE. 3291174Stmm * 3392991Sobrien * @(#)fpu_emu.h 8.1 (Berkeley) 6/11/93 3492991Sobrien * $NetBSD: fpu_emu.h,v 1.4 2000/08/03 18:32:07 eeh Exp $ 3591174Stmm * $FreeBSD: head/lib/libc/sparc64/fpu/fpu_emu.h 230193 2012-01-16 04:09:45Z das $ 3691174Stmm */ 3791174Stmm 3891174Stmm/* 3991174Stmm * Floating point emulator (tailored for SPARC, but structurally 4091174Stmm * machine-independent). 4191174Stmm * 4291174Stmm * Floating point numbers are carried around internally in an `expanded' 4391174Stmm * or `unpacked' form consisting of: 4491174Stmm * - sign 4591174Stmm * - unbiased exponent 4691174Stmm * - mantissa (`1.' + 112-bit fraction + guard + round) 4791174Stmm * - sticky bit 4891174Stmm * Any implied `1' bit is inserted, giving a 113-bit mantissa that is 4991174Stmm * always nonzero. Additional low-order `guard' and `round' bits are 5091174Stmm * scrunched in, making the entire mantissa 115 bits long. This is divided 5191174Stmm * into four 32-bit words, with `spare' bits left over in the upper part 5291174Stmm * of the top word (the high bits of fp_mant[0]). An internal `exploded' 5391174Stmm * number is thus kept within the half-open interval [1.0,2.0) (but see 5491174Stmm * the `number classes' below). This holds even for denormalized numbers: 5591174Stmm * when we explode an external denorm, we normalize it, introducing low-order 5691174Stmm * zero bits, so that the rest of the code always sees normalized values. 5791174Stmm * 5891174Stmm * Note that a number of our algorithms use the `spare' bits at the top. 5991174Stmm * The most demanding algorithm---the one for sqrt---depends on two such 6091174Stmm * bits, so that it can represent values up to (but not including) 8.0, 6191174Stmm * and then it needs a carry on top of that, so that we need three `spares'. 6291174Stmm * 6391174Stmm * The sticky-word is 32 bits so that we can use `OR' operators to goosh 6491174Stmm * whole words from the mantissa into it. 6591174Stmm * 6691174Stmm * All operations are done in this internal extended precision. According 6791174Stmm * to Hennesey & Patterson, Appendix A, rounding can be repeated---that is, 6891174Stmm * it is OK to do a+b in extended precision and then round the result to 6991174Stmm * single precision---provided single, double, and extended precisions are 7091174Stmm * `far enough apart' (they always are), but we will try to avoid any such 7191174Stmm * extra work where possible. 7291174Stmm */ 7391174Stmm 7491174Stmm#ifndef _SPARC64_FPU_FPU_EMU_H_ 7591174Stmm#define _SPARC64_FPU_FPU_EMU_H_ 7691174Stmm 7791174Stmm#include "fpu_reg.h" 7891174Stmm 7991174Stmmstruct fpn { 8091174Stmm int fp_class; /* see below */ 8191174Stmm int fp_sign; /* 0 => positive, 1 => negative */ 8291174Stmm int fp_exp; /* exponent (unbiased) */ 8391174Stmm int fp_sticky; /* nonzero bits lost at right end */ 8491174Stmm u_int fp_mant[4]; /* 115-bit mantissa */ 8591174Stmm}; 8691174Stmm 8791174Stmm#define FP_NMANT 115 /* total bits in mantissa (incl g,r) */ 8891174Stmm#define FP_NG 2 /* number of low-order guard bits */ 8991174Stmm#define FP_LG ((FP_NMANT - 1) & 31) /* log2(1.0) for fp_mant[0] */ 9091174Stmm#define FP_LG2 ((FP_NMANT - 1) & 63) /* log2(1.0) for fp_mant[0] and fp_mant[1] */ 9191174Stmm#define FP_QUIETBIT (1 << (FP_LG - 1)) /* Quiet bit in NaNs (0.5) */ 9291174Stmm#define FP_1 (1 << FP_LG) /* 1.0 in fp_mant[0] */ 9391174Stmm#define FP_2 (1 << (FP_LG + 1)) /* 2.0 in fp_mant[0] */ 9491174Stmm 9591174Stmm/* 9691174Stmm * Number classes. Since zero, Inf, and NaN cannot be represented using 9791174Stmm * the above layout, we distinguish these from other numbers via a class. 9891174Stmm * In addition, to make computation easier and to follow Appendix N of 9991174Stmm * the SPARC Version 8 standard, we give each kind of NaN a separate class. 10091174Stmm */ 10191174Stmm#define FPC_SNAN -2 /* signalling NaN (sign irrelevant) */ 10291174Stmm#define FPC_QNAN -1 /* quiet NaN (sign irrelevant) */ 10391174Stmm#define FPC_ZERO 0 /* zero (sign matters) */ 10491174Stmm#define FPC_NUM 1 /* number (sign matters) */ 10591174Stmm#define FPC_INF 2 /* infinity (sign matters) */ 10691174Stmm 10791174Stmm#define ISNAN(fp) ((fp)->fp_class < 0) 10891174Stmm#define ISZERO(fp) ((fp)->fp_class == 0) 10991174Stmm#define ISINF(fp) ((fp)->fp_class == FPC_INF) 11091174Stmm 11191174Stmm/* 11291174Stmm * ORDER(x,y) `sorts' a pair of `fpn *'s so that the right operand (y) points 11391174Stmm * to the `more significant' operand for our purposes. Appendix N says that 11491174Stmm * the result of a computation involving two numbers are: 11591174Stmm * 11691174Stmm * If both are SNaN: operand 2, converted to Quiet 11791174Stmm * If only one is SNaN: the SNaN operand, converted to Quiet 11891174Stmm * If both are QNaN: operand 2 11991174Stmm * If only one is QNaN: the QNaN operand 12091174Stmm * 12191174Stmm * In addition, in operations with an Inf operand, the result is usually 12291174Stmm * Inf. The class numbers are carefully arranged so that if 12391174Stmm * (unsigned)class(op1) > (unsigned)class(op2) 12491174Stmm * then op1 is the one we want; otherwise op2 is the one we want. 12591174Stmm */ 12691174Stmm#define ORDER(x, y) { \ 12791174Stmm if ((u_int)(x)->fp_class > (u_int)(y)->fp_class) \ 12891174Stmm SWAP(x, y); \ 12991174Stmm} 13091174Stmm#define SWAP(x, y) { \ 13191174Stmm register struct fpn *swap; \ 13291174Stmm swap = (x), (x) = (y), (y) = swap; \ 13391174Stmm} 13491174Stmm 13591174Stmm/* 13691174Stmm * Floating point operand types. FTYPE_LNG is syntethic (it does not occur in 13791174Stmm * instructions). 13891174Stmm */ 13991174Stmm#define FTYPE_INT INSFP_i 14091174Stmm#define FTYPE_SNG INSFP_s 14191174Stmm#define FTYPE_DBL INSFP_d 14291174Stmm#define FTYPE_EXT INSFP_q 143205002Smarius#define FTYPE_LNG 4 14491174Stmm 14591174Stmm/* 14691174Stmm * Emulator state. 14791174Stmm */ 14891174Stmmstruct fpemu { 14992055Stmm u_long fe_fsr; /* fsr copy (modified during op) */ 15091174Stmm int fe_cx; /* exceptions */ 151163258Skmacy int pad; /* align access to following fields */ 15291174Stmm struct fpn fe_f1; /* operand 1 */ 15391174Stmm struct fpn fe_f2; /* operand 2, if required */ 15491174Stmm struct fpn fe_f3; /* available storage for result */ 15591174Stmm}; 15691174Stmm 15791174Stmm/* 15891174Stmm * Arithmetic functions. 15991174Stmm * Each of these may modify its inputs (f1,f2) and/or the temporary. 16091174Stmm * Each returns a pointer to the result and/or sets exceptions. 16191174Stmm */ 162230193Sdas#define __fpu_sub(fe) (ISNAN(&(fe)->fe_f2) ? 0 : ((fe)->fe_f2.fp_sign ^= 1), \ 163230193Sdas __fpu_add(fe)) 16491174Stmm 16591174Stmm#ifdef FPU_DEBUG 16691174Stmm#define FPE_INSN 0x1 16791174Stmm#define FPE_REG 0x2 16891174Stmmextern int __fpe_debug; 16991174Stmmvoid __fpu_dumpfpn(struct fpn *); 17091174Stmm#define DPRINTF(x, y) if (__fpe_debug & (x)) printf y 17191174Stmm#define DUMPFPN(x, f) if (__fpe_debug & (x)) __fpu_dumpfpn((f)) 17291174Stmm#else 17391174Stmm#define DPRINTF(x, y) 17491174Stmm#define DUMPFPN(x, f) 17591174Stmm#endif 17691174Stmm 17791174Stmm#endif /* !_SPARC64_FPU_FPU_EXTERN_H_ */ 178