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