1 /*
2 * Copyright (C) 2005-2011 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *
28 * Alpha ALU instructions. (Included from tmp_alpha_misc.c.)
29 *
30 *
31 * Most ALU instructions have the following arguments:
32 *
33 * arg[0] = pointer to destination uint64_t
34 * arg[1] = pointer to source uint64_t nr 1
35 * arg[2] = pointer to source uint64_t nr 2
36 *
37 * or, if ALU_IMM is set, arg[2] contains an 8-bit immediate value.
38 *
39 * The main function groups are:
40 *
41 * ALU_INS inserts
42 * ALU_EXT extracts
43 * ALU_MSK masks
44 * ALU_CMOV conditional moves
45 * ALU_CMP compares
46 * ALU_CMPBGE byte compare
47 * none of the above everything else (add, sub, ...)
48 */
49
ALU_N(struct cpu * cpu,struct alpha_instr_call * ic)50 void ALU_N(struct cpu *cpu, struct alpha_instr_call *ic)
51 {
52 #ifdef ALU_INS
53
54 uint64_t x = *((uint64_t *)ic->arg[1]);
55 int r = (
56 #ifdef ALU_IMM
57 ic->arg[2]
58 #else
59 (*((uint64_t *)ic->arg[2]))
60 #endif
61 & 7) * 8;
62
63 #ifdef ALU_B
64 x &= 0xff;
65 #endif
66 #ifdef ALU_W
67 x &= 0xffff;
68 #endif
69 #ifdef ALU_L
70 x &= 0xffffffffULL;
71 #endif
72
73 #ifdef ALU_LO
74 x <<= r;
75 #else
76 r = 64 - r;
77 if (r == 64)
78 x = 0;
79 else
80 x >>= r;
81 #endif
82 *((uint64_t *)ic->arg[0]) = x;
83
84 #else /* ! INS */
85
86 #ifdef ALU_EXT
87
88 uint64_t x = *((uint64_t *)ic->arg[1]);
89 int r = (
90 #ifdef ALU_IMM
91 ic->arg[2]
92 #else
93 (*((uint64_t *)ic->arg[2]))
94 #endif
95 & 7) * 8;
96 #ifdef ALU_LO
97 x >>= r;
98 #else
99 r = 64 - r;
100 if (r != 64)
101 x <<= r;
102 #endif
103 #ifdef ALU_B
104 x &= 0xff;
105 #endif
106 #ifdef ALU_W
107 x &= 0xffff;
108 #endif
109 #ifdef ALU_L
110 x &= 0xffffffffULL;
111 #endif
112 *((uint64_t *)ic->arg[0]) = x;
113
114 #else /* ! EXT */
115
116 #ifdef ALU_MSK
117
118 uint64_t x = *((uint64_t *)ic->arg[1]);
119 #ifdef ALU_B
120 uint64_t mask = 0x00000000000000ffULL;
121 #endif
122 #ifdef ALU_W
123 uint64_t mask = 0x000000000000ffffULL;
124 #endif
125 #ifdef ALU_L
126 uint64_t mask = 0x00000000ffffffffULL;
127 #endif
128 #ifdef ALU_Q
129 uint64_t mask = 0xffffffffffffffffULL;
130 #endif
131 int r = (
132 #ifdef ALU_IMM
133 ic->arg[2]
134 #else
135 (*((uint64_t *)ic->arg[2]))
136 #endif
137 & 7) * 8;
138
139 #ifdef ALU_LO
140 mask <<= r;
141 #else
142 if (r == 0)
143 mask = 0;
144 else
145 mask >>= (64 - r);
146 #endif
147
148 *((uint64_t *)ic->arg[0]) = x & ~mask;
149
150 #else /* !MSK */
151
152 #ifdef ALU_CMOV
153
154 if (
155 #ifdef ALU_CMOV_lbc
156 !(
157 #endif
158 (*((int64_t *)ic->arg[1]))
159 #ifdef ALU_CMOV_eq
160 == 0
161 #endif
162 #ifdef ALU_CMOV_ne
163 != 0
164 #endif
165 #ifdef ALU_CMOV_le
166 <= 0
167 #endif
168 #ifdef ALU_CMOV_lt
169 < 0
170 #endif
171 #ifdef ALU_CMOV_ge
172 >= 0
173 #endif
174 #ifdef ALU_CMOV_gt
175 > 0
176 #endif
177 #ifdef ALU_CMOV_lbs
178 & 1
179 #endif
180 #ifdef ALU_CMOV_lbc
181 & 1)
182 #endif
183 )
184 *((uint64_t *)ic->arg[0]) =
185 #ifdef ALU_IMM
186 (uint64_t)ic->arg[2]
187 #else
188 (*((uint64_t *)ic->arg[2]))
189 #endif
190 ;
191
192 #else /* ! CMOV */
193
194 #ifdef ALU_CMPBGE
195
196 uint64_t ra = *((uint64_t *)ic->arg[1]), rc = 0, rb =
197 #ifdef ALU_IMM
198 (uint64_t)ic->arg[2]
199 #else
200 (*((uint64_t *)ic->arg[2]))
201 #endif
202 ;
203 int i;
204 for (i=7; i>=0; i--) {
205 if ((uint8_t)ra >= (uint8_t)rb)
206 rc |= (1 << i);
207 rb >>= 8; ra >>= 8;
208 }
209
210 *((uint64_t *)ic->arg[0]) = rc;
211
212 #else /* ! CMPBGE */
213
214 #ifdef ALU_CMP
215
216 uint64_t x;
217
218 x = (*((
219 #ifdef ALU_UNSIGNED
220 uint64_t
221 #else
222 int64_t
223 #endif
224 *)ic->arg[1]))
225
226 #ifdef ALU_CMP_EQ
227 ==
228 #endif
229 #ifdef ALU_CMP_LE
230 <=
231 #endif
232 #ifdef ALU_CMP_LT
233 <
234 #endif
235
236 #ifdef ALU_IMM
237 #ifdef ALU_UNSIGNED
238 (uint64_t)ic->arg[2]
239 #else
240 (int64_t)ic->arg[2]
241 #endif
242 #else
243 #ifdef ALU_UNSIGNED
244 (*((uint64_t *)ic->arg[2]))
245 #else
246 (*((int64_t *)ic->arg[2]))
247 #endif
248 #endif
249 ;
250
251 #else /* !ALU_CMP */
252
253 #ifdef ALU_LONG
254 /* Long */
255 int32_t x;
256 #else
257 /* Quad */
258 int64_t x;
259 #endif
260
261 #ifdef ALU_ZAP
262 /* Prepare for zapping: */
263 uint64_t zapmask = 0xffffffffffffffffULL;
264 int zapbytes =
265 #ifdef ALU_NOT
266 ~
267 #endif
268 #ifdef ALU_IMM
269 (int64_t)ic->arg[2]
270 #else
271 (*((uint64_t *)ic->arg[2]))
272 #endif
273 ;
274 if (zapbytes & 0x80)
275 zapmask &= ~0xff00000000000000ULL;
276 if (zapbytes & 0x40)
277 zapmask &= ~0xff000000000000ULL;
278 if (zapbytes & 0x20)
279 zapmask &= ~0xff0000000000ULL;
280 if (zapbytes & 0x10)
281 zapmask &= ~0xff00000000ULL;
282 if (zapbytes & 0x08)
283 zapmask &= ~0xff000000ULL;
284 if (zapbytes & 0x04)
285 zapmask &= ~0xff0000ULL;
286 if (zapbytes & 0x02)
287 zapmask &= ~0xff00ULL;
288 if (zapbytes & 0x01)
289 zapmask &= ~0xffULL;
290 #endif /* ZAP */
291
292 x = (
293 #ifdef ALU_SRA
294 (int64_t)
295 #endif
296 (*((uint64_t *)ic->arg[1]))
297 #ifdef ALU_S4
298 * 4
299 #endif
300 #ifdef ALU_S8
301 * 8
302 #endif
303 )
304 #ifdef ALU_ADD
305 +
306 #endif
307 #ifdef ALU_SUB
308 -
309 #endif
310 #ifdef ALU_OR
311 |
312 #endif
313 #ifdef ALU_XOR
314 ^
315 #endif
316 #ifdef ALU_AND
317 &
318 #endif
319 #ifdef ALU_SLL
320 <<
321 #endif
322 #if defined(ALU_SRA) || defined(ALU_SRL)
323 >>
324 #endif
325
326 #ifdef ALU_ZAP
327 & zapmask
328 #else /* !ZAP */
329 (
330 #ifdef ALU_NOT
331 ~
332 #endif
333 (
334 #ifdef ALU_IMM
335 (int64_t)ic->arg[2]
336 #else
337 (*((uint64_t *)ic->arg[2]))
338 #endif
339 #if defined(ALU_SRA) || defined(ALU_SRL) || defined(ALU_SLL)
340 & 63
341 #endif
342 )
343 )
344 #endif /* !ZAP */
345
346 ;
347
348 #endif /* !ALU_CMP */
349
350 *((uint64_t *)ic->arg[0]) = x;
351 #endif /* ! CMPBGE */
352 #endif /* ! CMOV */
353 #endif /* ! MSK */
354 #endif /* ! EXT */
355 #endif /* ! INS */
356 }
357
358