* gas/mn10300/udf.s: New test.
[deliverable/binutils-gdb.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
This page took 0.084359 seconds and 4 git commands to generate.