1 /* The common simulator framework for GDB, the GNU Debugger.
2 
3    Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4 
5    Contributed by Andrew Cagney and Red Hat.
6 
7    This file is part of GDB.
8 
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.
13 
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.
18 
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/>.  */
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    arithmetic 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    	occurred.
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 referred to as carry and borrow)
88    	occurred.
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 arithmetic - 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 arithmetic is computed `modulo (Un)'.
158 
159    X[p]: Is bit P of X.  X[0] denotes the least significant 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    arithmetic.  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 occurs 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 occurs 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 occurs 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 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.
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    arithmetic.  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 occurs:
318 
319 		X + Y >= Un, Y < Un
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
323 
324    or when carry as occurred:
325 
326                (X + Y) mod Un < X mod Un
327 
328    Consider Y when carry does not occur:
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 occurred:
336 
337 	        ! ( (X + Y) mod Un < X mod Un)
338 
339    hence we get carry by computing in N bit unsigned arithmetic.
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 precision 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) occurs 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 arithmetic, 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    arithmetic, 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
1048