home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / LINUX / MATH_EMU.ZIP / MATH_EMU / FPU_EMUL.H < prev    next >
Encoding:
C/C++ Source or Header  |  1979-12-31  |  12.9 KB  |  333 lines

  1. #define __P(name)  name  
  2. #define quad_t int /* ?????????????????? */
  3.  
  4. inline extern void fpu_copy(char*, char*,int);
  5. extern void copyin(char*, char*, int);
  6. extern void copyout(char*, char*, int);
  7. inline extern int fusword(unsigned int);
  8.  
  9. /*        $NetBSD$  */
  10.  
  11. /*
  12.  * Copyright (c) 1995 Gordon Ross
  13.  * Copyright (c) 1995 Ken Nakata
  14.  * All rights reserved.
  15.  *
  16.  * Redistribution and use in source and binary forms, with or without
  17.  * modification, are permitted provided that the following conditions
  18.  * are met:
  19.  * 1. Redistributions of source code must retain the above copyright
  20.  *    notice, this list of conditions and the following disclaimer.
  21.  * 2. Redistributions in binary form must reproduce the above copyright
  22.  *    notice, this list of conditions and the following disclaimer in the
  23.  *    documentation and/or other materials provided with the distribution.
  24.  * 3. The name of the author may not be used to endorse or promote products
  25.  *    derived from this software without specific prior written permission.
  26.  * 4. All advertising materials mentioning features or use of this software
  27.  *    must display the following acknowledgement:
  28.  *      This product includes software developed by Gordon Ross
  29.  *
  30.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  31.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  33.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  34.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  35.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  36.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  37.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  39.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  40.  */
  41.  
  42. #ifndef _FPU_EMULATE_H_
  43. #define _FPU_EMULATE_H_ 
  44.  
  45. #ifndef _TURBO_C
  46. #include "types.h"
  47. #endif
  48.  
  49. /*
  50.  * Floating point emulator (tailored for SPARC/modified for m68k, but
  51.  * structurally machine-independent).
  52.  *
  53.  * Floating point numbers are carried around internally in an `expanded'
  54.  * or `unpacked' form consisting of:
  55.  *        - sign
  56.  *        - unbiased exponent
  57.  *        - mantissa (`1.' + 112-bit fraction + guard + round)
  58.  *        - sticky bit
  59.  * Any implied `1' bit is inserted, giving a 113-bit mantissa that is
  60.  * always nonzero.  Additional low-order `guard' and `round' bits are
  61.  * scrunched in, making the entire mantissa 115 bits long.  This is divided
  62.  * into four 32-bit words, with `spare' bits left over in the upper part
  63.  * of the top word (the high bits of fp_mant[0]).  An internal `exploded'
  64.  * number is thus kept within the half-open interval [1.0,2.0) (but see
  65.  * the `number classes' below).  This holds even for denormalized numbers:
  66.  * when we explode an external denorm, we normalize it, introducing low-order
  67.  * zero bits, so that the rest of the code always sees normalized values.
  68.  *
  69.  * Note that a number of our algorithms use the `spare' bits at the top.
  70.  * The most demanding algorithm---the one for sqrt---depends on two such
  71.  * bits, so that it can represent values up to (but not including) 8.0,
  72.  * and then it needs a carry on top of that, so that we need three `spares'.
  73.  *
  74.  * The sticky-word is 32 bits so that we can use `OR' operators to goosh
  75.  * whole words from the mantissa into it.
  76.  *
  77.  * All operations are done in this internal extended precision.  According
  78.  * to Hennesey & Patterson, Appendix A, rounding can be repeated---that is,
  79.  * it is OK to do a+b in extended precision and then round the result to
  80.  * single precision---provided single, double, and extended precisions are
  81.  * `far enough apart' (they always are), but we will try to avoid any such
  82.  * extra work where possible.
  83.  */
  84. struct fpn {
  85.           int       fp_class;           /* see below */
  86.           int       fp_sign;            /* 0 => positive, 1 => negative */
  87.           int       fp_exp;                       /* exponent (unbiased) */
  88.           int       fp_sticky;                    /* nonzero bits lost at right end */
  89.           u_int     fp_mant[4];                   /* 115-bit mantissa */
  90. };
  91.  
  92. #define   FP_NMANT  115                 /* total bits in mantissa (incl g,r) */
  93. #define   FP_NG               2                   /* number of low-order guard bits */
  94. #define   FP_LG               ((FP_NMANT - 1) & 31)         /* log2(1.0) for fp_mant[0] */
  95. #define   FP_QUIETBIT         (1 << (FP_LG - 1))  /* Quiet bit in NaNs (0.5) */
  96. #define   FP_1                (1 << FP_LG)                  /* 1.0 in fp_mant[0] */
  97. #define   FP_2                (1 << (FP_LG + 1))  /* 2.0 in fp_mant[0] */
  98.  
  99. #define CPYFPN(dst, src) if ((dst) != (src)) {(dst)->fp_class = (src)->fp_class; \
  100.     (dst)->fp_sign = (src)->fp_sign; (dst)->fp_exp = (src)->fp_exp; \
  101.     (dst)->fp_sticky = (src)->fp_sticky; (dst)->fp_mant[0] = (src)->fp_mant[0];\
  102.  (dst)->fp_mant[1] = (src)->fp_mant[1]; (dst)->fp_mant[2] = (src)->fp_mant[2]; (dst)->fp_mant[3] = (src)->fp_mant[3];}
  103.  
  104. /*
  105.  * Number classes.  Since zero, Inf, and NaN cannot be represented using
  106.  * the above layout, we distinguish these from other numbers via a class.
  107.  */
  108. #define   FPC_SNAN  -2                  /* signalling NaN (sign irrelevant) */
  109. #define   FPC_QNAN  -1                  /* quiet NaN (sign irrelevant) */
  110. #define   FPC_ZERO  0                   /* zero (sign matters) */
  111. #define   FPC_NUM             1                   /* number (sign matters) */
  112. #define   FPC_INF             2                   /* infinity (sign matters) */
  113.  
  114. #define   ISNAN(fp) ((fp)->fp_class < 0)
  115. #define   ISZERO(fp)          ((fp)->fp_class == 0)
  116. #define   ISINF(fp) ((fp)->fp_class == FPC_INF)
  117.  
  118. /*
  119.  * ORDER(x,y) `sorts' a pair of `fpn *'s so that the right operand (y) points
  120.  * to the `more significant' operand for our purposes.  Appendix N says that
  121.  * the result of a computation involving two numbers are:
  122.  *
  123.  *        If both are SNaN: operand 2, converted to Quiet
  124.  *        If only one is SNaN: the SNaN operand, converted to Quiet
  125.  *        If both are QNaN: operand 2
  126.  *        If only one is QNaN: the QNaN operand
  127.  *
  128.  * In addition, in operations with an Inf operand, the result is usually
  129.  * Inf.  The class numbers are carefully arranged so that if
  130.  *        (unsigned)class(op1) > (unsigned)class(op2)
  131.  * then op1 is the one we want; otherwise op2 is the one we want.
  132.  */
  133. #define   ORDER(x, y) { if ((u_int)(x)->fp_class > (u_int)(y)->fp_class) SWAP(x, y); }
  134. #define   SWAP(x, y) { register struct fpn *swap; swap = (x), (x) = (y), (y) = swap; }
  135.  
  136. /*
  137.  * Emulator state.
  138.  */
  139. struct fpemu {
  140.     struct          frame *fe_frame; /* integer regs, etc */
  141.     struct          fpframe *fe_fpframe; /* FP registers, etc */
  142.     u_int fe_fpsr;  /* fpsr copy (modified during op) */
  143.     u_int fe_fpcr;  /* fpcr copy */
  144.     struct          fpn fe_f1;          /* operand 1 */
  145.     struct          fpn fe_f2;          /* operand 2, if required */
  146.     struct          fpn fe_f3;          /* available storage for result */
  147. };
  148.  
  149. /*****************************************************************************
  150.  * End of definitions derived from Sparc FPE
  151.  *****************************************************************************/
  152.  
  153. /*
  154.  * Internal info about a decoded effective address.
  155.  */
  156. struct insn_ea {
  157.     int   ea_regnum;
  158.     int   ea_ext[3];                    /* extention words if any */
  159.     int   ea_flags;           /* flags == 0 means mode 2: An@ */
  160. #define   EA_DIRECT 0x001     /* mode [01]: Dn or An */
  161. #define EA_PREDECR  0x002     /* mode 4: An@- */
  162. #define   EA_POSTINCR         0x004     /* mode 3: An@+ */
  163. #define EA_OFFSET   0x008     /* mode 5 or (7,2): APC@(d16) */
  164. #define   EA_INDEXED          0x010     /* mode 6 or (7,3): APC@(Xn:*:*,d8) etc */
  165. #define EA_ABS      0x020     /* mode (7,[01]): abs */
  166. #define EA_PC_REL   0x040     /* mode (7,[23]): PC@(d16) etc */
  167. #define   EA_IMMED  0x080     /* mode (7,4): #immed */
  168. #define EA_MEM_INDIR          0x100     /* mode 6 or (7,3): APC@(Xn:*:*,*)@(*) etc */
  169. #define EA_BASE_SUPPRSS       0x200     /* mode 6 or (7,3): base register suppressed */
  170.     int   ea_tdisp;           /* temp. displ. used to xfer many words */
  171. };
  172.  
  173. #define ea_offset   ea_ext[0] /* mode 5: offset word */
  174. #define ea_absaddr  ea_ext[0] /* mode (7,[01]): absolute address */
  175. #define ea_immed    ea_ext              /* mode (7,4): immediate value */
  176. #define ea_basedisp ea_ext[0] /* mode 6: base displacement */
  177. #define ea_outerdisp          ea_ext[1] /* mode 6: outer displacement */
  178. #define   ea_idxreg ea_ext[2] /* mode 6: index register number */
  179.  
  180. struct instruction {
  181.     int             is_advance;         /* length of instruction */
  182.     int             is_datasize;        /* byte, word, long, float, double, ... */
  183.     int             is_opcode;          /* opcode word */
  184.     int             is_word1; /* second word */
  185.     struct          insn_ea   is_ea0;   /* decoded effective address mode */
  186. };
  187.  
  188. /*
  189.  * FP data types
  190.  */
  191. #define FTYPE_LNG 0 /* Long Word Integer */
  192. #define FTYPE_SNG 1 /* Single Prec */
  193. #define FTYPE_EXT 2 /* Extended Prec */
  194. #define FTYPE_BCD 3 /* Packed BCD */
  195. #define FTYPE_WRD 4 /* Word Integer */
  196. #define FTYPE_DBL 5 /* Double Prec */
  197. #define FTYPE_BYT 6 /* Byte Integer */
  198.  
  199. /*
  200.  * MC68881/68882 FPcr bit definitions (should these go to <m68k/reg.h>
  201.  * or <m68k/fpu.h> or something?)
  202.  */
  203.  
  204. /* fpsr */
  205. #define FPSR_CCB    0xff000000
  206. # define FPSR_NEG   0x08000000
  207. # define FPSR_ZERO  0x04000000
  208. # define FPSR_INF   0x02000000
  209. # define FPSR_NAN   0x01000000
  210. #define FPSR_QTT    0x00ff0000
  211. # define FPSR_QSG   0x00800000
  212. # define FPSR_QUO   0x007f0000
  213. #define FPSR_EXCP   0x0000ff00
  214. # define FPSR_BSUN  0x00008000
  215. # define FPSR_SNAN  0x00004000
  216. # define FPSR_OPERR 0x00002000
  217. # define FPSR_OVFL  0x00001000
  218. # define FPSR_UNFL  0x00000800
  219. # define FPSR_DZ    0x00000400
  220. # define FPSR_INEX2 0x00000200
  221. # define FPSR_INEX1 0x00000100
  222. #define FPSR_AEX    0x000000ff
  223. # define FPSR_AIOP  0x00000080
  224. # define FPSR_AOVFL 0x00000040
  225. # define FPSR_AUNFL 0x00000020
  226. # define FPSR_ADZ   0x00000010
  227. # define FPSR_AINEX 0x00000008
  228.  
  229. /* fpcr */
  230. #define FPCR_EXCP   FPSR_EXCP
  231. # define FPCR_BSUN  FPSR_BSUN
  232. # define FPCR_SNAN  FPSR_SNAN
  233. # define FPCR_OPERR FPSR_OPERR
  234. # define FPCR_OVFL  FPSR_OVFL
  235. # define FPCR_UNFL  FPSR_UNFL
  236. # define FPCR_DZ    FPSR_DZ
  237. # define FPCR_INEX2 FPSR_INEX2
  238. # define FPCR_INEX1 FPSR_INEX1
  239. #define FPCR_MODE   0x000000ff
  240. # define FPCR_PREC  0x000000c0
  241. #  define FPCR_EXTD 0x00000000
  242. #  define FPCR_SNGL 0x00000040
  243. #  define FPCR_DBL  0x00000080
  244. # define FPCR_ROUND 0x00000030
  245. #  define FPCR_NEAR 0x00000000
  246. #  define FPCR_ZERO 0x00000010
  247. #  define FPCR_MINF 0x00000020
  248. #  define FPCR_PINF 0x00000030
  249.  
  250. /*
  251.  * Other functions.
  252.  */
  253.  
  254. /* Build a new Quiet NaN (sign=0, frac=all 1's). */
  255. struct    fpn *fpu_newnan (struct fpemu *fe);
  256.  
  257. /*
  258.  * Shift a number right some number of bits, taking care of round/sticky.
  259.  * Note that the result is probably not a well-formed number (it will lack
  260.  * the normal 1-bit mant[0]&FP_1).
  261.  */
  262. int       fpu_shr (struct fpn * fp, int shr);
  263. /*
  264.  * Round a number according to the round mode in FPCR
  265.  */
  266. int       round (register struct fpemu *fe, register struct fpn *fp);
  267.  
  268. /* type conversion */
  269. void      fpu_explode (struct fpemu *fe, struct fpn *fp, int t, u_int *src);
  270. void      fpu_implode (struct fpemu *fe, struct fpn *fp, int t, u_int *dst);
  271.  
  272. /*
  273.  * non-static emulation functions
  274.  */
  275. /* type 0 */
  276. int fpu_emul_fmovecr (struct fpemu *fe, struct instruction *insn);
  277. int fpu_emul_fstore (struct fpemu *fe, struct instruction *insn);
  278. int fpu_emul_fscale (struct fpemu *fe, struct instruction *insn);
  279.  
  280. /*
  281.  * include function declarations of those which are called by fpu_emul_arith()
  282.  */
  283. #include "fpu_arpr.h"
  284.  
  285. /*
  286.  * "helper" functions
  287.  */
  288. /* return values from constant rom */
  289. struct fpn *fpu_const (struct fpn *fp, u_int offset);
  290. /* update exceptions and FPSR */
  291. int fpu_upd_excp (struct fpemu *fe);
  292. u_int fpu_upd_fpsr (struct fpemu *fe, struct fpn *fp);
  293.  
  294. /* address mode decoder, and load/store */
  295. int fpu_decode_ea (struct frame *frame, struct instruction *insn,
  296.                        struct insn_ea *ea, int modreg);
  297. int fpu_load_ea (struct frame *frame, struct instruction *insn,
  298.                      struct insn_ea *ea, char *dst);
  299. int fpu_store_ea (struct frame *frame, struct instruction *insn,
  300.                       struct insn_ea *ea, char *src);
  301.  
  302. /* macros for debugging */
  303.  
  304.  
  305. extern int fpu_debug_level;
  306.  
  307. /* debug classes */
  308. #define DL_DUMPINSN 0x0001
  309. #define DL_DECODEEA 0x0002
  310. #define DL_LOADEA   0x0004
  311. #define DL_STOREEA  0x0008
  312. #define DL_OPERANDS 0x0010
  313. #define DL_RESULT   0x0020
  314. #define DL_TESTCC   0x0040
  315. #define DL_BRANCH   0x0080
  316. #define DL_FSTORE   0x0100
  317. #define DL_FSCALE   0x0200
  318. #define DL_ARITH    0x0400
  319. #define DL_INSN     0x0800
  320. #define DL_FMOVEM   0x1000
  321. /* not defined yet
  322. #define DL_2000     0x2000
  323. #define DL_4000     0x4000
  324. */
  325. #define DL_VERBOSE  0x8000
  326. /* composit debug classes */
  327. #define DL_EA       (DL_DECODEEA|DL_LOADEA|DL_STOREEA)
  328. #define DL_VALUES   (DL_OPERANDS|DL_RESULT)
  329. #define DL_COND     (DL_TESTCC|DL_BRANCH)
  330. #define DL_ALL      0xffff
  331.  
  332. #endif /* _FPU_EMULATE_H_ */
  333.