Commit | Line | Data |
---|---|---|
d6fea803 AC |
1 | /* This file is part of the program psim. |
2 | ||
3 | Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au> | |
4 | Copyright (C) 1997, Free Software Foundation, Inc. | |
5 | ||
6 | This program is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8 | the Free Software Foundation; either version 2 of the License, or | |
9 | (at your option) any later version. | |
10 | ||
11 | This program is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
17 | along with this program; if not, write to the Free Software | |
18 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
19 | ||
20 | */ | |
21 | ||
22 | ||
23 | #ifndef _SIM_ALU_H_ | |
24 | #define _SIM_ALU_H_ | |
25 | ||
36dbc8bb | 26 | #include "symcat.h" |
d6fea803 | 27 | |
d6fea803 | 28 | |
36dbc8bb | 29 | /* INTEGER ALU MODULE: |
d6fea803 | 30 | |
36dbc8bb DE |
31 | This module provides an implementation of 2's complement arithmetic |
32 | including the recording of carry and overflow status bits. | |
d6fea803 AC |
33 | |
34 | ||
36dbc8bb | 35 | EXAMPLE: |
d6fea803 | 36 | |
36dbc8bb DE |
37 | Code using this module includes it into sim-main.h and then, as a |
38 | convention, defines macro's ALU*_END that records the result of any | |
39 | aritmetic performed. Ex: | |
d6fea803 | 40 | |
36dbc8bb DE |
41 | #include "sim-alu.h" |
42 | #define ALU32_END(RES) \ | |
43 | (RES) = ALU32_OVERFLOW_RESULT; \ | |
44 | carry = ALU32_HAD_CARRY_BORROW; \ | |
45 | overflow = ALU32_HAD_OVERFLOW | |
d6fea803 | 46 | |
36dbc8bb DE |
47 | The macro's are then used vis: |
48 | ||
49 | { | |
50 | ALU32_BEGIN (GPR[i]); | |
51 | ALU32_ADDC (GPR[j]); | |
52 | ALU32_END (GPR[k]); | |
53 | } | |
54 | ||
55 | ||
56 | NOTES: | |
57 | ||
58 | Macros exist for efficiently computing 8, 16, 32 and 64 bit | |
59 | arithmetic - ALU8_*, ALU16_*, .... In addition, according to | |
60 | TARGET_WORD_BITSIZE a set of short-hand macros are defined - ALU_* | |
61 | ||
62 | Initialization: | |
63 | ||
64 | ALU*_BEGIN(ACC): Declare initialize the ALU accumulator with ACC. | |
65 | ||
66 | Results: | |
67 | ||
68 | The calculation of the final result may be computed a number | |
69 | of different ways. Three different overflow macro's are | |
70 | defined, the most efficient one to use depends on which other | |
71 | outputs from the alu are being used. | |
72 | ||
73 | ALU*_RESULT: Generic ALU result output. | |
74 | ||
75 | ALU*_HAD_OVERFLOW: Returns a nonzero value if signed overflow | |
76 | occured. | |
77 | ||
78 | ALU*_OVERFLOW_RESULT: If the macro ALU*_HAD_OVERFLOW is being | |
79 | used this is the most efficient result available. Ex: | |
80 | ||
81 | #define ALU16_END(RES) \ | |
82 | if (ALU16_HAD_OVERFLOW) \ | |
83 | sim_engine_halt (...); \ | |
84 | (RES) = ALU16_OVERFLOW_RESULT | |
85 | ||
86 | ALU*_HAD_CARRY_BORROW: Returns a nonzero value if unsigned | |
87 | overflow or underflow (also refered to as carry and borrow) | |
88 | occured. | |
89 | ||
90 | ALU*_CARRY_BORROW_RESULT: If the macro ALU*_HAD_CARRY_BORROW is being | |
91 | used this is the most efficient result available. Ex: | |
92 | ||
93 | #define ALU64_END(RES) \ | |
94 | State.carry = ALU64_HAD_CARRY_BORROW; \ | |
95 | (RES) = ALU64_CARRY_BORROW_RESULT | |
96 | ||
97 | ||
98 | Addition: | |
99 | ||
100 | ALU*_ADD(VAL): Add VAL to the ALU accumulator. Record any | |
101 | overflow as well as the final result. | |
102 | ||
103 | ALU*_ADDC(VAL): Add VAL to the ALU accumulator. Record any | |
104 | carry-out or overflow as well as the final result. | |
105 | ||
106 | ALU*_ADDC_C(VAL,CI): Add VAL and CI (carry-in). Record any | |
107 | carry-out or overflow as well as the final result. | |
108 | ||
109 | Subtraction: | |
110 | ||
111 | ALU*_SUB(VAL): Subtract VAL from the ALU accumulator. Record | |
112 | any underflow as well as the final result. | |
113 | ||
114 | ALU*_SUBC(VAL): Subtract VAL from the ALU accumulator using | |
115 | negated addition. Record any underflow or carry-out as well | |
116 | as the final result. | |
117 | ||
118 | ALU*_SUBB(VAL): Subtract VAL from the ALU accumulator using | |
119 | direct subtraction (ACC+~VAL+1). Record any underflow or | |
120 | borrow-out as well as the final result. | |
121 | ||
122 | ALU*_SUBC_X(VAL,CI): Subtract VAL and CI (carry-in) from the | |
123 | ALU accumulator using extended negated addition (ACC+~VAL+CI). | |
124 | Record any underflow or carry-out as well as the final result. | |
125 | ||
126 | ALU*_SUBB_B(VAL,BI): Subtract VAL and BI (borrow-in) from the | |
127 | ALU accumulator using direct subtraction. Record any | |
128 | underflow or borrow-out as well as the final result. | |
129 | ||
130 | ||
131 | */ | |
132 | ||
133 | ||
134 | ||
135 | /* Twos complement aritmetic - addition/subtraction - carry/borrow | |
136 | (or you thought you knew the answer to 0-0) | |
137 | ||
138 | ||
139 | ||
140 | Notation and Properties: | |
141 | ||
142 | ||
143 | Xn denotes the value X stored in N bits. | |
144 | ||
145 | MSBn (X): The most significant (sign) bit of X treated as an N bit | |
146 | value. | |
147 | ||
148 | SEXTn (X): The infinite sign extension of X treated as an N bit | |
149 | value. | |
150 | ||
151 | MAXn, MINn: The upper and lower bound of a signed, two's | |
152 | complement N bit value. | |
153 | ||
154 | UMAXn: The upper bound of an unsigned N bit value (the lower | |
155 | bound is always zero). | |
156 | ||
157 | Un: UMAXn + 1. Unsigned arrithmetic is computed `modulo (Un)'. | |
158 | ||
159 | X[p]: Is bit P of X. X[0] denotes the least signifant bit. | |
160 | ||
161 | ~X[p]: Is the inversion of bit X[p]. Also equal to 1-X[p], | |
162 | (1+X[p])mod(2). | |
163 | ||
164 | ||
165 | ||
166 | Addition - Overflow - Introduction: | |
167 | ||
168 | ||
169 | Overflow/Overflow indicates an error in computation of signed | |
170 | arrithmetic. i.e. given X,Y in [MINn..MAXn]; overflow | |
171 | indicates that the result X+Y > MAXn or X+Y < MIN_INTx. | |
172 | ||
173 | Hardware traditionally implements overflow by computing the XOR of | |
174 | carry-in/carry-out of the most significant bit of the ALU. Here | |
175 | other methods need to be found. | |
176 | ||
177 | ||
178 | ||
179 | Addition - Overflow - method 1: | |
180 | ||
181 | ||
182 | Overflow occures when the sign (most significant bit) of the two N | |
183 | bit operands is identical but different to the sign of the result: | |
184 | ||
185 | Rn = (Xn + Yn) | |
186 | V = MSBn (~(Xn ^ Yn) & (Rn ^ Xn)) | |
187 | ||
188 | ||
189 | ||
190 | Addition - Overflow - method 2: | |
d6fea803 AC |
191 | |
192 | ||
465db791 MM |
193 | The two N bit operands are sign extended to M>N bits and then |
194 | added. Overflow occures when SIGN_BIT<n> and SIGN_BIT<m> do not | |
195 | match. | |
196 | ||
36dbc8bb DE |
197 | Rm = (SEXTn (Xn) + SEXTn (Yn)) |
198 | V = MSBn ((Rm >> (M - N)) ^ Rm) | |
199 | ||
d6fea803 | 200 | |
d6fea803 | 201 | |
36dbc8bb DE |
202 | Addition - Overflow - method 3: |
203 | ||
d6fea803 | 204 | |
465db791 | 205 | The two N bit operands are sign extended to M>N bits and then |
36dbc8bb DE |
206 | added. Overflow occures when the result is outside of the sign |
207 | extended range [MINn .. MAXn]. | |
208 | ||
d6fea803 | 209 | |
d6fea803 | 210 | |
36dbc8bb | 211 | Addition - Overflow - method 4: |
465db791 | 212 | |
465db791 | 213 | |
36dbc8bb DE |
214 | Given the Result and Carry-out bits, the oVerflow from the addition |
215 | of X, Y and carry-In can be computed using the equation: | |
216 | ||
217 | Rn = (Xn + Yn) | |
218 | V = (MSBn ((Xn ^ Yn) ^ Rn)) ^ C) | |
465db791 MM |
219 | |
220 | As shown in the table below: | |
221 | ||
36dbc8bb | 222 | I X Y R C | V | X^Y ^R ^C |
465db791 MM |
223 | ---------------+---+------------- |
224 | 0 0 0 0 0 | 0 | 0 0 0 | |
225 | 0 0 1 1 0 | 0 | 1 0 0 | |
226 | 0 1 0 1 0 | 0 | 1 0 0 | |
227 | 0 1 1 0 1 | 1 | 0 0 1 | |
228 | 1 0 0 1 0 | 1 | 0 1 1 | |
229 | 1 0 1 0 1 | 0 | 1 1 0 | |
230 | 1 1 0 0 1 | 0 | 1 1 0 | |
231 | 1 1 1 1 1 | 0 | 0 1 0 | |
232 | ||
233 | ||
234 | ||
36dbc8bb DE |
235 | Addition - Carry - Introduction: |
236 | ||
465db791 | 237 | |
36dbc8bb DE |
238 | Carry (poorly named) indicates that an overflow occured for |
239 | unsigned N bit addition. i.e. given X, Y in [0..UMAXn] then | |
240 | carry indicates X+Y > UMAXn or X+Y >= Un. | |
465db791 | 241 | |
36dbc8bb DE |
242 | The following table lists the output for all given inputs into a |
243 | full-adder. | |
244 | ||
245 | I X Y R | C | |
465db791 MM |
246 | ------------+--- |
247 | 0 0 0 0 | 0 | |
248 | 0 0 1 1 | 0 | |
249 | 0 1 0 1 | 0 | |
250 | 0 1 1 0 | 1 | |
251 | 1 0 0 1 | 0 | |
252 | 1 0 1 0 | 1 | |
253 | 1 1 0 0 | 1 | |
254 | 1 1 1 1 | 1 | |
255 | ||
36dbc8bb DE |
256 | (carry-In, X, Y, Result, Carry-out): |
257 | ||
258 | ||
259 | ||
260 | Addition - Carry - method 1: | |
261 | ||
262 | ||
263 | Looking at the terms X, Y and R we want an equation for C. | |
465db791 | 264 | |
36dbc8bb | 265 | XY\R 0 1 |
465db791 MM |
266 | +------- |
267 | 00 | 0 0 | |
268 | 01 | 1 0 | |
269 | 11 | 1 1 | |
270 | 10 | 1 0 | |
271 | ||
272 | This giving us the sum-of-prod equation: | |
273 | ||
36dbc8bb | 274 | MSBn ((Xn & Yn) | (Xn & ~Rn) | (Yn & ~Rn)) |
465db791 MM |
275 | |
276 | Verifying: | |
277 | ||
36dbc8bb | 278 | I X Y R | C | X&Y X&~R Y&~R |
465db791 MM |
279 | ------------+---+--------------- |
280 | 0 0 0 0 | 0 | 0 0 0 | |
281 | 0 0 1 1 | 0 | 0 0 0 | |
282 | 0 1 0 1 | 0 | 0 0 0 | |
283 | 0 1 1 0 | 1 | 1 1 1 | |
284 | 1 0 0 1 | 0 | 0 0 0 | |
285 | 1 0 1 0 | 1 | 0 0 1 | |
286 | 1 1 0 0 | 1 | 0 1 0 | |
287 | 1 1 1 1 | 1 | 1 0 0 | |
288 | ||
289 | ||
290 | ||
36dbc8bb DE |
291 | Addition - Carry - method 2: |
292 | ||
465db791 MM |
293 | |
294 | Given two signed N bit numbers, a carry can be detected by treating | |
295 | the numbers as N bit unsigned and adding them using M>N unsigned | |
296 | arrithmetic. Carry is indicated by bit (1 << N) being set (result | |
297 | >= 2**N). | |
298 | ||
d6fea803 | 299 | |
30efae3a | 300 | |
36dbc8bb DE |
301 | Addition - Carry - method 3: |
302 | ||
30efae3a | 303 | |
36dbc8bb | 304 | Given the oVerflow bit. The carry can be computed from: |
d6fea803 | 305 | |
465db791 | 306 | (~R&V) | (R&V) |
d6fea803 AC |
307 | |
308 | ||
465db791 | 309 | |
36dbc8bb DE |
310 | Addition - Carry - method 4: |
311 | ||
312 | Given two signed numbers. Treating them as unsigned we have: | |
313 | ||
314 | 0 <= X < Un, 0 <= Y < Un | |
315 | ==> X + Y < 2 Un | |
316 | ||
317 | Consider Y when carry occures: | |
318 | ||
319 | X + Y >= Un, Y < Un | |
320 | ==> (Un - X) <= Y < Un # re-arange | |
321 | ==> Un <= X + Y < Un + X < 2 Un # add Xn | |
322 | ==> 0 <= (X + Y) mod Un < X mod Un | |
323 | ||
324 | or when carry as occured: | |
325 | ||
326 | (X + Y) mod Un < X mod Un | |
327 | ||
328 | Consider Y when carry does not occure: | |
329 | ||
330 | X + Y < Un | |
331 | have X < Un, Y >= 0 | |
332 | ==> X <= X + Y < Un | |
333 | ==> X mod Un <= (X + Y) mod Un | |
334 | ||
335 | or when carry has not occured: | |
336 | ||
337 | ! ( (X + Y) mod Un < X mod Un) | |
338 | ||
339 | ||
340 | ||
341 | Subtraction - Introduction | |
342 | ||
343 | ||
344 | There are two different ways of computing the signed two's | |
345 | complement difference of two numbers. The first is based on | |
346 | negative addition, the second on direct subtraction. | |
347 | ||
348 | ||
349 | ||
350 | Subtraction - Carry - Introduction - Negated Addition | |
351 | ||
352 | ||
353 | The equation X - Y can be computed using: | |
354 | ||
355 | X + (-Y) | |
356 | ==> X + ~Y + 1 # -Y = ~Y + 1 | |
357 | ||
358 | In addition to the result, the equation produces Carry-out. For | |
359 | succeeding extended prrcision calculations, the more general | |
360 | equation can be used: | |
361 | ||
362 | C[p]:R[p] = X[p] + ~Y[p] + C[p-1] | |
363 | where C[0]:R[0] = X[0] + ~Y[0] + 1 | |
364 | ||
365 | ||
366 | ||
367 | Subtraction - Borrow - Introduction - Direct Subtraction | |
368 | ||
369 | ||
370 | The alternative to negative addition is direct subtraction where | |
371 | `X-Y is computed directly. In addition to the result of the | |
372 | calculation, a Borrow bit is produced. In general terms: | |
373 | ||
374 | B[p]:R[p] = X[p] - Y[p] - B[p-1] | |
375 | where B[0]:R[0] = X[0] - Y[0] | |
376 | ||
377 | The Borrow bit is the complement of the Carry bit produced by | |
378 | Negated Addition above. A dodgy proof follows: | |
379 | ||
380 | Case 0: | |
381 | C[0]:R[0] = X[0] + ~Y[0] + 1 | |
382 | ==> C[0]:R[0] = X[0] + 1 - Y[0] + 1 # ~Y[0] = (1 - Y[0])? | |
383 | ==> C[0]:R[0] = 2 + X[0] - Y[0] | |
384 | ==> C[0]:R[0] = 2 + B[0]:R[0] | |
385 | ==> C[0]:R[0] = (1 + B[0]):R[0] | |
386 | ==> C[0] = ~B[0] # (1 + B[0]) mod 2 = ~B[0]? | |
387 | ||
388 | Case P: | |
389 | C[p]:R[p] = X[p] + ~Y[p] + C[p-1] | |
390 | ==> C[p]:R[p] = X[p] + 1 - Y[0] + 1 - B[p-1] | |
391 | ==> C[p]:R[p] = 2 + X[p] - Y[0] - B[p-1] | |
392 | ==> C[p]:R[p] = 2 + B[p]:R[p] | |
393 | ==> C[p]:R[p] = (1 + B[p]):R[p] | |
394 | ==> C[p] = ~B[p] | |
395 | ||
396 | The table below lists all possible inputs/outputs for a | |
397 | full-subtractor: | |
398 | ||
399 | X Y I | R B | |
400 | 0 0 0 | 0 0 | |
401 | 0 0 1 | 1 1 | |
402 | 0 1 0 | 1 1 | |
403 | 0 1 1 | 0 1 | |
404 | 1 0 0 | 1 0 | |
405 | 1 0 1 | 0 0 | |
406 | 1 1 0 | 0 0 | |
407 | 1 1 1 | 1 1 | |
408 | ||
409 | ||
410 | ||
411 | Subtraction - Method 1 | |
412 | ||
413 | ||
414 | Treating Xn and Yn as unsigned values then a borrow (unsigned | |
415 | underflow) occures when: | |
416 | ||
417 | B = Xn < Yn | |
418 | ==> C = Xn >= Yn | |
419 | ||
420 | */ | |
465db791 MM |
421 | |
422 | ||
423 | ||
424 | /* 8 bit target expressions: | |
425 | ||
426 | Since the host's natural bitsize > 8 bits, carry method 2 and | |
427 | overflow method 2 are used. */ | |
428 | ||
429 | #define ALU8_BEGIN(VAL) \ | |
36dbc8bb DE |
430 | unsigned alu8_cr = (unsigned8) (VAL); \ |
431 | signed alu8_vr = (signed8) (alu8_cr) | |
465db791 MM |
432 | |
433 | #define ALU8_SET(VAL) \ | |
434 | alu8_cr = (unsigned8) (VAL); \ | |
435 | alu8_vr = (signed8) (alu8_cr) | |
436 | ||
36dbc8bb | 437 | #define ALU8_SET_CARRY_BORROW(CARRY) \ |
465db791 MM |
438 | do { \ |
439 | if (CARRY) \ | |
440 | alu8_cr |= ((signed)-1) << 8; \ | |
441 | else \ | |
442 | alu8_cr &= 0xff; \ | |
443 | } while (0) | |
36dbc8bb DE |
444 | |
445 | #define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8)) | |
465db791 MM |
446 | #define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1)) |
447 | ||
448 | #define ALU8_RESULT ((unsigned8) alu8_cr) | |
36dbc8bb | 449 | #define ALU8_CARRY_BORROW_RESULT ((unsigned8) alu8_cr) |
465db791 MM |
450 | #define ALU8_OVERFLOW_RESULT ((unsigned8) alu8_vr) |
451 | ||
452 | /* #define ALU8_END ????? - target dependant */ | |
453 | ||
454 | ||
455 | ||
456 | /* 16 bit target expressions: | |
457 | ||
458 | Since the host's natural bitsize > 16 bits, carry method 2 and | |
459 | overflow method 2 are used. */ | |
460 | ||
461 | #define ALU16_BEGIN(VAL) \ | |
462 | signed alu16_cr = (unsigned16) (VAL); \ | |
463 | unsigned alu16_vr = (signed16) (alu16_cr) | |
d6fea803 AC |
464 | |
465 | #define ALU16_SET(VAL) \ | |
465db791 MM |
466 | alu16_cr = (unsigned16) (VAL); \ |
467 | alu16_vr = (signed16) (alu16_cr) | |
468 | ||
36dbc8bb | 469 | #define ALU16_SET_CARRY_BORROW(CARRY) \ |
465db791 MM |
470 | do { \ |
471 | if (CARRY) \ | |
472 | alu16_cr |= ((signed)-1) << 16; \ | |
473 | else \ | |
474 | alu16_cr &= 0xffff; \ | |
d6fea803 AC |
475 | } while (0) |
476 | ||
36dbc8bb | 477 | #define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16)) |
465db791 MM |
478 | #define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1)) |
479 | ||
480 | #define ALU16_RESULT ((unsigned16) alu16_cr) | |
36dbc8bb | 481 | #define ALU16_CARRY_BORROW_RESULT ((unsigned16) alu16_cr) |
465db791 MM |
482 | #define ALU16_OVERFLOW_RESULT ((unsigned16) alu16_vr) |
483 | ||
484 | /* #define ALU16_END ????? - target dependant */ | |
485 | ||
486 | ||
487 | ||
488 | /* 32 bit target expressions: | |
489 | ||
490 | Since most hosts do not support 64 (> 32) bit arrithmetic, carry | |
36dbc8bb | 491 | method 4 and overflow method 4 are used. */ |
465db791 MM |
492 | |
493 | #define ALU32_BEGIN(VAL) \ | |
494 | unsigned32 alu32_r = (VAL); \ | |
495 | int alu32_c = 0; \ | |
496 | int alu32_v = 0 | |
497 | ||
d6fea803 | 498 | #define ALU32_SET(VAL) \ |
465db791 MM |
499 | alu32_r = (VAL); \ |
500 | alu32_c = 0; \ | |
501 | alu32_v = 0 | |
502 | ||
36dbc8bb | 503 | #define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY) |
465db791 | 504 | |
36dbc8bb | 505 | #define ALU32_HAD_CARRY_BORROW (alu32_c) |
465db791 | 506 | #define ALU32_HAD_OVERFLOW (alu32_v) |
465db791 MM |
507 | |
508 | #define ALU32_RESULT (alu32_r) | |
36dbc8bb | 509 | #define ALU32_CARRY_BORROW_RESULT (alu32_r) |
465db791 MM |
510 | #define ALU32_OVERFLOW_RESULT (alu32_r) |
511 | ||
512 | ||
513 | ||
514 | /* 64 bit target expressions: | |
515 | ||
516 | Even though the host typically doesn't support native 64 bit | |
517 | arrithmetic, it is still used. */ | |
518 | ||
519 | #define ALU64_BEGIN(VAL) \ | |
520 | natural64 alu64_r = (VAL); \ | |
521 | int alu64_c = 0; \ | |
522 | int alu64_v = 0 | |
d6fea803 AC |
523 | |
524 | #define ALU64_SET(VAL) \ | |
465db791 MM |
525 | alu64_r = (VAL); \ |
526 | alu64_c = 0; \ | |
527 | alu64_v = 0 | |
528 | ||
36dbc8bb | 529 | #define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY) |
465db791 | 530 | |
36dbc8bb | 531 | #define ALU64_HAD_CARRY_BORROW (alu64_c) |
465db791 MM |
532 | #define ALU64_HAD_OVERFLOW (alu64_v) |
533 | ||
534 | #define ALU64_RESULT (alu64_r) | |
36dbc8bb | 535 | #define ALU64_CARRY_BORROW_RESULT (alu64_r) |
465db791 MM |
536 | #define ALU64_OVERFLOW_RESULT (alu64_r) |
537 | ||
538 | ||
539 | ||
540 | /* Generic versions of above macros */ | |
541 | ||
542 | #define ALU_BEGIN XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_BEGIN) | |
543 | #define ALU_SET XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET) | |
544 | #define ALU_SET_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET_CARRY) | |
545 | ||
546 | #define ALU_HAD_OVERFLOW XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_OVERFLOW) | |
547 | #define ALU_HAD_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_CARRY) | |
548 | ||
549 | #define ALU_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_RESULT) | |
550 | #define ALU_OVERFLOW_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OVERFLOW_RESULT) | |
551 | #define ALU_CARRY_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_CARRY_RESULT) | |
d6fea803 | 552 | |
d6fea803 AC |
553 | |
554 | ||
36dbc8bb | 555 | /* Basic operation - add (overflowing) */ |
d6fea803 | 556 | |
465db791 MM |
557 | #define ALU8_ADD(VAL) \ |
558 | do { \ | |
36dbc8bb DE |
559 | unsigned8 alu8add_val = (VAL); \ |
560 | ALU8_ADDC (alu8add_val); \ | |
d6fea803 AC |
561 | } while (0) |
562 | ||
465db791 MM |
563 | #define ALU16_ADD(VAL) \ |
564 | do { \ | |
36dbc8bb DE |
565 | unsigned16 alu16add_val = (VAL); \ |
566 | ALU16_ADDC (alu8add_val); \ | |
d6fea803 AC |
567 | } while (0) |
568 | ||
465db791 MM |
569 | #define ALU32_ADD(VAL) \ |
570 | do { \ | |
36dbc8bb DE |
571 | unsigned32 alu32add_val = (VAL); \ |
572 | ALU32_ADDC (alu32add_val); \ | |
465db791 MM |
573 | } while (0) |
574 | ||
575 | #define ALU64_ADD(VAL) \ | |
576 | do { \ | |
36dbc8bb DE |
577 | unsigned64 alu64add_val = (unsigned64) (VAL); \ |
578 | ALU64_ADDC (alu64add_val); \ | |
579 | } while (0) | |
580 | ||
581 | #define ALU_ADD XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADD) | |
582 | ||
583 | ||
584 | ||
585 | /* Basic operation - add carrying (and overflowing) */ | |
586 | ||
587 | #define ALU8_ADDC(VAL) \ | |
588 | do { \ | |
589 | unsigned8 alu8addc_val = (VAL); \ | |
590 | alu8_cr += (unsigned8)(alu8addc_val); \ | |
591 | alu8_vr += (signed8)(alu8addc_val); \ | |
592 | } while (0) | |
593 | ||
594 | #define ALU16_ADDC(VAL) \ | |
595 | do { \ | |
596 | unsigned16 alu16addc_val = (VAL); \ | |
597 | alu16_cr += (unsigned16)(alu16addc_val); \ | |
598 | alu16_vr += (signed16)(alu16addc_val); \ | |
d6fea803 AC |
599 | } while (0) |
600 | ||
36dbc8bb DE |
601 | #define ALU32_ADDC(VAL) \ |
602 | do { \ | |
603 | unsigned32 alu32addc_val = (VAL); \ | |
604 | unsigned32 alu32addc_sign = alu32addc_val ^ alu32_r; \ | |
605 | alu32_r += (alu32addc_val); \ | |
606 | alu32_c = (alu32_r < alu32addc_val); \ | |
607 | alu32_v = ((alu32addc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \ | |
608 | } while (0) | |
609 | ||
610 | #define ALU64_ADDC(VAL) \ | |
611 | do { \ | |
612 | unsigned64 alu64addc_val = (unsigned64) (VAL); \ | |
613 | unsigned64 alu64addc_sign = alu64addc_val ^ alu64_r; \ | |
614 | alu64_r += (alu64addc_val); \ | |
615 | alu64_c = (alu64_r < alu64addc_val); \ | |
616 | alu64_v = ((alu64addc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63; \ | |
617 | } while (0) | |
618 | ||
619 | #define ALU_ADDC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC) | |
d6fea803 AC |
620 | |
621 | ||
622 | ||
36dbc8bb DE |
623 | /* Compound operation - add carrying (and overflowing) with carry-in */ |
624 | ||
625 | #define ALU8_ADDC_C(VAL,C) \ | |
465db791 | 626 | do { \ |
36dbc8bb DE |
627 | unsigned8 alu8addcc_val = (VAL); \ |
628 | unsigned8 alu8addcc_c = (C); \ | |
629 | alu8_cr += (unsigned)(unsigned8)alu8addcc_val + alu8addcc_c; \ | |
630 | alu8_vr += (signed)(signed8)(alu8addcc_val) + alu8addcc_c; \ | |
465db791 | 631 | } while (0) |
d6fea803 | 632 | |
36dbc8bb | 633 | #define ALU16_ADDC_C(VAL,C) \ |
465db791 | 634 | do { \ |
36dbc8bb DE |
635 | unsigned16 alu16addcc_val = (VAL); \ |
636 | unsigned16 alu16addcc_c = (C); \ | |
637 | alu16_cr += (unsigned)(unsigned16)alu16addcc_val + alu16addcc_c; \ | |
638 | alu16_vr += (signed)(signed16)(alu16addcc_val) + alu16addcc_c; \ | |
d6fea803 AC |
639 | } while (0) |
640 | ||
36dbc8bb | 641 | #define ALU32_ADDC_C(VAL,C) \ |
465db791 | 642 | do { \ |
36dbc8bb DE |
643 | unsigned32 alu32addcc_val = (VAL); \ |
644 | unsigned32 alu32addcc_c = (C); \ | |
645 | unsigned32 alu32addcc_sign = (alu32addcc_val ^ alu32_r); \ | |
646 | alu32_r += (alu32addcc_val + alu32addcc_c); \ | |
647 | alu32_c = ((alu32_r < alu32addcc_val) \ | |
648 | || (alu32addcc_c && alu32_r == alu32addcc_val)); \ | |
649 | alu32_v = ((alu32addcc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31;\ | |
d6fea803 AC |
650 | } while (0) |
651 | ||
36dbc8bb | 652 | #define ALU64_ADDC_C(VAL,C) \ |
465db791 | 653 | do { \ |
36dbc8bb DE |
654 | unsigned64 alu64addcc_val = (VAL); \ |
655 | unsigned64 alu64addcc_c = (C); \ | |
656 | unsigned64 alu64addcc_sign = (alu64addcc_val ^ alu64_r); \ | |
657 | alu64_r += (alu64addcc_val + alu64addcc_c); \ | |
658 | alu64_c = ((alu64_r < alu64addcc_val) \ | |
659 | || (alu64addcc_c && alu64_r == alu64addcc_val)); \ | |
660 | alu64_v = ((alu64addcc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63;\ | |
d6fea803 AC |
661 | } while (0) |
662 | ||
36dbc8bb | 663 | #define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C) |
d6fea803 AC |
664 | |
665 | ||
666 | ||
36dbc8bb | 667 | /* Basic operation - subtract (overflowing) */ |
d6fea803 | 668 | |
465db791 MM |
669 | #define ALU8_SUB(VAL) \ |
670 | do { \ | |
36dbc8bb DE |
671 | unsigned8 alu8sub_val = (VAL); \ |
672 | ALU8_ADDC_C (~alu8sub_val, 1); \ | |
d6fea803 AC |
673 | } while (0) |
674 | ||
465db791 MM |
675 | #define ALU16_SUB(VAL) \ |
676 | do { \ | |
36dbc8bb DE |
677 | unsigned16 alu16sub_val = (VAL); \ |
678 | ALU16_ADDC_C (~alu16sub_val, 1); \ | |
d6fea803 AC |
679 | } while (0) |
680 | ||
465db791 MM |
681 | #define ALU32_SUB(VAL) \ |
682 | do { \ | |
36dbc8bb DE |
683 | unsigned32 alu32sub_val = (VAL); \ |
684 | ALU32_ADDC_C (~alu32sub_val, 1); \ | |
465db791 MM |
685 | } while (0) |
686 | ||
687 | #define ALU64_SUB(VAL) \ | |
688 | do { \ | |
36dbc8bb DE |
689 | unsigned64 alu64sub_val = (VAL); \ |
690 | ALU64_ADDC_C (~alu64sub_val, 1); \ | |
691 | } while (0) | |
692 | ||
693 | #define ALU_SUB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUB) | |
694 | ||
695 | ||
696 | ||
697 | /* Basic operation - subtract carrying (and overflowing) */ | |
698 | ||
699 | #define ALU8_SUBC(VAL) \ | |
700 | do { \ | |
701 | unsigned8 alu8subc_val = (VAL); \ | |
702 | ALU8_ADDC_C (~alu8subc_val, 1); \ | |
d6fea803 AC |
703 | } while (0) |
704 | ||
36dbc8bb DE |
705 | #define ALU16_SUBC(VAL) \ |
706 | do { \ | |
707 | unsigned16 alu16subc_val = (VAL); \ | |
708 | ALU16_ADDC_C (~alu16subc_val, 1); \ | |
709 | } while (0) | |
d6fea803 | 710 | |
36dbc8bb DE |
711 | #define ALU32_SUBC(VAL) \ |
712 | do { \ | |
713 | unsigned32 alu32subc_val = (VAL); \ | |
714 | ALU32_ADDC_C (~alu32subc_val, 1); \ | |
715 | } while (0) | |
716 | ||
717 | #define ALU64_SUBC(VAL) \ | |
718 | do { \ | |
719 | unsigned64 alu64subc_val = (VAL); \ | |
720 | ALU64_ADDC_C (~alu64subc_val, 1); \ | |
721 | } while (0) | |
d6fea803 | 722 | |
36dbc8bb | 723 | #define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC) |
d6fea803 AC |
724 | |
725 | ||
36dbc8bb DE |
726 | |
727 | /* Compound operation - subtract carrying (and overflowing), extended */ | |
728 | ||
729 | #define ALU8_SUBC_X(VAL,C) \ | |
465db791 | 730 | do { \ |
36dbc8bb DE |
731 | unsigned8 alu8subcx_val = (VAL); \ |
732 | unsigned8 alu8subcx_c = (C); \ | |
733 | ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c); \ | |
d6fea803 AC |
734 | } while (0) |
735 | ||
36dbc8bb | 736 | #define ALU16_SUBC_X(VAL,C) \ |
465db791 | 737 | do { \ |
36dbc8bb DE |
738 | unsigned16 alu16subcx_val = (VAL); \ |
739 | unsigned16 alu16subcx_c = (C); \ | |
740 | ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c); \ | |
d6fea803 AC |
741 | } while (0) |
742 | ||
36dbc8bb | 743 | #define ALU32_SUBC_X(VAL,C) \ |
465db791 | 744 | do { \ |
36dbc8bb DE |
745 | unsigned32 alu32subcx_val = (VAL); \ |
746 | unsigned32 alu32subcx_c = (C); \ | |
747 | ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c); \ | |
d6fea803 AC |
748 | } while (0) |
749 | ||
36dbc8bb DE |
750 | #define ALU64_SUBC_X(VAL,C) \ |
751 | do { \ | |
752 | unsigned64 alu64subcx_val = (VAL); \ | |
753 | unsigned64 alu64subcx_c = (C); \ | |
754 | ALU64_ADDC_C (~alu64subcx_val, alu64subcx_c); \ | |
755 | } while (0) | |
756 | ||
757 | #define ALU_SUBC_X XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC_X) | |
758 | ||
759 | ||
760 | ||
761 | /* Basic operation - subtract borrowing (and overflowing) */ | |
762 | ||
763 | #define ALU8_SUBB(VAL) \ | |
764 | do { \ | |
765 | unsigned8 alu8subb_val = (VAL); \ | |
766 | alu8_cr -= (unsigned)(unsigned8)alu8subb_val; \ | |
767 | alu8_vr -= (signed)(signed8)alu8subb_val; \ | |
768 | } while (0) | |
769 | ||
770 | #define ALU16_SUBB(VAL) \ | |
771 | do { \ | |
772 | unsigned16 alu16subb_val = (VAL); \ | |
773 | alu16_cr -= (unsigned)(unsigned16)alu16subb_val; \ | |
774 | alu16_vr -= (signed)(signed16)alu16subb_val; \ | |
775 | } while (0) | |
776 | ||
777 | #define ALU32_SUBB(VAL) \ | |
778 | do { \ | |
779 | unsigned32 alu32subb_val = (VAL); \ | |
780 | unsigned32 alu32subb_sign = alu32subb_val ^ alu32_r; \ | |
781 | alu32_c = (alu32_r < alu32subb_val); \ | |
782 | alu32_r -= (alu32subb_val); \ | |
783 | alu32_v = ((alu32subb_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \ | |
784 | } while (0) | |
785 | ||
786 | #define ALU64_SUBB(VAL) \ | |
787 | do { \ | |
788 | unsigned64 alu64subb_val = (VAL); \ | |
789 | unsigned64 alu64subb_sign = alu64subb_val ^ alu64_r; \ | |
790 | alu64_c = (alu64_r < alu64subb_val); \ | |
791 | alu64_r -= (alu64subb_val); \ | |
792 | alu64_v = ((alu64subb_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 31; \ | |
793 | } while (0) | |
794 | ||
795 | #define ALU_SUBB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB) | |
796 | ||
797 | ||
798 | ||
799 | /* Compound operation - subtract borrowing (and overflowing) with borrow-in */ | |
800 | ||
801 | #define ALU8_SUBB_B(VAL,B) \ | |
802 | do { \ | |
803 | unsigned8 alu8subbb_val = (VAL); \ | |
804 | unsigned8 alu8subbb_b = (B); \ | |
805 | alu8_cr -= (unsigned)(unsigned8)alu8subbb_val; \ | |
806 | alu8_cr -= (unsigned)(unsigned8)alu8subbb_b; \ | |
807 | alu8_vr -= (signed)(signed8)alu8subbb_val + alu8subbb_b; \ | |
808 | } while (0) | |
809 | ||
810 | #define ALU16_SUBB_B(VAL,B) \ | |
811 | do { \ | |
812 | unsigned16 alu16subbb_val = (VAL); \ | |
813 | unsigned16 alu16subbb_b = (B); \ | |
814 | alu16_cr -= (unsigned)(unsigned16)alu16subbb_val; \ | |
815 | alu16_cr -= (unsigned)(unsigned16)alu16subbb_b; \ | |
816 | alu16_vr -= (signed)(signed16)alu16subbb_val + alu16subbb_b; \ | |
817 | } while (0) | |
818 | ||
819 | #define ALU32_SUBB_B(VAL,B) \ | |
820 | do { \ | |
821 | unsigned32 alu32subbb_val = (VAL); \ | |
822 | unsigned32 alu32subbb_b = (B); \ | |
823 | ALU32_ADDC_C (~alu32subbb_val, !alu32subbb_b); \ | |
824 | alu32_c = !alu32_c; \ | |
825 | } while (0) | |
826 | ||
827 | #define ALU64_SUBB_B(VAL,B) \ | |
828 | do { \ | |
829 | unsigned64 alu64subbb_val = (VAL); \ | |
830 | unsigned64 alu64subbb_b = (B); \ | |
831 | ALU64_ADDC_C (~alu64subbb_val, !alu64subbb_b); \ | |
832 | alu64_c = !alu64_c; \ | |
833 | } while (0) | |
834 | ||
835 | #define ALU_SUBB_B XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB_B) | |
836 | ||
837 | ||
838 | ||
839 | /* Basic operation - negate (overflowing) */ | |
840 | ||
841 | #define ALU8_NEG() \ | |
842 | do { \ | |
843 | signed alu8neg_val = (ALU8_RESULT); \ | |
844 | ALU8_SET (1); \ | |
845 | ALU8_ADDC (~alu8neg_val); \ | |
846 | } while (0) | |
847 | ||
848 | #define ALU16_NEG() \ | |
849 | do { \ | |
850 | signed alu16neg_val = (ALU16_RESULT); \ | |
851 | ALU16_SET (1); \ | |
852 | ALU16_ADDC (~alu16neg_val); \ | |
853 | } while (0) | |
854 | ||
855 | #define ALU32_NEG() \ | |
856 | do { \ | |
857 | unsigned32 alu32neg_val = (ALU32_RESULT); \ | |
858 | ALU32_SET (1); \ | |
859 | ALU32_ADDC (~alu32neg_val); \ | |
860 | } while(0) | |
861 | ||
862 | #define ALU64_NEG() \ | |
465db791 | 863 | do { \ |
36dbc8bb DE |
864 | unsigned64 alu64neg_val = (ALU64_RESULT); \ |
865 | ALU64_SET (1); \ | |
866 | ALU64_ADDC (~alu64neg_val); \ | |
465db791 | 867 | } while (0) |
d6fea803 | 868 | |
36dbc8bb | 869 | #define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG) |
d6fea803 AC |
870 | |
871 | ||
872 | ||
36dbc8bb DE |
873 | |
874 | /* Basic operation - negate carrying (and overflowing) */ | |
875 | ||
876 | #define ALU8_NEGC() \ | |
877 | do { \ | |
878 | signed alu8negc_val = (ALU8_RESULT); \ | |
879 | ALU8_SET (1); \ | |
880 | ALU8_ADDC (~alu8negc_val); \ | |
881 | } while (0) | |
882 | ||
883 | #define ALU16_NEGC() \ | |
884 | do { \ | |
885 | signed alu16negc_val = (ALU16_RESULT); \ | |
886 | ALU16_SET (1); \ | |
887 | ALU16_ADDC (~alu16negc_val); \ | |
888 | } while (0) | |
889 | ||
890 | #define ALU32_NEGC() \ | |
891 | do { \ | |
892 | unsigned32 alu32negc_val = (ALU32_RESULT); \ | |
893 | ALU32_SET (1); \ | |
894 | ALU32_ADDC (~alu32negc_val); \ | |
895 | } while(0) | |
896 | ||
897 | #define ALU64_NEGC() \ | |
898 | do { \ | |
899 | unsigned64 alu64negc_val = (ALU64_RESULT); \ | |
900 | ALU64_SET (1); \ | |
901 | ALU64_ADDC (~alu64negc_val); \ | |
902 | } while (0) | |
903 | ||
904 | #define ALU_NEGC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGC) | |
905 | ||
906 | ||
907 | ||
908 | ||
909 | /* Basic operation - negate borrowing (and overflowing) */ | |
910 | ||
911 | #define ALU8_NEGB() \ | |
912 | do { \ | |
913 | signed alu8negb_val = (ALU8_RESULT); \ | |
914 | ALU8_SET (0); \ | |
915 | ALU8_SUBB (alu8negb_val); \ | |
916 | } while (0) | |
917 | ||
918 | #define ALU16_NEGB() \ | |
919 | do { \ | |
920 | signed alu16negb_val = (ALU16_RESULT); \ | |
921 | ALU16_SET (0); \ | |
922 | ALU16_SUBB (alu16negb_val); \ | |
923 | } while (0) | |
924 | ||
925 | #define ALU32_NEGB() \ | |
926 | do { \ | |
927 | unsigned32 alu32negb_val = (ALU32_RESULT); \ | |
928 | ALU32_SET (0); \ | |
929 | ALU32_SUBB (alu32negb_val); \ | |
930 | } while(0) | |
931 | ||
932 | #define ALU64_NEGB() \ | |
933 | do { \ | |
934 | unsigned64 alu64negb_val = (ALU64_RESULT); \ | |
935 | ALU64_SET (0); \ | |
936 | ALU64_SUBB (alu64negb_val); \ | |
937 | } while (0) | |
938 | ||
939 | #define ALU_NEGB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGB) | |
940 | ||
941 | ||
942 | ||
943 | ||
944 | /* Other */ | |
945 | ||
946 | #define ALU8_OR(VAL) \ | |
947 | do { \ | |
948 | error("ALU16_OR"); \ | |
949 | } while (0) | |
950 | ||
465db791 MM |
951 | #define ALU16_OR(VAL) \ |
952 | do { \ | |
953 | error("ALU16_OR"); \ | |
d6fea803 AC |
954 | } while (0) |
955 | ||
465db791 MM |
956 | #define ALU32_OR(VAL) \ |
957 | do { \ | |
958 | alu32_r |= (VAL); \ | |
959 | alu32_c = 0; \ | |
960 | alu32_v = 0; \ | |
d6fea803 AC |
961 | } while (0) |
962 | ||
465db791 MM |
963 | #define ALU64_OR(VAL) \ |
964 | do { \ | |
965 | alu64_r |= (VAL); \ | |
966 | alu64_c = 0; \ | |
967 | alu64_v = 0; \ | |
d6fea803 AC |
968 | } while (0) |
969 | ||
970 | #define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL) | |
971 | ||
972 | ||
973 | ||
465db791 MM |
974 | #define ALU16_XOR(VAL) \ |
975 | do { \ | |
976 | error("ALU16_XOR"); \ | |
d6fea803 AC |
977 | } while (0) |
978 | ||
465db791 MM |
979 | #define ALU32_XOR(VAL) \ |
980 | do { \ | |
981 | alu32_r ^= (VAL); \ | |
982 | alu32_c = 0; \ | |
983 | alu32_v = 0; \ | |
d6fea803 AC |
984 | } while (0) |
985 | ||
465db791 MM |
986 | #define ALU64_XOR(VAL) \ |
987 | do { \ | |
988 | alu64_r ^= (VAL); \ | |
989 | alu64_c = 0; \ | |
990 | alu64_v = 0; \ | |
d6fea803 AC |
991 | } while (0) |
992 | ||
993 | #define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL) | |
994 | ||
995 | ||
996 | ||
997 | ||
465db791 MM |
998 | #define ALU16_AND(VAL) \ |
999 | do { \ | |
1000 | error("ALU_AND16"); \ | |
d6fea803 AC |
1001 | } while (0) |
1002 | ||
465db791 MM |
1003 | #define ALU32_AND(VAL) \ |
1004 | do { \ | |
1005 | alu32_r &= (VAL); \ | |
1006 | alu32_r = 0; \ | |
1007 | alu32_v = 0; \ | |
d6fea803 AC |
1008 | } while (0) |
1009 | ||
465db791 MM |
1010 | #define ALU64_AND(VAL) \ |
1011 | do { \ | |
1012 | alu64_r &= (VAL); \ | |
1013 | alu64_r = 0; \ | |
1014 | alu64_v = 0; \ | |
d6fea803 AC |
1015 | } while (0) |
1016 | ||
1017 | #define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL) | |
1018 | ||
1019 | ||
1020 | ||
1021 | ||
465db791 MM |
1022 | #define ALU16_NOT(VAL) \ |
1023 | do { \ | |
1024 | error("ALU_NOT16"); \ | |
d6fea803 AC |
1025 | } while (0) |
1026 | ||
465db791 MM |
1027 | #define ALU32_NOT \ |
1028 | do { \ | |
1029 | alu32_r = ~alu32_r; \ | |
1030 | alu32_c = 0; \ | |
1031 | alu32_v = 0; \ | |
d6fea803 AC |
1032 | } while (0) |
1033 | ||
465db791 MM |
1034 | #define ALU64_NOT \ |
1035 | do { \ | |
1036 | alu64_r = ~alu64_r; \ | |
1037 | alu64_c = 0; \ | |
1038 | alu64_v = 0; \ | |
d6fea803 AC |
1039 | } while (0) |
1040 | ||
1041 | #define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT) | |
1042 | ||
d6fea803 | 1043 | #endif |