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