This commit was generated by cvs2svn to track changes on a CVS vendor
[external/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    hence we get carry by computing in N bit unsigned arrithmetic.
340
341                 carry <- (Xn + Yn) < Xn
342
343
344
345    Subtraction - Introduction
346
347
348    There are two different ways of computing the signed two's
349    complement difference of two numbers.  The first is based on
350    negative addition, the second on direct subtraction.
351
352
353
354    Subtraction - Carry - Introduction - Negated Addition
355
356
357    The equation X - Y can be computed using:
358
359                 X + (-Y)
360         ==>     X + ~Y + 1              # -Y = ~Y + 1
361
362    In addition to the result, the equation produces Carry-out.  For
363    succeeding extended prrcision calculations, the more general
364    equation can be used:
365
366                 C[p]:R[p]  =  X[p] + ~Y[p] + C[p-1]
367         where   C[0]:R[0]  =  X[0] + ~Y[0] + 1
368
369
370
371    Subtraction - Borrow - Introduction - Direct Subtraction
372
373
374    The alternative to negative addition is direct subtraction where
375    `X-Y is computed directly.  In addition to the result of the
376    calculation, a Borrow bit is produced.  In general terms:
377
378                 B[p]:R[p]  =  X[p] - Y[p] - B[p-1]
379         where   B[0]:R[0]  =  X[0] - Y[0]
380
381    The Borrow bit is the complement of the Carry bit produced by
382    Negated Addition above.  A dodgy proof follows:
383
384         Case 0:
385                 C[0]:R[0] = X[0] + ~Y[0] + 1
386         ==>     C[0]:R[0] = X[0] + 1 - Y[0] + 1 # ~Y[0] = (1 - Y[0])?
387         ==>     C[0]:R[0] = 2 + X[0] - Y[0]
388         ==>     C[0]:R[0] = 2 + B[0]:R[0]
389         ==>     C[0]:R[0] = (1 + B[0]):R[0]
390         ==>     C[0] = ~B[0]                    # (1 + B[0]) mod 2 = ~B[0]?
391
392         Case P:
393                 C[p]:R[p] = X[p] + ~Y[p] + C[p-1]
394         ==>     C[p]:R[p] = X[p] + 1 - Y[0] + 1 - B[p-1]
395         ==>     C[p]:R[p] = 2 + X[p] - Y[0] - B[p-1]
396         ==>     C[p]:R[p] = 2 + B[p]:R[p]
397         ==>     C[p]:R[p] = (1 + B[p]):R[p]
398         ==>     C[p] = ~B[p]
399
400    The table below lists all possible inputs/outputs for a
401    full-subtractor:
402
403         X  Y  I  |  R  B
404         0  0  0  |  0  0
405         0  0  1  |  1  1
406         0  1  0  |  1  1
407         0  1  1  |  0  1
408         1  0  0  |  1  0
409         1  0  1  |  0  0
410         1  1  0  |  0  0
411         1  1  1  |  1  1
412
413
414
415    Subtraction - Method 1
416
417
418    Treating Xn and Yn as unsigned values then a borrow (unsigned
419    underflow) occures when:
420
421                 B = Xn < Yn
422         ==>     C = Xn >= Yn
423
424  */
425
426
427
428 /* 8 bit target expressions:
429
430    Since the host's natural bitsize > 8 bits, carry method 2 and
431    overflow method 2 are used. */
432
433 #define ALU8_BEGIN(VAL) \
434 unsigned alu8_cr = (unsigned8) (VAL); \
435 signed alu8_vr = (signed8) (alu8_cr)
436
437 #define ALU8_SET(VAL) \
438 alu8_cr = (unsigned8) (VAL); \
439 alu8_vr = (signed8) (alu8_cr)
440
441 #define ALU8_SET_CARRY_BORROW(CARRY)                                    \
442 do {                                                                    \
443   if (CARRY)                                                            \
444     alu8_cr |= ((signed)-1) << 8;                                       \
445   else                                                                  \
446     alu8_cr &= 0xff;                                                    \
447 } while (0)
448
449 #define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8))
450 #define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1))
451
452 #define ALU8_RESULT ((unsigned8) alu8_cr)
453 #define ALU8_CARRY_BORROW_RESULT ((unsigned8) alu8_cr)
454 #define ALU8_OVERFLOW_RESULT ((unsigned8) alu8_vr)
455
456 /* #define ALU8_END ????? - target dependant */
457
458
459
460 /* 16 bit target expressions:
461
462    Since the host's natural bitsize > 16 bits, carry method 2 and
463    overflow method 2 are used. */
464
465 #define ALU16_BEGIN(VAL) \
466 signed alu16_cr = (unsigned16) (VAL); \
467 unsigned alu16_vr = (signed16) (alu16_cr)
468
469 #define ALU16_SET(VAL) \
470 alu16_cr = (unsigned16) (VAL); \
471 alu16_vr = (signed16) (alu16_cr)
472
473 #define ALU16_SET_CARRY_BORROW(CARRY)                                   \
474 do {                                                                    \
475   if (CARRY)                                                            \
476     alu16_cr |= ((signed)-1) << 16;                                     \
477   else                                                                  \
478     alu16_cr &= 0xffff;                                                 \
479 } while (0)
480
481 #define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16))
482 #define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1))
483
484 #define ALU16_RESULT ((unsigned16) alu16_cr)
485 #define ALU16_CARRY_BORROW_RESULT ((unsigned16) alu16_cr)
486 #define ALU16_OVERFLOW_RESULT ((unsigned16) alu16_vr)
487
488 /* #define ALU16_END ????? - target dependant */
489
490
491
492 /* 32 bit target expressions:
493
494    Since most hosts do not support 64 (> 32) bit arrithmetic, carry
495    method 4 and overflow method 4 are used. */
496
497 #define ALU32_BEGIN(VAL) \
498 unsigned32 alu32_r = (VAL); \
499 int alu32_c = 0; \
500 int alu32_v = 0
501
502 #define ALU32_SET(VAL) \
503 alu32_r = (VAL); \
504 alu32_c = 0; \
505 alu32_v = 0
506
507 #define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY)
508
509 #define ALU32_HAD_CARRY_BORROW (alu32_c)
510 #define ALU32_HAD_OVERFLOW (alu32_v)
511
512 #define ALU32_RESULT (alu32_r)
513 #define ALU32_CARRY_BORROW_RESULT (alu32_r)
514 #define ALU32_OVERFLOW_RESULT (alu32_r)
515
516
517
518 /* 64 bit target expressions:
519
520    Even though the host typically doesn't support native 64 bit
521    arrithmetic, it is still used. */
522
523 #define ALU64_BEGIN(VAL) \
524 unsigned64 alu64_r = (VAL); \
525 int alu64_c = 0; \
526 int alu64_v = 0
527
528 #define ALU64_SET(VAL) \
529 alu64_r = (VAL); \
530 alu64_c = 0; \
531 alu64_v = 0
532
533 #define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY)
534
535 #define ALU64_HAD_CARRY_BORROW (alu64_c)
536 #define ALU64_HAD_OVERFLOW (alu64_v)
537
538 #define ALU64_RESULT (alu64_r)
539 #define ALU64_CARRY_BORROW_RESULT (alu64_r)
540 #define ALU64_OVERFLOW_RESULT (alu64_r)
541
542
543
544 /* Generic versions of above macros */
545
546 #define ALU_BEGIN           XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_BEGIN)
547 #define ALU_SET             XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET)
548 #define ALU_SET_CARRY       XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET_CARRY)
549
550 #define ALU_HAD_OVERFLOW    XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_OVERFLOW)
551 #define ALU_HAD_CARRY       XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_CARRY)
552
553 #define ALU_RESULT          XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_RESULT)
554 #define ALU_OVERFLOW_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OVERFLOW_RESULT)
555 #define ALU_CARRY_RESULT    XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_CARRY_RESULT)
556
557
558
559 /* Basic operation - add (overflowing) */
560
561 #define ALU8_ADD(VAL)                                                   \
562 do {                                                                    \
563   unsigned8 alu8add_val = (VAL);                                        \
564   ALU8_ADDC (alu8add_val);                                              \
565 } while (0)
566
567 #define ALU16_ADD(VAL)                                                  \
568 do {                                                                    \
569   unsigned16 alu16add_val = (VAL);                                      \
570   ALU16_ADDC (alu8add_val);                                             \
571 } while (0)
572
573 #define ALU32_ADD(VAL)                                                  \
574 do {                                                                    \
575   unsigned32 alu32add_val = (VAL);                                      \
576   ALU32_ADDC (alu32add_val);                                            \
577 } while (0)
578
579 #define ALU64_ADD(VAL)                                                  \
580 do {                                                                    \
581   unsigned64 alu64add_val = (unsigned64) (VAL);                         \
582   ALU64_ADDC (alu64add_val);                                            \
583 } while (0)
584
585 #define ALU_ADD XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADD)
586
587
588
589 /* Basic operation - add carrying (and overflowing) */
590
591 #define ALU8_ADDC(VAL)                                                  \
592 do {                                                                    \
593   unsigned8 alu8addc_val = (VAL);                                       \
594   alu8_cr += (unsigned8)(alu8addc_val);                                 \
595   alu8_vr += (signed8)(alu8addc_val);                                   \
596 } while (0)
597
598 #define ALU16_ADDC(VAL)                                                 \
599 do {                                                                    \
600   unsigned16 alu16addc_val = (VAL);                                     \
601   alu16_cr += (unsigned16)(alu16addc_val);                              \
602   alu16_vr += (signed16)(alu16addc_val);                                \
603 } while (0)
604
605 #define ALU32_ADDC(VAL)                                                 \
606 do {                                                                    \
607   unsigned32 alu32addc_val = (VAL);                                     \
608   unsigned32 alu32addc_sign = alu32addc_val ^ alu32_r;                  \
609   alu32_r += (alu32addc_val);                                           \
610   alu32_c = (alu32_r < alu32addc_val);                                  \
611   alu32_v = ((alu32addc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \
612 } while (0)
613
614 #define ALU64_ADDC(VAL)                                                 \
615 do {                                                                    \
616   unsigned64 alu64addc_val = (unsigned64) (VAL);                        \
617   unsigned64 alu64addc_sign = alu64addc_val ^ alu64_r;                  \
618   alu64_r += (alu64addc_val);                                           \
619   alu64_c = (alu64_r < alu64addc_val);                                  \
620   alu64_v = ((alu64addc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63; \
621 } while (0)
622
623 #define ALU_ADDC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC)
624
625
626
627 /* Compound operation - add carrying (and overflowing) with carry-in */
628
629 #define ALU8_ADDC_C(VAL,C)                                              \
630 do {                                                                    \
631   unsigned8 alu8addcc_val = (VAL);                                      \
632   unsigned8 alu8addcc_c = (C);                                          \
633   alu8_cr += (unsigned)(unsigned8)alu8addcc_val + alu8addcc_c;          \
634   alu8_vr += (signed)(signed8)(alu8addcc_val) + alu8addcc_c;            \
635 } while (0)
636
637 #define ALU16_ADDC_C(VAL,C)                                             \
638 do {                                                                    \
639   unsigned16 alu16addcc_val = (VAL);                                    \
640   unsigned16 alu16addcc_c = (C);                                        \
641   alu16_cr += (unsigned)(unsigned16)alu16addcc_val + alu16addcc_c;      \
642   alu16_vr += (signed)(signed16)(alu16addcc_val) + alu16addcc_c;        \
643 } while (0)
644
645 #define ALU32_ADDC_C(VAL,C)                                             \
646 do {                                                                    \
647   unsigned32 alu32addcc_val = (VAL);                                    \
648   unsigned32 alu32addcc_c = (C);                                        \
649   unsigned32 alu32addcc_sign = (alu32addcc_val ^ alu32_r);              \
650   alu32_r += (alu32addcc_val + alu32addcc_c);                           \
651   alu32_c = ((alu32_r < alu32addcc_val)                                 \
652              || (alu32addcc_c && alu32_r == alu32addcc_val));           \
653   alu32_v = ((alu32addcc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31;\
654 } while (0)
655
656 #define ALU64_ADDC_C(VAL,C)                                             \
657 do {                                                                    \
658   unsigned64 alu64addcc_val = (VAL);                                    \
659   unsigned64 alu64addcc_c = (C);                                        \
660   unsigned64 alu64addcc_sign = (alu64addcc_val ^ alu64_r);              \
661   alu64_r += (alu64addcc_val + alu64addcc_c);                           \
662   alu64_c = ((alu64_r < alu64addcc_val)                                 \
663              || (alu64addcc_c && alu64_r == alu64addcc_val));           \
664   alu64_v = ((alu64addcc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63;\
665 } while (0)
666
667 #define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C)
668
669
670
671 /* Basic operation - subtract (overflowing) */
672
673 #define ALU8_SUB(VAL)                                                   \
674 do {                                                                    \
675   unsigned8 alu8sub_val = (VAL);                                        \
676   ALU8_ADDC_C (~alu8sub_val, 1);                                        \
677 } while (0)
678
679 #define ALU16_SUB(VAL)                                                  \
680 do {                                                                    \
681   unsigned16 alu16sub_val = (VAL);                                      \
682   ALU16_ADDC_C (~alu16sub_val, 1);                                      \
683 } while (0)
684
685 #define ALU32_SUB(VAL)                                                  \
686 do {                                                                    \
687   unsigned32 alu32sub_val = (VAL);                                      \
688   ALU32_ADDC_C (~alu32sub_val, 1);                                      \
689 } while (0)
690
691 #define ALU64_SUB(VAL)                                                  \
692 do {                                                                    \
693   unsigned64 alu64sub_val = (VAL);                                      \
694   ALU64_ADDC_C (~alu64sub_val, 1);                                      \
695 } while (0)
696
697 #define ALU_SUB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUB)
698
699
700
701 /* Basic operation - subtract carrying (and overflowing) */
702
703 #define ALU8_SUBC(VAL)                                                  \
704 do {                                                                    \
705   unsigned8 alu8subc_val = (VAL);                                       \
706   ALU8_ADDC_C (~alu8subc_val, 1);                                       \
707 } while (0)
708
709 #define ALU16_SUBC(VAL)                                                 \
710 do {                                                                    \
711   unsigned16 alu16subc_val = (VAL);                                     \
712   ALU16_ADDC_C (~alu16subc_val, 1);                                     \
713 } while (0)
714
715 #define ALU32_SUBC(VAL)                                                 \
716 do {                                                                    \
717   unsigned32 alu32subc_val = (VAL);                                     \
718   ALU32_ADDC_C (~alu32subc_val, 1);                                     \
719 } while (0)
720
721 #define ALU64_SUBC(VAL)                                                 \
722 do {                                                                    \
723   unsigned64 alu64subc_val = (VAL);                                     \
724   ALU64_ADDC_C (~alu64subc_val, 1);                                     \
725 } while (0)
726
727 #define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC)
728
729
730
731 /* Compound operation - subtract carrying (and overflowing), extended */
732
733 #define ALU8_SUBC_X(VAL,C)                                              \
734 do {                                                                    \
735   unsigned8 alu8subcx_val = (VAL);                                      \
736   unsigned8 alu8subcx_c = (C);                                          \
737   ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c);                            \
738 } while (0)
739
740 #define ALU16_SUBC_X(VAL,C)                                             \
741 do {                                                                    \
742   unsigned16 alu16subcx_val = (VAL);                                    \
743   unsigned16 alu16subcx_c = (C);                                        \
744   ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c);                         \
745 } while (0)
746
747 #define ALU32_SUBC_X(VAL,C)                                             \
748 do {                                                                    \
749   unsigned32 alu32subcx_val = (VAL);                                    \
750   unsigned32 alu32subcx_c = (C);                                        \
751   ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c);                         \
752 } while (0)
753
754 #define ALU64_SUBC_X(VAL,C)                                             \
755 do {                                                                    \
756   unsigned64 alu64subcx_val = (VAL);                                    \
757   unsigned64 alu64subcx_c = (C);                                        \
758   ALU64_ADDC_C (~alu64subcx_val, alu64subcx_c);                         \
759 } while (0)
760
761 #define ALU_SUBC_X XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC_X)
762
763
764
765 /* Basic operation - subtract borrowing (and overflowing) */
766
767 #define ALU8_SUBB(VAL)                                                  \
768 do {                                                                    \
769   unsigned8 alu8subb_val = (VAL);                                       \
770   alu8_cr -= (unsigned)(unsigned8)alu8subb_val;                         \
771   alu8_vr -= (signed)(signed8)alu8subb_val;                             \
772 } while (0)
773
774 #define ALU16_SUBB(VAL)                                                 \
775 do {                                                                    \
776   unsigned16 alu16subb_val = (VAL);                                     \
777   alu16_cr -= (unsigned)(unsigned16)alu16subb_val;                      \
778   alu16_vr -= (signed)(signed16)alu16subb_val;                          \
779 } while (0)
780
781 #define ALU32_SUBB(VAL)                                                 \
782 do {                                                                    \
783   unsigned32 alu32subb_val = (VAL);                                     \
784   unsigned32 alu32subb_sign = alu32subb_val ^ alu32_r;                  \
785   alu32_c = (alu32_r < alu32subb_val);                                  \
786   alu32_r -= (alu32subb_val);                                           \
787   alu32_v = ((alu32subb_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \
788 } while (0)
789
790 #define ALU64_SUBB(VAL)                                                 \
791 do {                                                                    \
792   unsigned64 alu64subb_val = (VAL);                                     \
793   unsigned64 alu64subb_sign = alu64subb_val ^ alu64_r;                  \
794   alu64_c = (alu64_r < alu64subb_val);                                  \
795   alu64_r -= (alu64subb_val);                                           \
796   alu64_v = ((alu64subb_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 31; \
797 } while (0)
798
799 #define ALU_SUBB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB)
800
801
802
803 /* Compound operation - subtract borrowing (and overflowing) with borrow-in */
804
805 #define ALU8_SUBB_B(VAL,B)                                              \
806 do {                                                                    \
807   unsigned8 alu8subbb_val = (VAL);                                      \
808   unsigned8 alu8subbb_b = (B);                                          \
809   alu8_cr -= (unsigned)(unsigned8)alu8subbb_val;                        \
810   alu8_cr -= (unsigned)(unsigned8)alu8subbb_b;                          \
811   alu8_vr -= (signed)(signed8)alu8subbb_val + alu8subbb_b;              \
812 } while (0)
813
814 #define ALU16_SUBB_B(VAL,B)                                             \
815 do {                                                                    \
816   unsigned16 alu16subbb_val = (VAL);                                    \
817   unsigned16 alu16subbb_b = (B);                                        \
818   alu16_cr -= (unsigned)(unsigned16)alu16subbb_val;                     \
819   alu16_cr -= (unsigned)(unsigned16)alu16subbb_b;                       \
820   alu16_vr -= (signed)(signed16)alu16subbb_val + alu16subbb_b;          \
821 } while (0)
822
823 #define ALU32_SUBB_B(VAL,B)                                             \
824 do {                                                                    \
825   unsigned32 alu32subbb_val = (VAL);                                    \
826   unsigned32 alu32subbb_b = (B);                                        \
827   ALU32_ADDC_C (~alu32subbb_val, !alu32subbb_b);                        \
828   alu32_c = !alu32_c;                                                   \
829 } while (0)
830
831 #define ALU64_SUBB_B(VAL,B)                                             \
832 do {                                                                    \
833   unsigned64 alu64subbb_val = (VAL);                                    \
834   unsigned64 alu64subbb_b = (B);                                        \
835   ALU64_ADDC_C (~alu64subbb_val, !alu64subbb_b);                        \
836   alu64_c = !alu64_c;                                                   \
837 } while (0)
838
839 #define ALU_SUBB_B XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB_B)
840
841
842
843 /* Basic operation - negate (overflowing) */
844
845 #define ALU8_NEG()                                                      \
846 do {                                                                    \
847   signed alu8neg_val = (ALU8_RESULT);                                   \
848   ALU8_SET (1);                                                         \
849   ALU8_ADDC (~alu8neg_val);                                             \
850 } while (0)
851
852 #define ALU16_NEG()                                                     \
853 do {                                                                    \
854   signed alu16neg_val = (ALU16_RESULT);                         \
855   ALU16_SET (1);                                                        \
856   ALU16_ADDC (~alu16neg_val);                                           \
857 } while (0)
858
859 #define ALU32_NEG()                                                     \
860 do {                                                                    \
861   unsigned32 alu32neg_val = (ALU32_RESULT);                             \
862   ALU32_SET (1);                                                        \
863   ALU32_ADDC (~alu32neg_val);                                           \
864 } while(0)
865
866 #define ALU64_NEG()                                                     \
867 do {                                                                    \
868   unsigned64 alu64neg_val = (ALU64_RESULT);                             \
869   ALU64_SET (1);                                                        \
870   ALU64_ADDC (~alu64neg_val);                                           \
871 } while (0)
872
873 #define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG)
874
875
876
877
878 /* Basic operation - negate carrying (and overflowing) */
879
880 #define ALU8_NEGC()                                                     \
881 do {                                                                    \
882   signed alu8negc_val = (ALU8_RESULT);                                  \
883   ALU8_SET (1);                                                         \
884   ALU8_ADDC (~alu8negc_val);                                            \
885 } while (0)
886
887 #define ALU16_NEGC()                                                    \
888 do {                                                                    \
889   signed alu16negc_val = (ALU16_RESULT);                                \
890   ALU16_SET (1);                                                        \
891   ALU16_ADDC (~alu16negc_val);                                          \
892 } while (0)
893
894 #define ALU32_NEGC()                                                    \
895 do {                                                                    \
896   unsigned32 alu32negc_val = (ALU32_RESULT);                            \
897   ALU32_SET (1);                                                        \
898   ALU32_ADDC (~alu32negc_val);                                          \
899 } while(0)
900
901 #define ALU64_NEGC()                                                    \
902 do {                                                                    \
903   unsigned64 alu64negc_val = (ALU64_RESULT);                            \
904   ALU64_SET (1);                                                        \
905   ALU64_ADDC (~alu64negc_val);                                          \
906 } while (0)
907
908 #define ALU_NEGC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGC)
909
910
911
912
913 /* Basic operation - negate borrowing (and overflowing) */
914
915 #define ALU8_NEGB()                                                     \
916 do {                                                                    \
917   signed alu8negb_val = (ALU8_RESULT);                                  \
918   ALU8_SET (0);                                                         \
919   ALU8_SUBB (alu8negb_val);                                             \
920 } while (0)
921
922 #define ALU16_NEGB()                                                    \
923 do {                                                                    \
924   signed alu16negb_val = (ALU16_RESULT);                                \
925   ALU16_SET (0);                                                        \
926   ALU16_SUBB (alu16negb_val);                                           \
927 } while (0)
928
929 #define ALU32_NEGB()                                                    \
930 do {                                                                    \
931   unsigned32 alu32negb_val = (ALU32_RESULT);                            \
932   ALU32_SET (0);                                                        \
933   ALU32_SUBB (alu32negb_val);                                           \
934 } while(0)
935
936 #define ALU64_NEGB()                                                    \
937 do {                                                                    \
938   unsigned64 alu64negb_val = (ALU64_RESULT);                            \
939   ALU64_SET (0);                                                        \
940   ALU64_SUBB (alu64negb_val);                                           \
941 } while (0)
942
943 #define ALU_NEGB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGB)
944
945
946
947
948 /* Other */
949
950 #define ALU8_OR(VAL)                                                    \
951 do {                                                                    \
952   error("ALU16_OR");                                                    \
953 } while (0)
954
955 #define ALU16_OR(VAL)                                                   \
956 do {                                                                    \
957   error("ALU16_OR");                                                    \
958 } while (0)
959
960 #define ALU32_OR(VAL)                                                   \
961 do {                                                                    \
962   alu32_r |= (VAL);                                                     \
963   alu32_c = 0;                                                          \
964   alu32_v = 0;                                                          \
965 } while (0)
966
967 #define ALU64_OR(VAL)                                                   \
968 do {                                                                    \
969   alu64_r |= (VAL);                                                     \
970   alu64_c = 0;                                                          \
971   alu64_v = 0;                                                          \
972 } while (0)
973
974 #define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL)
975
976
977
978 #define ALU16_XOR(VAL)                                                  \
979 do {                                                                    \
980   error("ALU16_XOR");                                                   \
981 } while (0)
982
983 #define ALU32_XOR(VAL)                                                  \
984 do {                                                                    \
985   alu32_r ^= (VAL);                                                     \
986   alu32_c = 0;                                                          \
987   alu32_v = 0;                                                          \
988 } while (0)
989
990 #define ALU64_XOR(VAL)                                                  \
991 do {                                                                    \
992   alu64_r ^= (VAL);                                                     \
993   alu64_c = 0;                                                          \
994   alu64_v = 0;                                                          \
995 } while (0)
996
997 #define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL)
998
999
1000
1001
1002 #define ALU16_AND(VAL)                                                  \
1003 do {                                                                    \
1004   error("ALU_AND16");                                                   \
1005 } while (0)
1006
1007 #define ALU32_AND(VAL)                                                  \
1008 do {                                                                    \
1009   alu32_r &= (VAL);                                                     \
1010   alu32_r = 0;                                                          \
1011   alu32_v = 0;                                                          \
1012 } while (0)
1013
1014 #define ALU64_AND(VAL)                                                  \
1015 do {                                                                    \
1016   alu64_r &= (VAL);                                                     \
1017   alu64_r = 0;                                                          \
1018   alu64_v = 0;                                                          \
1019 } while (0)
1020
1021 #define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL)
1022
1023
1024
1025
1026 #define ALU16_NOT(VAL)                                                  \
1027 do {                                                                    \
1028   error("ALU_NOT16");                                                   \
1029 } while (0)
1030
1031 #define ALU32_NOT                                                       \
1032 do {                                                                    \
1033   alu32_r = ~alu32_r;                                                   \
1034   alu32_c = 0;                                                          \
1035   alu32_v = 0;                                                          \
1036 } while (0)
1037
1038 #define ALU64_NOT                                                       \
1039 do {                                                                    \
1040   alu64_r = ~alu64_r;                                                   \
1041   alu64_c = 0;                                                          \
1042   alu64_v = 0;                                                          \
1043 } while (0)
1044
1045 #define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT)
1046
1047 #endif