OSDN Git Service

2002-11-22 Andrew Cagney <ac131313@redhat.com>
[pf3gnuchains/pf3gnuchains3x.git] / sim / common / sim-alu.h
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