|
|
1.1 root 1: /* $NetBSD: fpu_arith.h,v 1.8 2013/04/01 13:59:21 isaki 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. Neither the name of the University nor the names of its contributors
25: * may be used to endorse or promote products derived from this software
26: * without specific prior written permission.
27: *
28: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38: * SUCH DAMAGE.
39: *
40: * @(#)fpu_arith.h 8.1 (Berkeley) 6/11/93
41: */
42:
43: /*
44: * Extended-precision arithmetic.
45: *
46: * We hold the notion of a `carry register', which may or may not be a
47: * machine carry bit or register. On the SPARC, it is just the machine's
48: * carry bit.
49: *
50: * In the worst case, you can compute the carry from x+y as
51: * (unsigned)(x + y) < (unsigned)x
52: * and from x+y+c as
53: * ((unsigned)(x + y + c) <= (unsigned)x && (y|c) != 0)
54: * for example.
55: */
56:
57: #ifndef FPE_USE_ASM
58:
59: /* set up for extended-precision arithemtic */
60: #define FPU_DECL_CARRY uint64_t fpu_carry, fpu_tmp;
61:
62: /*
63: * We have three kinds of add:
64: * add with carry: r = x + y + c
65: * add (ignoring current carry) and set carry: c'r = x + y + 0
66: * add with carry and set carry: c'r = x + y + c
67: * The macros use `C' for `use carry' and `S' for `set carry'.
68: * Note that the state of the carry is undefined after ADDC and SUBC,
69: * so if all you have for these is `add with carry and set carry',
70: * that is OK.
71: *
72: * The same goes for subtract, except that we compute x - y - c.
73: *
74: * Finally, we have a way to get the carry into a `regular' variable,
75: * or set it from a value. SET_CARRY turns 0 into no-carry, nonzero
76: * into carry; GET_CARRY sets its argument to 0 or 1.
77: */
78: #define FPU_ADDC(r, x, y) \
79: (r) = (x) + (y) + (!!fpu_carry)
80: #define FPU_ADDS(r, x, y) \
81: { \
82: fpu_tmp = (uint64_t)(x) + (uint64_t)(y); \
83: (r) = (uint32_t)fpu_tmp; \
84: fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
85: }
86: #define FPU_ADDCS(r, x, y) \
87: { \
88: fpu_tmp = (uint64_t)(x) + (uint64_t)(y) + (!!fpu_carry); \
89: (r) = (uint32_t)fpu_tmp; \
90: fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
91: }
92: #define FPU_SUBC(r, x, y) \
93: (r) = (x) - (y) - (!!fpu_carry)
94: #define FPU_SUBS(r, x, y) \
95: { \
96: fpu_tmp = (uint64_t)(x) - (uint64_t)(y); \
97: (r) = (uint32_t)fpu_tmp; \
98: fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
99: }
100: #define FPU_SUBCS(r, x, y) \
101: { \
102: fpu_tmp = (uint64_t)(x) - (uint64_t)(y) - (!!fpu_carry); \
103: (r) = (uint32_t)fpu_tmp; \
104: fpu_carry = ((fpu_tmp & 0xffffffff00000000LL) != 0); \
105: }
106:
107: #define FPU_GET_CARRY(r) (r) = (!!fpu_carry)
108: #define FPU_SET_CARRY(v) fpu_carry = ((v) != 0)
109:
110: #else
111:
112: /* set up for extended-precision arithemtic */
113: #define FPU_DECL_CARRY int fpu_tmp;
114:
115: /*
116: * We have three kinds of add:
117: * add with carry: r = x + y + c
118: * add (ignoring current carry) and set carry: c'r = x + y + 0
119: * add with carry and set carry: c'r = x + y + c
120: * The macros use `C' for `use carry' and `S' for `set carry'.
121: * Note that the state of the carry is undefined after ADDC and SUBC,
122: * so if all you have for these is `add with carry and set carry',
123: * that is OK.
124: *
125: * The same goes for subtract, except that we compute x - y - c.
126: *
127: * Finally, we have a way to get the carry into a `regular' variable,
128: * or set it from a value. SET_CARRY turns 0 into no-carry, nonzero
129: * into carry; GET_CARRY sets its argument to 0 or 1.
130: */
131: #define FPU_ADDC(r, x, y) \
132: { \
133: __asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
134: __asm volatile("addxl %1,%0" : "=d"(fpu_tmp) : "d"(y)); \
135: __asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
136: }
137: #define FPU_ADDS(r, x, y) \
138: { \
139: __asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
140: __asm volatile("addl %1,%0" : "=d"(fpu_tmp) : "g"(y)); \
141: __asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
142: }
143: #define FPU_ADDCS(r, x, y) FPU_ADDC(r, x, y)
144:
145: #define FPU_SUBC(r, x, y) \
146: { \
147: __asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
148: __asm volatile("subxl %1,%0" : "=d"(fpu_tmp) : "d"(y)); \
149: __asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
150: }
151: #define FPU_SUBS(r, x, y) \
152: { \
153: __asm volatile("movel %1,%0" : "=d"(fpu_tmp) : "g"(x)); \
154: __asm volatile("subl %1,%0" : "=d"(fpu_tmp) : "g"(y)); \
155: __asm volatile("movel %1,%0" : "=g"(r) : "r"(fpu_tmp)); \
156: }
157: #define FPU_SUBCS(r, x, y) FPU_SUBC(r, x, y)
158:
159: #define FPU_GET_CARRY(r) \
160: { \
161: __asm volatile("moveq #0,%0" : "=d"(r)); \
162: __asm volatile("addxl %0,%0" : "+d"(r)); \
163: }
164: #define FPU_SET_CARRY(v) \
165: { \
166: __asm volatile("moveq #0,%0" : "=d"(fpu_tmp)); \
167: __asm volatile("subl %1,%0" : "=d"(fpu_tmp) : "g"(v)); \
168: }
169:
170: #endif /* FPE_USE_ASM */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.