1 /* The common simulator framework for GDB, the GNU Debugger.
3 Copyright 2002-2024 Free Software Foundation, Inc.
5 Contributed by Andrew Cagney and Red Hat.
7 This file is part of GDB.
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>. */
29 /* INTEGER ALU MODULE:
31 This module provides an implementation of 2's complement arithmetic
32 including the recording of carry and overflow status bits.
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 arithmetic performed. Ex:
42 #define ALU32_END(RES) \
43 (RES) = ALU32_OVERFLOW_RESULT; \
44 carry = ALU32_HAD_CARRY_BORROW; \
45 overflow = ALU32_HAD_OVERFLOW
47 The macro's are then used vis:
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_*
64 ALU*_BEGIN(ACC): Declare initialize the ALU accumulator with ACC.
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.
73 ALU*_RESULT: Generic ALU result output.
75 ALU*_HAD_OVERFLOW: Returns a nonzero value if signed overflow
78 ALU*_OVERFLOW_RESULT: If the macro ALU*_HAD_OVERFLOW is being
79 used this is the most efficient result available. Ex:
81 #define ALU16_END(RES) \
82 if (ALU16_HAD_OVERFLOW) \
83 sim_engine_halt (...); \
84 (RES) = ALU16_OVERFLOW_RESULT
86 ALU*_HAD_CARRY_BORROW: Returns a nonzero value if unsigned
87 overflow or underflow (also referred to as carry and borrow)
90 ALU*_CARRY_BORROW_RESULT: If the macro ALU*_HAD_CARRY_BORROW is being
91 used this is the most efficient result available. Ex:
93 #define ALU64_END(RES) \
94 State.carry = ALU64_HAD_CARRY_BORROW; \
95 (RES) = ALU64_CARRY_BORROW_RESULT
100 ALU*_ADD(VAL): Add VAL to the ALU accumulator. Record any
101 overflow as well as the final result.
103 ALU*_ADDC(VAL): Add VAL to the ALU accumulator. Record any
104 carry-out or overflow as well as the final result.
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.
111 ALU*_SUB(VAL): Subtract VAL from the ALU accumulator. Record
112 any underflow as well as the final result.
114 ALU*_SUBC(VAL): Subtract VAL from the ALU accumulator using
115 negated addition. Record any underflow or carry-out as well
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.
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.
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.
135 /* Twos complement arithmetic - addition/subtraction - carry/borrow
136 (or you thought you knew the answer to 0-0)
140 Notation and Properties:
143 Xn denotes the value X stored in N bits.
145 MSBn (X): The most significant (sign) bit of X treated as an N bit
148 SEXTn (X): The infinite sign extension of X treated as an N bit
151 MAXn, MINn: The upper and lower bound of a signed, two's
152 complement N bit value.
154 UMAXn: The upper bound of an unsigned N bit value (the lower
155 bound is always zero).
157 Un: UMAXn + 1. Unsigned arithmetic is computed `modulo (Un)'.
159 X[p]: Is bit P of X. X[0] denotes the least significant bit.
161 ~X[p]: Is the inversion of bit X[p]. Also equal to 1-X[p],
166 Addition - Overflow - Introduction:
169 Overflow/Overflow indicates an error in computation of signed
170 arithmetic. i.e. given X,Y in [MINn..MAXn]; overflow
171 indicates that the result X+Y > MAXn or X+Y < MIN_INTx.
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.
179 Addition - Overflow - method 1:
182 Overflow occurs when the sign (most significant bit) of the two N
183 bit operands is identical but different to the sign of the result:
186 V = MSBn (~(Xn ^ Yn) & (Rn ^ Xn))
190 Addition - Overflow - method 2:
193 The two N bit operands are sign extended to M>N bits and then
194 added. Overflow occurs when SIGN_BIT<n> and SIGN_BIT<m> do not
197 Rm = (SEXTn (Xn) + SEXTn (Yn))
198 V = MSBn ((Rm >> (M - N)) ^ Rm)
202 Addition - Overflow - method 3:
205 The two N bit operands are sign extended to M>N bits and then
206 added. Overflow occurs when the result is outside of the sign
207 extended range [MINn .. MAXn].
211 Addition - Overflow - method 4:
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:
218 V = (MSBn ((Xn ^ Yn) ^ Rn)) ^ C)
220 As shown in the table below:
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
235 Addition - Carry - Introduction:
238 Carry (poorly named) indicates that an overflow occurred 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.
242 The following table lists the output for all given inputs into a
256 (carry-In, X, Y, Result, Carry-out):
260 Addition - Carry - method 1:
263 Looking at the terms X, Y and R we want an equation for C.
272 This giving us the sum-of-prod equation:
274 MSBn ((Xn & Yn) | (Xn & ~Rn) | (Yn & ~Rn))
278 I X Y R | C | X&Y X&~R Y&~R
279 ------------+---+---------------
291 Addition - Carry - method 2:
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 arithmetic. Carry is indicated by bit (1 << N) being set (result
301 Addition - Carry - method 3:
304 Given the oVerflow bit. The carry can be computed from:
310 Addition - Carry - method 4:
312 Given two signed numbers. Treating them as unsigned we have:
314 0 <= X < Un, 0 <= Y < Un
317 Consider Y when carry occurs:
320 ==> (Un - X) <= Y < Un # rearrange
321 ==> Un <= X + Y < Un + X < 2 Un # add Xn
322 ==> 0 <= (X + Y) mod Un < X mod Un
324 or when carry as occurred:
326 (X + Y) mod Un < X mod Un
328 Consider Y when carry does not occur:
333 ==> X mod Un <= (X + Y) mod Un
335 or when carry has not occurred:
337 ! ( (X + Y) mod Un < X mod Un)
339 hence we get carry by computing in N bit unsigned arithmetic.
341 carry <- (Xn + Yn) < Xn
345 Subtraction - Introduction
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.
354 Subtraction - Carry - Introduction - Negated Addition
357 The equation X - Y can be computed using:
360 ==> X + ~Y + 1 # -Y = ~Y + 1
362 In addition to the result, the equation produces Carry-out. For
363 succeeding extended precision calculations, the more general
364 equation can be used:
366 C[p]:R[p] = X[p] + ~Y[p] + C[p-1]
367 where C[0]:R[0] = X[0] + ~Y[0] + 1
371 Subtraction - Borrow - Introduction - Direct Subtraction
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:
378 B[p]:R[p] = X[p] - Y[p] - B[p-1]
379 where B[0]:R[0] = X[0] - Y[0]
381 The Borrow bit is the complement of the Carry bit produced by
382 Negated Addition above. A dodgy proof follows:
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]?
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]
400 The table below lists all possible inputs/outputs for a
415 Subtraction - Method 1
418 Treating Xn and Yn as unsigned values then a borrow (unsigned
419 underflow) occurs when:
428 /* 8 bit target expressions:
430 Since the host's natural bitsize > 8 bits, carry method 2 and
431 overflow method 2 are used. */
433 #define ALU8_BEGIN(VAL) \
434 unsigned alu8_cr = (uint8_t) (VAL); \
435 signed alu8_vr = (int8_t) (alu8_cr)
437 #define ALU8_SET(VAL) \
438 alu8_cr = (uint8_t) (VAL); \
439 alu8_vr = (int8_t) (alu8_cr)
441 #define ALU8_SET_CARRY_BORROW(CARRY) \
444 alu8_cr |= ((signed)-1) << 8; \
449 #define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8))
450 #define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1))
452 #define ALU8_RESULT ((uint8_t) alu8_cr)
453 #define ALU8_CARRY_BORROW_RESULT ((uint8_t) alu8_cr)
454 #define ALU8_OVERFLOW_RESULT ((uint8_t) alu8_vr)
456 /* #define ALU8_END ????? - target dependant */
460 /* 16 bit target expressions:
462 Since the host's natural bitsize > 16 bits, carry method 2 and
463 overflow method 2 are used. */
465 #define ALU16_BEGIN(VAL) \
466 signed alu16_cr = (uint16_t) (VAL); \
467 unsigned alu16_vr = (int16_t) (alu16_cr)
469 #define ALU16_SET(VAL) \
470 alu16_cr = (uint16_t) (VAL); \
471 alu16_vr = (int16_t) (alu16_cr)
473 #define ALU16_SET_CARRY_BORROW(CARRY) \
476 alu16_cr |= ((signed)-1) << 16; \
478 alu16_cr &= 0xffff; \
481 #define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16))
482 #define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1))
484 #define ALU16_RESULT ((uint16_t) alu16_cr)
485 #define ALU16_CARRY_BORROW_RESULT ((uint16_t) alu16_cr)
486 #define ALU16_OVERFLOW_RESULT ((uint16_t) alu16_vr)
488 /* #define ALU16_END ????? - target dependant */
492 /* 32 bit target expressions:
494 Since most hosts do not support 64 (> 32) bit arithmetic, carry
495 method 4 and overflow method 4 are used. */
497 #define ALU32_BEGIN(VAL) \
498 uint32_t alu32_r = (VAL); \
502 #define ALU32_SET(VAL) \
507 #define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY)
509 #define ALU32_HAD_CARRY_BORROW (alu32_c)
510 #define ALU32_HAD_OVERFLOW (alu32_v)
512 #define ALU32_RESULT (alu32_r)
513 #define ALU32_CARRY_BORROW_RESULT (alu32_r)
514 #define ALU32_OVERFLOW_RESULT (alu32_r)
518 /* 64 bit target expressions:
520 Even though the host typically doesn't support native 64 bit
521 arithmetic, it is still used. */
523 #define ALU64_BEGIN(VAL) \
524 uint64_t alu64_r = (VAL); \
528 #define ALU64_SET(VAL) \
533 #define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY)
535 #define ALU64_HAD_CARRY_BORROW (alu64_c)
536 #define ALU64_HAD_OVERFLOW (alu64_v)
538 #define ALU64_RESULT (alu64_r)
539 #define ALU64_CARRY_BORROW_RESULT (alu64_r)
540 #define ALU64_OVERFLOW_RESULT (alu64_r)
544 /* Generic versions of above macros */
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)
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)
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)
559 /* Basic operation - add (overflowing) */
561 #define ALU8_ADD(VAL) \
563 uint8_t alu8add_val = (VAL); \
564 ALU8_ADDC (alu8add_val); \
567 #define ALU16_ADD(VAL) \
569 uint16_t alu16add_val = (VAL); \
570 ALU16_ADDC (alu8add_val); \
573 #define ALU32_ADD(VAL) \
575 uint32_t alu32add_val = (VAL); \
576 ALU32_ADDC (alu32add_val); \
579 #define ALU64_ADD(VAL) \
581 uint64_t alu64add_val = (uint64_t) (VAL); \
582 ALU64_ADDC (alu64add_val); \
585 #define ALU_ADD XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADD)
589 /* Basic operation - add carrying (and overflowing) */
591 #define ALU8_ADDC(VAL) \
593 uint8_t alu8addc_val = (VAL); \
594 alu8_cr += (uint8_t)(alu8addc_val); \
595 alu8_vr += (int8_t)(alu8addc_val); \
598 #define ALU16_ADDC(VAL) \
600 uint16_t alu16addc_val = (VAL); \
601 alu16_cr += (uint16_t)(alu16addc_val); \
602 alu16_vr += (int16_t)(alu16addc_val); \
605 #define ALU32_ADDC(VAL) \
607 uint32_t alu32addc_val = (VAL); \
608 uint32_t alu32addc_sign = alu32addc_val ^ alu32_r; \
609 alu32_r += (alu32addc_val); \
610 alu32_c = (alu32_r < alu32addc_val); \
611 alu32_v = ((alu32addc_sign ^ - (uint32_t)alu32_c) ^ alu32_r) >> 31; \
614 #define ALU64_ADDC(VAL) \
616 uint64_t alu64addc_val = (uint64_t) (VAL); \
617 uint64_t alu64addc_sign = alu64addc_val ^ alu64_r; \
618 alu64_r += (alu64addc_val); \
619 alu64_c = (alu64_r < alu64addc_val); \
620 alu64_v = ((alu64addc_sign ^ - (uint64_t)alu64_c) ^ alu64_r) >> 63; \
623 #define ALU_ADDC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC)
627 /* Compound operation - add carrying (and overflowing) with carry-in */
629 #define ALU8_ADDC_C(VAL,C) \
631 uint8_t alu8addcc_val = (VAL); \
632 uint8_t alu8addcc_c = (C); \
633 alu8_cr += (unsigned)(uint8_t)alu8addcc_val + alu8addcc_c; \
634 alu8_vr += (signed)(int8_t)(alu8addcc_val) + alu8addcc_c; \
637 #define ALU16_ADDC_C(VAL,C) \
639 uint16_t alu16addcc_val = (VAL); \
640 uint16_t alu16addcc_c = (C); \
641 alu16_cr += (unsigned)(uint16_t)alu16addcc_val + alu16addcc_c; \
642 alu16_vr += (signed)(int16_t)(alu16addcc_val) + alu16addcc_c; \
645 #define ALU32_ADDC_C(VAL,C) \
647 uint32_t alu32addcc_val = (VAL); \
648 uint32_t alu32addcc_c = (C); \
649 uint32_t 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 ^ - (uint32_t)alu32_c) ^ alu32_r) >> 31;\
656 #define ALU64_ADDC_C(VAL,C) \
658 uint64_t alu64addcc_val = (VAL); \
659 uint64_t alu64addcc_c = (C); \
660 uint64_t 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 ^ - (uint64_t)alu64_c) ^ alu64_r) >> 63;\
667 #define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C)
671 /* Basic operation - subtract (overflowing) */
673 #define ALU8_SUB(VAL) \
675 uint8_t alu8sub_val = (VAL); \
676 ALU8_ADDC_C (~alu8sub_val, 1); \
679 #define ALU16_SUB(VAL) \
681 uint16_t alu16sub_val = (VAL); \
682 ALU16_ADDC_C (~alu16sub_val, 1); \
685 #define ALU32_SUB(VAL) \
687 uint32_t alu32sub_val = (VAL); \
688 ALU32_ADDC_C (~alu32sub_val, 1); \
691 #define ALU64_SUB(VAL) \
693 uint64_t alu64sub_val = (VAL); \
694 ALU64_ADDC_C (~alu64sub_val, 1); \
697 #define ALU_SUB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUB)
701 /* Basic operation - subtract carrying (and overflowing) */
703 #define ALU8_SUBC(VAL) \
705 uint8_t alu8subc_val = (VAL); \
706 ALU8_ADDC_C (~alu8subc_val, 1); \
709 #define ALU16_SUBC(VAL) \
711 uint16_t alu16subc_val = (VAL); \
712 ALU16_ADDC_C (~alu16subc_val, 1); \
715 #define ALU32_SUBC(VAL) \
717 uint32_t alu32subc_val = (VAL); \
718 ALU32_ADDC_C (~alu32subc_val, 1); \
721 #define ALU64_SUBC(VAL) \
723 uint64_t alu64subc_val = (VAL); \
724 ALU64_ADDC_C (~alu64subc_val, 1); \
727 #define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC)
731 /* Compound operation - subtract carrying (and overflowing), extended */
733 #define ALU8_SUBC_X(VAL,C) \
735 uint8_t alu8subcx_val = (VAL); \
736 uint8_t alu8subcx_c = (C); \
737 ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c); \
740 #define ALU16_SUBC_X(VAL,C) \
742 uint16_t alu16subcx_val = (VAL); \
743 uint16_t alu16subcx_c = (C); \
744 ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c); \
747 #define ALU32_SUBC_X(VAL,C) \
749 uint32_t alu32subcx_val = (VAL); \
750 uint32_t alu32subcx_c = (C); \
751 ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c); \
754 #define ALU64_SUBC_X(VAL,C) \
756 uint64_t alu64subcx_val = (VAL); \
757 uint64_t alu64subcx_c = (C); \
758 ALU64_ADDC_C (~alu64subcx_val, alu64subcx_c); \
761 #define ALU_SUBC_X XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC_X)
765 /* Basic operation - subtract borrowing (and overflowing) */
767 #define ALU8_SUBB(VAL) \
769 uint8_t alu8subb_val = (VAL); \
770 alu8_cr -= (unsigned)(uint8_t)alu8subb_val; \
771 alu8_vr -= (signed)(int8_t)alu8subb_val; \
774 #define ALU16_SUBB(VAL) \
776 uint16_t alu16subb_val = (VAL); \
777 alu16_cr -= (unsigned)(uint16_t)alu16subb_val; \
778 alu16_vr -= (signed)(int16_t)alu16subb_val; \
781 #define ALU32_SUBB(VAL) \
783 uint32_t alu32subb_val = (VAL); \
784 uint32_t alu32subb_sign = alu32subb_val ^ alu32_r; \
785 alu32_c = (alu32_r < alu32subb_val); \
786 alu32_r -= (alu32subb_val); \
787 alu32_v = ((alu32subb_sign ^ - (uint32_t)alu32_c) ^ alu32_r) >> 31; \
790 #define ALU64_SUBB(VAL) \
792 uint64_t alu64subb_val = (VAL); \
793 uint64_t alu64subb_sign = alu64subb_val ^ alu64_r; \
794 alu64_c = (alu64_r < alu64subb_val); \
795 alu64_r -= (alu64subb_val); \
796 alu64_v = ((alu64subb_sign ^ - (uint64_t)alu64_c) ^ alu64_r) >> 31; \
799 #define ALU_SUBB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB)
803 /* Compound operation - subtract borrowing (and overflowing) with borrow-in */
805 #define ALU8_SUBB_B(VAL,B) \
807 uint8_t alu8subbb_val = (VAL); \
808 uint8_t alu8subbb_b = (B); \
809 alu8_cr -= (unsigned)(uint8_t)alu8subbb_val; \
810 alu8_cr -= (unsigned)(uint8_t)alu8subbb_b; \
811 alu8_vr -= (signed)(int8_t)alu8subbb_val + alu8subbb_b; \
814 #define ALU16_SUBB_B(VAL,B) \
816 uint16_t alu16subbb_val = (VAL); \
817 uint16_t alu16subbb_b = (B); \
818 alu16_cr -= (unsigned)(uint16_t)alu16subbb_val; \
819 alu16_cr -= (unsigned)(uint16_t)alu16subbb_b; \
820 alu16_vr -= (signed)(int16_t)alu16subbb_val + alu16subbb_b; \
823 #define ALU32_SUBB_B(VAL,B) \
825 uint32_t alu32subbb_val = (VAL); \
826 uint32_t alu32subbb_b = (B); \
827 ALU32_ADDC_C (~alu32subbb_val, !alu32subbb_b); \
828 alu32_c = !alu32_c; \
831 #define ALU64_SUBB_B(VAL,B) \
833 uint64_t alu64subbb_val = (VAL); \
834 uint64_t alu64subbb_b = (B); \
835 ALU64_ADDC_C (~alu64subbb_val, !alu64subbb_b); \
836 alu64_c = !alu64_c; \
839 #define ALU_SUBB_B XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB_B)
843 /* Basic operation - negate (overflowing) */
847 signed alu8neg_val = (ALU8_RESULT); \
849 ALU8_ADDC (~alu8neg_val); \
852 #define ALU16_NEG() \
854 signed alu16neg_val = (ALU16_RESULT); \
856 ALU16_ADDC (~alu16neg_val); \
859 #define ALU32_NEG() \
861 uint32_t alu32neg_val = (ALU32_RESULT); \
863 ALU32_ADDC (~alu32neg_val); \
866 #define ALU64_NEG() \
868 uint64_t alu64neg_val = (ALU64_RESULT); \
870 ALU64_ADDC (~alu64neg_val); \
873 #define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG)
878 /* Basic operation - negate carrying (and overflowing) */
880 #define ALU8_NEGC() \
882 signed alu8negc_val = (ALU8_RESULT); \
884 ALU8_ADDC (~alu8negc_val); \
887 #define ALU16_NEGC() \
889 signed alu16negc_val = (ALU16_RESULT); \
891 ALU16_ADDC (~alu16negc_val); \
894 #define ALU32_NEGC() \
896 uint32_t alu32negc_val = (ALU32_RESULT); \
898 ALU32_ADDC (~alu32negc_val); \
901 #define ALU64_NEGC() \
903 uint64_t alu64negc_val = (ALU64_RESULT); \
905 ALU64_ADDC (~alu64negc_val); \
908 #define ALU_NEGC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGC)
913 /* Basic operation - negate borrowing (and overflowing) */
915 #define ALU8_NEGB() \
917 signed alu8negb_val = (ALU8_RESULT); \
919 ALU8_SUBB (alu8negb_val); \
922 #define ALU16_NEGB() \
924 signed alu16negb_val = (ALU16_RESULT); \
926 ALU16_SUBB (alu16negb_val); \
929 #define ALU32_NEGB() \
931 uint32_t alu32negb_val = (ALU32_RESULT); \
933 ALU32_SUBB (alu32negb_val); \
936 #define ALU64_NEGB() \
938 uint64_t alu64negb_val = (ALU64_RESULT); \
940 ALU64_SUBB (alu64negb_val); \
943 #define ALU_NEGB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGB)
950 #define ALU8_OR(VAL) \
955 #define ALU16_OR(VAL) \
960 #define ALU32_OR(VAL) \
967 #define ALU64_OR(VAL) \
974 #define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL)
978 #define ALU16_XOR(VAL) \
980 error("ALU16_XOR"); \
983 #define ALU32_XOR(VAL) \
990 #define ALU64_XOR(VAL) \
997 #define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL)
1002 #define ALU16_AND(VAL) \
1004 error("ALU_AND16"); \
1007 #define ALU32_AND(VAL) \
1014 #define ALU64_AND(VAL) \
1021 #define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL)
1026 #define ALU16_NOT(VAL) \
1028 error("ALU_NOT16"); \
1033 alu32_r = ~alu32_r; \
1040 alu64_r = ~alu64_r; \
1045 #define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT)