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_ARIT.H < prev    next >
Encoding:
C/C++ Source or Header  |  1979-12-31  |  6.0 KB  |  131 lines

  1. /*        $NetBSD: fpu_arith.h,v 1.2 1994/11/20 20:52:35 deraadt Exp $ */
  2.  
  3. /*
  4.  * Copyright (c) 1992, 1993
  5.  *        The Regents of the University of California.  All rights reserved.
  6.  *
  7.  * This software was developed by the Computer Systems Engineering group
  8.  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
  9.  * contributed to Berkeley.
  10.  *
  11.  * All advertising materials mentioning features or use of this software
  12.  * must display the following acknowledgement:
  13.  *        This product includes software developed by the University of
  14.  *        California, Lawrence Berkeley Laboratory.
  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. All advertising materials mentioning features or use of this software
  25.  *    must display the following acknowledgement:
  26.  *        This product includes software developed by the University of
  27.  *        California, Berkeley and its contributors.
  28.  * 4. Neither the name of the University nor the names of its contributors
  29.  *    may be used to endorse or promote products derived from this software
  30.  *    without specific prior written permission.
  31.  *
  32.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  33.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  34.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  35.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  36.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  37.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  38.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  40.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  41.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  42.  * SUCH DAMAGE.
  43.  *
  44.  *        @(#)fpu_arith.h     8.1 (Berkeley) 6/11/93
  45.  */
  46.  
  47. /*
  48.  * Extended-precision arithmetic.
  49.  *
  50.  * We hold the notion of a `carry register', which may or may not be a
  51.  * machine carry bit or register.  On the SPARC, it is just the machine's
  52.  * carry bit.
  53.  *
  54.  * In the worst case, you can compute the carry from x+y as
  55.  *        (unsigned)(x + y) < (unsigned)x
  56.  * and from x+y+c as
  57.  *        ((unsigned)(x + y + c) <= (unsigned)x && (y|c) != 0)
  58.  * for example.
  59.  */
  60.  
  61. #ifdef sparc
  62.  
  63. /* set up for extended-precision arithemtic */
  64. #define   FPU_DECL_CARRY
  65.  
  66. /*
  67.  * We have three kinds of add:
  68.  *        add with carry:                                               r = x + y + c
  69.  *        add (ignoring current carry) and set carry:       c'r = x + y + 0
  70.  *        add with carry and set carry:                     c'r = x + y + c
  71.  * The macros use `C' for `use carry' and `S' for `set carry'.
  72.  * Note that the state of the carry is undefined after ADDC and SUBC,
  73.  * so if all you have for these is `add with carry and set carry',
  74.  * that is OK.
  75.  *
  76.  * The same goes for subtract, except that we compute x - y - c.
  77.  *
  78.  * Finally, we have a way to get the carry into a `regular' variable,
  79.  * or set it from a value.  SET_CARRY turns 0 into no-carry, nonzero
  80.  * into carry; GET_CARRY sets its argument to 0 or 1.
  81.  */
  82. #define   FPU_ADDC(r, x, y) \
  83.           asm volatile("addx %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  84. #define   FPU_ADDS(r, x, y) \
  85.           asm volatile("addcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  86. #define   FPU_ADDCS(r, x, y) \
  87.           asm volatile("addxcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  88. #define   FPU_SUBC(r, x, y) \
  89.           asm volatile("subx %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  90. #define   FPU_SUBS(r, x, y) \
  91.           asm volatile("subcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  92. #define   FPU_SUBCS(r, x, y) \
  93.           asm volatile("subxcc %1,%2,%0" : "=r"(r) : "r"(x), "r"(y))
  94.  
  95. #define   FPU_GET_CARRY(r) asm volatile("addx %%g0,%%g0,%0" : "=r"(r))
  96. #define   FPU_SET_CARRY(v) asm volatile("addcc %0,-1,%%g0" : : "r"(v))
  97.  
  98. #define   FPU_SHL1_BY_ADD     /* shift left 1 faster by ADDC than (a<<1)|(b>>31) */
  99.  
  100. #else /* non sparc */
  101.  
  102. /* set up for extended-precision arithemtic */
  103. #define   FPU_DECL_CARRY quad_t fpu_carry, fpu_tmp;
  104.  
  105. /*
  106.  * We have three kinds of add:
  107.  *        add with carry:                                               r = x + y + c
  108.  *        add (ignoring current carry) and set carry:       c'r = x + y + 0
  109.  *        add with carry and set carry:                     c'r = x + y + c
  110.  * The macros use `C' for `use carry' and `S' for `set carry'.
  111.  * Note that the state of the carry is undefined after ADDC and SUBC,
  112.  * so if all you have for these is `add with carry and set carry',
  113.  * that is OK.
  114.  *
  115.  * The same goes for subtract, except that we compute x - y - c.
  116.  *
  117.  * Finally, we have a way to get the carry into a `regular' variable,
  118.  * or set it from a value.  SET_CARRY turns 0 into no-carry, nonzero
  119.  * into carry; GET_CARRY sets its argument to 0 or 1.
  120.  */
  121. #define   FPU_ADDC(r, x, y) (r) = (x) + (y) + (!!fpu_carry)
  122. #define   FPU_ADDS(r, x, y) { fpu_tmp = (quad_t)(x) + (quad_t)(y); (r) = (u_int)fpu_tmp; fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); }
  123. #define   FPU_ADDCS(r, x, y) { fpu_tmp = (quad_t)(x) + (quad_t)(y) + (!!fpu_carry); (r) = (u_int)fpu_tmp; fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); }
  124. #define   FPU_SUBC(r, x, y) (r) = (x) - (y) - (!!fpu_carry)
  125. #define   FPU_SUBS(r, x, y) { fpu_tmp = (quad_t)(x) - (quad_t)(y); (r) = (u_int)fpu_tmp; fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); }
  126. #define   FPU_SUBCS(r, x, y) { fpu_tmp = (quad_t)(x) - (quad_t)(y) - (!!fpu_carry); (r) = (u_int)fpu_tmp; fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); }
  127. #define   FPU_GET_CARRY(r) (r) = (!!fpu_carry)
  128. #define   FPU_SET_CARRY(v) fpu_carry = ((v) != 0)
  129.  
  130. #endif
  131.