/* [<][>][^][v][top][bottom][index][help] */
1 /*
2 * arith_i386.h - i386 specific arithmetic macros
3 *
4 * Copyright (c) 2000-2003 Shiro Kawai, All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the authors nor the names of its contributors
18 * may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * $Id: arith_i386.h,v 1.6 2005/05/24 07:31:48 shirok Exp $
34 */
35
36 #ifdef __GNUC__
37
38 /*-----------------------------------------------------------------
39 * UADD(r, c, x, y) unsigned word add with carry
40 * u_long : r, c, x, y;
41 * r <- x + y + c mod wordsize
42 * c <- 1 if carry, 0 otherwise
43 */
44
45 /* NB: in some context, the compiler failed to allocate registers
46 * for 'r' and 'c', so I can't use "r" constraint for them.
47 * The following code assumes 'r', 'c', 'x' and 'y' are stack-allocated
48 * and to avoid both operands from being on memory.
49 */
50 #define UADD(r, c, x, y) \
51 asm("cmpl $1, %2;" \
52 "cmc;" \
53 "movl %3, %%eax;" \
54 "adcl %4, %%eax;" \
55 "movl %%eax, %0;" \
56 "movl $0, %%eax;" \
57 "adcl $0, %%eax;" \
58 "movl %%eax, %1;" \
59 : "=&g" (r), "=&g" (c) \
60 : "1" (c), "g"(x), "g"(y) \
61 : "%eax")
62
63 /*-----------------------------------------------------------------
64 * UADDOV(r, v, x, y) unsigned word add with overflow check
65 * u_long : r, v, x, y;
66 * if x + y overflows, v = 1
67 * else r <- x + y, v = 0
68 */
69
70 #define UADDOV(r, v, x, y) \
71 asm("movl %2, %0;" \
72 "addl %3, %0;" \
73 "movl $0, %1;" \
74 "rcll $1, %1;" \
75 : "=&r" (r), "=&r" (v) \
76 : "g" (x), "g" (y))
77
78 /*-----------------------------------------------------------------
79 * SADDOV(r, v, x, y) signed word addition with overflow check
80 * long : r, v, x, y;
81 * if x + y overflows, v = 1 or -1 depending on the sign of the result
82 * else r <- x + y, v = 0
83 */
84
85 #define SADDOV(r, v, x, y) \
86 asm("movl $0, %1;" \
87 "movl %2, %0;" \
88 "addl %3, %0;" \
89 "jno 0f;" \
90 "jns 1f;" \
91 "movl $1, %1; jmp 0f;" \
92 "1: movl $-1, %1;" \
93 "0:" \
94 : "=&r" (r), "=&r" (v) \
95 : "g" (x), "g" (y))
96
97 /*-----------------------------------------------------------------
98 * USUB(r, c, x, y) unsigned word subtract with borrow
99 * u_long : r, x, c, y;
100 * r <- x - y - c mod wordsize
101 * c <- 1 if borrow, 0 otherwise
102 */
103
104 #define USUB(r, c, x, y) \
105 asm("shrl $1, %2;" \
106 "movl %3, %0;" \
107 "sbbl %4, %0;" \
108 "movl $0, %1;" \
109 "rcll $1, %1;" \
110 : "=&r" (r), "=&r"(c) \
111 : "1" (c), "g" (x), "g" (y))
112
113 /*-----------------------------------------------------------------
114 * USUBOV(r, v, x, y) unsigned word subtract with overflow check
115 * u_long : r, v, x, y;
116 * if x - y overflows, v = 1
117 * else r <- x - y, v = 0
118 */
119
120 #define USUBOV(r, v, x, y) \
121 asm("movl %2, %0;" \
122 "subl %3, %0;" \
123 "movl $0, %1;" \
124 "rcll $1, %1;" \
125 : "=&r" (r), "=&r"(v) \
126 : "g" (x), "g" (y))
127
128 /*-----------------------------------------------------------------
129 * SSUBOV(r, v, x, y) signed word subtract without borrow
130 * long : r, v, x, y;
131 * if x - y overflows, c = 1 or -1 depending on the sign of the result
132 * else r <- x - y, v = 0
133 */
134
135 #define SSUBOV(r, v, x, y) \
136 asm("movl $0, %1;" \
137 "movl %2, %0;" \
138 "subl %3, %0;" \
139 "jno 0f;" \
140 "jns 1f;" \
141 "movl $1, %1; jmp 0f;" \
142 "1: movl $-1, %1;" \
143 "0:" \
144 : "=&r" (r), "=&r" (v) \
145 : "g" (x), "g" (y))
146
147 /*-----------------------------------------------------------------
148 * UMUL(hi, lo, x, y) unsigned word multiply
149 * u_long : hi, lo, x, y;
150 * [hi, lo] <- x * y
151 */
152
153 #define UMUL(hi, lo, x, y) \
154 asm("movl %2, %%eax;" \
155 "mull %3;" \
156 "movl %%eax, %1;" \
157 "movl %%edx, %0;" \
158 : "=r" (hi), "=r" (lo) \
159 : "g" (x), "r" (y) \
160 : "%eax", "%edx")
161
162 /*-----------------------------------------------------------------
163 * UMULOV(r, v, x, y) unsigned word multiply with overflow check
164 * u_long : r, x, y
165 * int : v
166 * if x * y overflows, v = 1
167 * else r <- x * y, v = 0
168 */
169 /* This and SMULOV is used in the gauche.uvector where lots of
170 functions are inlined, and using "r" constraint sometimes makes
171 gcc fail to allocate registers. Thus we use "g" constraint. */
172
173 #define UMULOV(r, v, x, y) \
174 asm("mull %2;" \
175 "rcll $1, %1;" \
176 : "=a" (r), "=r" (v) \
177 : "r" (y), "0" (x), "1" (0) \
178 : "%edx")
179
180 /*-----------------------------------------------------------------
181 * SMULOV(r, v, x, y) signed word multiply with overflow check
182 * long : r, x, y
183 * int : v
184 * if x * y overflows, v = 1 or -1 depending on the sign of the result
185 * else r <- x * y, v = 0
186 */
187
188 #define SMULOV(r, v, x, y) \
189 asm("imull %2;" \
190 "jno 0f;" \
191 "cmp $0, %%edx;" \
192 "jl 1f;" \
193 "movl $1, %1; jmp 0f;" \
194 "1: movl $-1, %1;" \
195 "0:" \
196 : "=a" (r), "=r" (v) \
197 : "r" (y), "0" (x), "1" (0) \
198 : "%edx")
199
200 #endif /*__GNUC__*/
201
202