]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/sim-alu.h
Initial creation of sourceware repository
[thirdparty/binutils-gdb.git] / sim / common / sim-alu.h
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
26 #include "symcat.h"
27
28
29 /* INTEGER ALU MODULE:
30
31 This module provides an implementation of 2's complement arithmetic
32 including the recording of carry and overflow status bits.
33
34
35 EXAMPLE:
36
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:
40
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
46
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:
191
192
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
197 Rm = (SEXTn (Xn) + SEXTn (Yn))
198 V = MSBn ((Rm >> (M - N)) ^ Rm)
199
200
201
202 Addition - Overflow - method 3:
203
204
205 The two N bit operands are sign extended to M>N bits and then
206 added. Overflow occures when the result is outside of the sign
207 extended range [MINn .. MAXn].
208
209
210
211 Addition - Overflow - method 4:
212
213
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)
219
220 As shown in the table below:
221
222 I X Y R C | V | X^Y ^R ^C
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
235 Addition - Carry - Introduction:
236
237
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.
241
242 The following table lists the output for all given inputs into a
243 full-adder.
244
245 I X Y R | C
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
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.
264
265 XY\R 0 1
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
274 MSBn ((Xn & Yn) | (Xn & ~Rn) | (Yn & ~Rn))
275
276 Verifying:
277
278 I X Y R | C | X&Y X&~R Y&~R
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
291 Addition - Carry - method 2:
292
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
299
300
301 Addition - Carry - method 3:
302
303
304 Given the oVerflow bit. The carry can be computed from:
305
306 (~R&V) | (R&V)
307
308
309
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 hence we get carry by computing in N bit unsigned arrithmetic.
340
341 carry <- (Xn + Yn) < Xn
342
343
344
345 Subtraction - Introduction
346
347
348 There are two different ways of computing the signed two's
349 complement difference of two numbers. The first is based on
350 negative addition, the second on direct subtraction.
351
352
353
354 Subtraction - Carry - Introduction - Negated Addition
355
356
357 The equation X - Y can be computed using:
358
359 X + (-Y)
360 ==> X + ~Y + 1 # -Y = ~Y + 1
361
362 In addition to the result, the equation produces Carry-out. For
363 succeeding extended prrcision calculations, the more general
364 equation can be used:
365
366 C[p]:R[p] = X[p] + ~Y[p] + C[p-1]
367 where C[0]:R[0] = X[0] + ~Y[0] + 1
368
369
370
371 Subtraction - Borrow - Introduction - Direct Subtraction
372
373
374 The alternative to negative addition is direct subtraction where
375 `X-Y is computed directly. In addition to the result of the
376 calculation, a Borrow bit is produced. In general terms:
377
378 B[p]:R[p] = X[p] - Y[p] - B[p-1]
379 where B[0]:R[0] = X[0] - Y[0]
380
381 The Borrow bit is the complement of the Carry bit produced by
382 Negated Addition above. A dodgy proof follows:
383
384 Case 0:
385 C[0]:R[0] = X[0] + ~Y[0] + 1
386 ==> C[0]:R[0] = X[0] + 1 - Y[0] + 1 # ~Y[0] = (1 - Y[0])?
387 ==> C[0]:R[0] = 2 + X[0] - Y[0]
388 ==> C[0]:R[0] = 2 + B[0]:R[0]
389 ==> C[0]:R[0] = (1 + B[0]):R[0]
390 ==> C[0] = ~B[0] # (1 + B[0]) mod 2 = ~B[0]?
391
392 Case P:
393 C[p]:R[p] = X[p] + ~Y[p] + C[p-1]
394 ==> C[p]:R[p] = X[p] + 1 - Y[0] + 1 - B[p-1]
395 ==> C[p]:R[p] = 2 + X[p] - Y[0] - B[p-1]
396 ==> C[p]:R[p] = 2 + B[p]:R[p]
397 ==> C[p]:R[p] = (1 + B[p]):R[p]
398 ==> C[p] = ~B[p]
399
400 The table below lists all possible inputs/outputs for a
401 full-subtractor:
402
403 X Y I | R B
404 0 0 0 | 0 0
405 0 0 1 | 1 1
406 0 1 0 | 1 1
407 0 1 1 | 0 1
408 1 0 0 | 1 0
409 1 0 1 | 0 0
410 1 1 0 | 0 0
411 1 1 1 | 1 1
412
413
414
415 Subtraction - Method 1
416
417
418 Treating Xn and Yn as unsigned values then a borrow (unsigned
419 underflow) occures when:
420
421 B = Xn < Yn
422 ==> C = Xn >= Yn
423
424 */
425
426
427
428 /* 8 bit target expressions:
429
430 Since the host's natural bitsize > 8 bits, carry method 2 and
431 overflow method 2 are used. */
432
433 #define ALU8_BEGIN(VAL) \
434 unsigned alu8_cr = (unsigned8) (VAL); \
435 signed alu8_vr = (signed8) (alu8_cr)
436
437 #define ALU8_SET(VAL) \
438 alu8_cr = (unsigned8) (VAL); \
439 alu8_vr = (signed8) (alu8_cr)
440
441 #define ALU8_SET_CARRY_BORROW(CARRY) \
442 do { \
443 if (CARRY) \
444 alu8_cr |= ((signed)-1) << 8; \
445 else \
446 alu8_cr &= 0xff; \
447 } while (0)
448
449 #define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8))
450 #define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1))
451
452 #define ALU8_RESULT ((unsigned8) alu8_cr)
453 #define ALU8_CARRY_BORROW_RESULT ((unsigned8) alu8_cr)
454 #define ALU8_OVERFLOW_RESULT ((unsigned8) alu8_vr)
455
456 /* #define ALU8_END ????? - target dependant */
457
458
459
460 /* 16 bit target expressions:
461
462 Since the host's natural bitsize > 16 bits, carry method 2 and
463 overflow method 2 are used. */
464
465 #define ALU16_BEGIN(VAL) \
466 signed alu16_cr = (unsigned16) (VAL); \
467 unsigned alu16_vr = (signed16) (alu16_cr)
468
469 #define ALU16_SET(VAL) \
470 alu16_cr = (unsigned16) (VAL); \
471 alu16_vr = (signed16) (alu16_cr)
472
473 #define ALU16_SET_CARRY_BORROW(CARRY) \
474 do { \
475 if (CARRY) \
476 alu16_cr |= ((signed)-1) << 16; \
477 else \
478 alu16_cr &= 0xffff; \
479 } while (0)
480
481 #define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16))
482 #define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1))
483
484 #define ALU16_RESULT ((unsigned16) alu16_cr)
485 #define ALU16_CARRY_BORROW_RESULT ((unsigned16) alu16_cr)
486 #define ALU16_OVERFLOW_RESULT ((unsigned16) alu16_vr)
487
488 /* #define ALU16_END ????? - target dependant */
489
490
491
492 /* 32 bit target expressions:
493
494 Since most hosts do not support 64 (> 32) bit arrithmetic, carry
495 method 4 and overflow method 4 are used. */
496
497 #define ALU32_BEGIN(VAL) \
498 unsigned32 alu32_r = (VAL); \
499 int alu32_c = 0; \
500 int alu32_v = 0
501
502 #define ALU32_SET(VAL) \
503 alu32_r = (VAL); \
504 alu32_c = 0; \
505 alu32_v = 0
506
507 #define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY)
508
509 #define ALU32_HAD_CARRY_BORROW (alu32_c)
510 #define ALU32_HAD_OVERFLOW (alu32_v)
511
512 #define ALU32_RESULT (alu32_r)
513 #define ALU32_CARRY_BORROW_RESULT (alu32_r)
514 #define ALU32_OVERFLOW_RESULT (alu32_r)
515
516
517
518 /* 64 bit target expressions:
519
520 Even though the host typically doesn't support native 64 bit
521 arrithmetic, it is still used. */
522
523 #define ALU64_BEGIN(VAL) \
524 unsigned64 alu64_r = (VAL); \
525 int alu64_c = 0; \
526 int alu64_v = 0
527
528 #define ALU64_SET(VAL) \
529 alu64_r = (VAL); \
530 alu64_c = 0; \
531 alu64_v = 0
532
533 #define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY)
534
535 #define ALU64_HAD_CARRY_BORROW (alu64_c)
536 #define ALU64_HAD_OVERFLOW (alu64_v)
537
538 #define ALU64_RESULT (alu64_r)
539 #define ALU64_CARRY_BORROW_RESULT (alu64_r)
540 #define ALU64_OVERFLOW_RESULT (alu64_r)
541
542
543
544 /* Generic versions of above macros */
545
546 #define ALU_BEGIN XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_BEGIN)
547 #define ALU_SET XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET)
548 #define ALU_SET_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET_CARRY)
549
550 #define ALU_HAD_OVERFLOW XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_OVERFLOW)
551 #define ALU_HAD_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_CARRY)
552
553 #define ALU_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_RESULT)
554 #define ALU_OVERFLOW_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OVERFLOW_RESULT)
555 #define ALU_CARRY_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_CARRY_RESULT)
556
557
558
559 /* Basic operation - add (overflowing) */
560
561 #define ALU8_ADD(VAL) \
562 do { \
563 unsigned8 alu8add_val = (VAL); \
564 ALU8_ADDC (alu8add_val); \
565 } while (0)
566
567 #define ALU16_ADD(VAL) \
568 do { \
569 unsigned16 alu16add_val = (VAL); \
570 ALU16_ADDC (alu8add_val); \
571 } while (0)
572
573 #define ALU32_ADD(VAL) \
574 do { \
575 unsigned32 alu32add_val = (VAL); \
576 ALU32_ADDC (alu32add_val); \
577 } while (0)
578
579 #define ALU64_ADD(VAL) \
580 do { \
581 unsigned64 alu64add_val = (unsigned64) (VAL); \
582 ALU64_ADDC (alu64add_val); \
583 } while (0)
584
585 #define ALU_ADD XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADD)
586
587
588
589 /* Basic operation - add carrying (and overflowing) */
590
591 #define ALU8_ADDC(VAL) \
592 do { \
593 unsigned8 alu8addc_val = (VAL); \
594 alu8_cr += (unsigned8)(alu8addc_val); \
595 alu8_vr += (signed8)(alu8addc_val); \
596 } while (0)
597
598 #define ALU16_ADDC(VAL) \
599 do { \
600 unsigned16 alu16addc_val = (VAL); \
601 alu16_cr += (unsigned16)(alu16addc_val); \
602 alu16_vr += (signed16)(alu16addc_val); \
603 } while (0)
604
605 #define ALU32_ADDC(VAL) \
606 do { \
607 unsigned32 alu32addc_val = (VAL); \
608 unsigned32 alu32addc_sign = alu32addc_val ^ alu32_r; \
609 alu32_r += (alu32addc_val); \
610 alu32_c = (alu32_r < alu32addc_val); \
611 alu32_v = ((alu32addc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \
612 } while (0)
613
614 #define ALU64_ADDC(VAL) \
615 do { \
616 unsigned64 alu64addc_val = (unsigned64) (VAL); \
617 unsigned64 alu64addc_sign = alu64addc_val ^ alu64_r; \
618 alu64_r += (alu64addc_val); \
619 alu64_c = (alu64_r < alu64addc_val); \
620 alu64_v = ((alu64addc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63; \
621 } while (0)
622
623 #define ALU_ADDC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC)
624
625
626
627 /* Compound operation - add carrying (and overflowing) with carry-in */
628
629 #define ALU8_ADDC_C(VAL,C) \
630 do { \
631 unsigned8 alu8addcc_val = (VAL); \
632 unsigned8 alu8addcc_c = (C); \
633 alu8_cr += (unsigned)(unsigned8)alu8addcc_val + alu8addcc_c; \
634 alu8_vr += (signed)(signed8)(alu8addcc_val) + alu8addcc_c; \
635 } while (0)
636
637 #define ALU16_ADDC_C(VAL,C) \
638 do { \
639 unsigned16 alu16addcc_val = (VAL); \
640 unsigned16 alu16addcc_c = (C); \
641 alu16_cr += (unsigned)(unsigned16)alu16addcc_val + alu16addcc_c; \
642 alu16_vr += (signed)(signed16)(alu16addcc_val) + alu16addcc_c; \
643 } while (0)
644
645 #define ALU32_ADDC_C(VAL,C) \
646 do { \
647 unsigned32 alu32addcc_val = (VAL); \
648 unsigned32 alu32addcc_c = (C); \
649 unsigned32 alu32addcc_sign = (alu32addcc_val ^ alu32_r); \
650 alu32_r += (alu32addcc_val + alu32addcc_c); \
651 alu32_c = ((alu32_r < alu32addcc_val) \
652 || (alu32addcc_c && alu32_r == alu32addcc_val)); \
653 alu32_v = ((alu32addcc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31;\
654 } while (0)
655
656 #define ALU64_ADDC_C(VAL,C) \
657 do { \
658 unsigned64 alu64addcc_val = (VAL); \
659 unsigned64 alu64addcc_c = (C); \
660 unsigned64 alu64addcc_sign = (alu64addcc_val ^ alu64_r); \
661 alu64_r += (alu64addcc_val + alu64addcc_c); \
662 alu64_c = ((alu64_r < alu64addcc_val) \
663 || (alu64addcc_c && alu64_r == alu64addcc_val)); \
664 alu64_v = ((alu64addcc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63;\
665 } while (0)
666
667 #define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C)
668
669
670
671 /* Basic operation - subtract (overflowing) */
672
673 #define ALU8_SUB(VAL) \
674 do { \
675 unsigned8 alu8sub_val = (VAL); \
676 ALU8_ADDC_C (~alu8sub_val, 1); \
677 } while (0)
678
679 #define ALU16_SUB(VAL) \
680 do { \
681 unsigned16 alu16sub_val = (VAL); \
682 ALU16_ADDC_C (~alu16sub_val, 1); \
683 } while (0)
684
685 #define ALU32_SUB(VAL) \
686 do { \
687 unsigned32 alu32sub_val = (VAL); \
688 ALU32_ADDC_C (~alu32sub_val, 1); \
689 } while (0)
690
691 #define ALU64_SUB(VAL) \
692 do { \
693 unsigned64 alu64sub_val = (VAL); \
694 ALU64_ADDC_C (~alu64sub_val, 1); \
695 } while (0)
696
697 #define ALU_SUB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUB)
698
699
700
701 /* Basic operation - subtract carrying (and overflowing) */
702
703 #define ALU8_SUBC(VAL) \
704 do { \
705 unsigned8 alu8subc_val = (VAL); \
706 ALU8_ADDC_C (~alu8subc_val, 1); \
707 } while (0)
708
709 #define ALU16_SUBC(VAL) \
710 do { \
711 unsigned16 alu16subc_val = (VAL); \
712 ALU16_ADDC_C (~alu16subc_val, 1); \
713 } while (0)
714
715 #define ALU32_SUBC(VAL) \
716 do { \
717 unsigned32 alu32subc_val = (VAL); \
718 ALU32_ADDC_C (~alu32subc_val, 1); \
719 } while (0)
720
721 #define ALU64_SUBC(VAL) \
722 do { \
723 unsigned64 alu64subc_val = (VAL); \
724 ALU64_ADDC_C (~alu64subc_val, 1); \
725 } while (0)
726
727 #define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC)
728
729
730
731 /* Compound operation - subtract carrying (and overflowing), extended */
732
733 #define ALU8_SUBC_X(VAL,C) \
734 do { \
735 unsigned8 alu8subcx_val = (VAL); \
736 unsigned8 alu8subcx_c = (C); \
737 ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c); \
738 } while (0)
739
740 #define ALU16_SUBC_X(VAL,C) \
741 do { \
742 unsigned16 alu16subcx_val = (VAL); \
743 unsigned16 alu16subcx_c = (C); \
744 ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c); \
745 } while (0)
746
747 #define ALU32_SUBC_X(VAL,C) \
748 do { \
749 unsigned32 alu32subcx_val = (VAL); \
750 unsigned32 alu32subcx_c = (C); \
751 ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c); \
752 } while (0)
753
754 #define ALU64_SUBC_X(VAL,C) \
755 do { \
756 unsigned64 alu64subcx_val = (VAL); \
757 unsigned64 alu64subcx_c = (C); \
758 ALU64_ADDC_C (~alu64subcx_val, alu64subcx_c); \
759 } while (0)
760
761 #define ALU_SUBC_X XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC_X)
762
763
764
765 /* Basic operation - subtract borrowing (and overflowing) */
766
767 #define ALU8_SUBB(VAL) \
768 do { \
769 unsigned8 alu8subb_val = (VAL); \
770 alu8_cr -= (unsigned)(unsigned8)alu8subb_val; \
771 alu8_vr -= (signed)(signed8)alu8subb_val; \
772 } while (0)
773
774 #define ALU16_SUBB(VAL) \
775 do { \
776 unsigned16 alu16subb_val = (VAL); \
777 alu16_cr -= (unsigned)(unsigned16)alu16subb_val; \
778 alu16_vr -= (signed)(signed16)alu16subb_val; \
779 } while (0)
780
781 #define ALU32_SUBB(VAL) \
782 do { \
783 unsigned32 alu32subb_val = (VAL); \
784 unsigned32 alu32subb_sign = alu32subb_val ^ alu32_r; \
785 alu32_c = (alu32_r < alu32subb_val); \
786 alu32_r -= (alu32subb_val); \
787 alu32_v = ((alu32subb_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \
788 } while (0)
789
790 #define ALU64_SUBB(VAL) \
791 do { \
792 unsigned64 alu64subb_val = (VAL); \
793 unsigned64 alu64subb_sign = alu64subb_val ^ alu64_r; \
794 alu64_c = (alu64_r < alu64subb_val); \
795 alu64_r -= (alu64subb_val); \
796 alu64_v = ((alu64subb_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 31; \
797 } while (0)
798
799 #define ALU_SUBB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB)
800
801
802
803 /* Compound operation - subtract borrowing (and overflowing) with borrow-in */
804
805 #define ALU8_SUBB_B(VAL,B) \
806 do { \
807 unsigned8 alu8subbb_val = (VAL); \
808 unsigned8 alu8subbb_b = (B); \
809 alu8_cr -= (unsigned)(unsigned8)alu8subbb_val; \
810 alu8_cr -= (unsigned)(unsigned8)alu8subbb_b; \
811 alu8_vr -= (signed)(signed8)alu8subbb_val + alu8subbb_b; \
812 } while (0)
813
814 #define ALU16_SUBB_B(VAL,B) \
815 do { \
816 unsigned16 alu16subbb_val = (VAL); \
817 unsigned16 alu16subbb_b = (B); \
818 alu16_cr -= (unsigned)(unsigned16)alu16subbb_val; \
819 alu16_cr -= (unsigned)(unsigned16)alu16subbb_b; \
820 alu16_vr -= (signed)(signed16)alu16subbb_val + alu16subbb_b; \
821 } while (0)
822
823 #define ALU32_SUBB_B(VAL,B) \
824 do { \
825 unsigned32 alu32subbb_val = (VAL); \
826 unsigned32 alu32subbb_b = (B); \
827 ALU32_ADDC_C (~alu32subbb_val, !alu32subbb_b); \
828 alu32_c = !alu32_c; \
829 } while (0)
830
831 #define ALU64_SUBB_B(VAL,B) \
832 do { \
833 unsigned64 alu64subbb_val = (VAL); \
834 unsigned64 alu64subbb_b = (B); \
835 ALU64_ADDC_C (~alu64subbb_val, !alu64subbb_b); \
836 alu64_c = !alu64_c; \
837 } while (0)
838
839 #define ALU_SUBB_B XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB_B)
840
841
842
843 /* Basic operation - negate (overflowing) */
844
845 #define ALU8_NEG() \
846 do { \
847 signed alu8neg_val = (ALU8_RESULT); \
848 ALU8_SET (1); \
849 ALU8_ADDC (~alu8neg_val); \
850 } while (0)
851
852 #define ALU16_NEG() \
853 do { \
854 signed alu16neg_val = (ALU16_RESULT); \
855 ALU16_SET (1); \
856 ALU16_ADDC (~alu16neg_val); \
857 } while (0)
858
859 #define ALU32_NEG() \
860 do { \
861 unsigned32 alu32neg_val = (ALU32_RESULT); \
862 ALU32_SET (1); \
863 ALU32_ADDC (~alu32neg_val); \
864 } while(0)
865
866 #define ALU64_NEG() \
867 do { \
868 unsigned64 alu64neg_val = (ALU64_RESULT); \
869 ALU64_SET (1); \
870 ALU64_ADDC (~alu64neg_val); \
871 } while (0)
872
873 #define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG)
874
875
876
877
878 /* Basic operation - negate carrying (and overflowing) */
879
880 #define ALU8_NEGC() \
881 do { \
882 signed alu8negc_val = (ALU8_RESULT); \
883 ALU8_SET (1); \
884 ALU8_ADDC (~alu8negc_val); \
885 } while (0)
886
887 #define ALU16_NEGC() \
888 do { \
889 signed alu16negc_val = (ALU16_RESULT); \
890 ALU16_SET (1); \
891 ALU16_ADDC (~alu16negc_val); \
892 } while (0)
893
894 #define ALU32_NEGC() \
895 do { \
896 unsigned32 alu32negc_val = (ALU32_RESULT); \
897 ALU32_SET (1); \
898 ALU32_ADDC (~alu32negc_val); \
899 } while(0)
900
901 #define ALU64_NEGC() \
902 do { \
903 unsigned64 alu64negc_val = (ALU64_RESULT); \
904 ALU64_SET (1); \
905 ALU64_ADDC (~alu64negc_val); \
906 } while (0)
907
908 #define ALU_NEGC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGC)
909
910
911
912
913 /* Basic operation - negate borrowing (and overflowing) */
914
915 #define ALU8_NEGB() \
916 do { \
917 signed alu8negb_val = (ALU8_RESULT); \
918 ALU8_SET (0); \
919 ALU8_SUBB (alu8negb_val); \
920 } while (0)
921
922 #define ALU16_NEGB() \
923 do { \
924 signed alu16negb_val = (ALU16_RESULT); \
925 ALU16_SET (0); \
926 ALU16_SUBB (alu16negb_val); \
927 } while (0)
928
929 #define ALU32_NEGB() \
930 do { \
931 unsigned32 alu32negb_val = (ALU32_RESULT); \
932 ALU32_SET (0); \
933 ALU32_SUBB (alu32negb_val); \
934 } while(0)
935
936 #define ALU64_NEGB() \
937 do { \
938 unsigned64 alu64negb_val = (ALU64_RESULT); \
939 ALU64_SET (0); \
940 ALU64_SUBB (alu64negb_val); \
941 } while (0)
942
943 #define ALU_NEGB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGB)
944
945
946
947
948 /* Other */
949
950 #define ALU8_OR(VAL) \
951 do { \
952 error("ALU16_OR"); \
953 } while (0)
954
955 #define ALU16_OR(VAL) \
956 do { \
957 error("ALU16_OR"); \
958 } while (0)
959
960 #define ALU32_OR(VAL) \
961 do { \
962 alu32_r |= (VAL); \
963 alu32_c = 0; \
964 alu32_v = 0; \
965 } while (0)
966
967 #define ALU64_OR(VAL) \
968 do { \
969 alu64_r |= (VAL); \
970 alu64_c = 0; \
971 alu64_v = 0; \
972 } while (0)
973
974 #define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL)
975
976
977
978 #define ALU16_XOR(VAL) \
979 do { \
980 error("ALU16_XOR"); \
981 } while (0)
982
983 #define ALU32_XOR(VAL) \
984 do { \
985 alu32_r ^= (VAL); \
986 alu32_c = 0; \
987 alu32_v = 0; \
988 } while (0)
989
990 #define ALU64_XOR(VAL) \
991 do { \
992 alu64_r ^= (VAL); \
993 alu64_c = 0; \
994 alu64_v = 0; \
995 } while (0)
996
997 #define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL)
998
999
1000
1001
1002 #define ALU16_AND(VAL) \
1003 do { \
1004 error("ALU_AND16"); \
1005 } while (0)
1006
1007 #define ALU32_AND(VAL) \
1008 do { \
1009 alu32_r &= (VAL); \
1010 alu32_r = 0; \
1011 alu32_v = 0; \
1012 } while (0)
1013
1014 #define ALU64_AND(VAL) \
1015 do { \
1016 alu64_r &= (VAL); \
1017 alu64_r = 0; \
1018 alu64_v = 0; \
1019 } while (0)
1020
1021 #define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL)
1022
1023
1024
1025
1026 #define ALU16_NOT(VAL) \
1027 do { \
1028 error("ALU_NOT16"); \
1029 } while (0)
1030
1031 #define ALU32_NOT \
1032 do { \
1033 alu32_r = ~alu32_r; \
1034 alu32_c = 0; \
1035 alu32_v = 0; \
1036 } while (0)
1037
1038 #define ALU64_NOT \
1039 do { \
1040 alu64_r = ~alu64_r; \
1041 alu64_c = 0; \
1042 alu64_v = 0; \
1043 } while (0)
1044
1045 #define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT)
1046
1047 #endif