* cgen-trace.c (trace_insn): Pass pc to trace_prefix for virtual insns.
[deliverable/binutils-gdb.git] / sim / common / sim-alu.h
CommitLineData
d6fea803
AC
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
36dbc8bb 26#include "symcat.h"
d6fea803 27
d6fea803 28
36dbc8bb 29/* INTEGER ALU MODULE:
d6fea803 30
36dbc8bb
DE
31 This module provides an implementation of 2's complement arithmetic
32 including the recording of carry and overflow status bits.
d6fea803
AC
33
34
36dbc8bb 35 EXAMPLE:
d6fea803 36
36dbc8bb
DE
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:
d6fea803 40
36dbc8bb
DE
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
d6fea803 46
36dbc8bb
DE
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:
d6fea803
AC
191
192
465db791
MM
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
36dbc8bb
DE
197 Rm = (SEXTn (Xn) + SEXTn (Yn))
198 V = MSBn ((Rm >> (M - N)) ^ Rm)
199
d6fea803 200
d6fea803 201
36dbc8bb
DE
202 Addition - Overflow - method 3:
203
d6fea803 204
465db791 205 The two N bit operands are sign extended to M>N bits and then
36dbc8bb
DE
206 added. Overflow occures when the result is outside of the sign
207 extended range [MINn .. MAXn].
208
d6fea803 209
d6fea803 210
36dbc8bb 211 Addition - Overflow - method 4:
465db791 212
465db791 213
36dbc8bb
DE
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)
465db791
MM
219
220 As shown in the table below:
221
36dbc8bb 222 I X Y R C | V | X^Y ^R ^C
465db791
MM
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
36dbc8bb
DE
235 Addition - Carry - Introduction:
236
465db791 237
36dbc8bb
DE
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.
465db791 241
36dbc8bb
DE
242 The following table lists the output for all given inputs into a
243 full-adder.
244
245 I X Y R | C
465db791
MM
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
36dbc8bb
DE
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.
465db791 264
36dbc8bb 265 XY\R 0 1
465db791
MM
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
36dbc8bb 274 MSBn ((Xn & Yn) | (Xn & ~Rn) | (Yn & ~Rn))
465db791
MM
275
276 Verifying:
277
36dbc8bb 278 I X Y R | C | X&Y X&~R Y&~R
465db791
MM
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
36dbc8bb
DE
291 Addition - Carry - method 2:
292
465db791
MM
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
d6fea803 299
30efae3a 300
36dbc8bb
DE
301 Addition - Carry - method 3:
302
30efae3a 303
36dbc8bb 304 Given the oVerflow bit. The carry can be computed from:
d6fea803 305
465db791 306 (~R&V) | (R&V)
d6fea803
AC
307
308
465db791 309
36dbc8bb
DE
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 */
465db791
MM
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) \
36dbc8bb
DE
430unsigned alu8_cr = (unsigned8) (VAL); \
431signed alu8_vr = (signed8) (alu8_cr)
465db791
MM
432
433#define ALU8_SET(VAL) \
434alu8_cr = (unsigned8) (VAL); \
435alu8_vr = (signed8) (alu8_cr)
436
36dbc8bb 437#define ALU8_SET_CARRY_BORROW(CARRY) \
465db791
MM
438do { \
439 if (CARRY) \
440 alu8_cr |= ((signed)-1) << 8; \
441 else \
442 alu8_cr &= 0xff; \
443} while (0)
36dbc8bb
DE
444
445#define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8))
465db791
MM
446#define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1))
447
448#define ALU8_RESULT ((unsigned8) alu8_cr)
36dbc8bb 449#define ALU8_CARRY_BORROW_RESULT ((unsigned8) alu8_cr)
465db791
MM
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) \
462signed alu16_cr = (unsigned16) (VAL); \
463unsigned alu16_vr = (signed16) (alu16_cr)
d6fea803
AC
464
465#define ALU16_SET(VAL) \
465db791
MM
466alu16_cr = (unsigned16) (VAL); \
467alu16_vr = (signed16) (alu16_cr)
468
36dbc8bb 469#define ALU16_SET_CARRY_BORROW(CARRY) \
465db791
MM
470do { \
471 if (CARRY) \
472 alu16_cr |= ((signed)-1) << 16; \
473 else \
474 alu16_cr &= 0xffff; \
d6fea803
AC
475} while (0)
476
36dbc8bb 477#define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16))
465db791
MM
478#define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1))
479
480#define ALU16_RESULT ((unsigned16) alu16_cr)
36dbc8bb 481#define ALU16_CARRY_BORROW_RESULT ((unsigned16) alu16_cr)
465db791
MM
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
36dbc8bb 491 method 4 and overflow method 4 are used. */
465db791
MM
492
493#define ALU32_BEGIN(VAL) \
494unsigned32 alu32_r = (VAL); \
495int alu32_c = 0; \
496int alu32_v = 0
497
d6fea803 498#define ALU32_SET(VAL) \
465db791
MM
499alu32_r = (VAL); \
500alu32_c = 0; \
501alu32_v = 0
502
36dbc8bb 503#define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY)
465db791 504
36dbc8bb 505#define ALU32_HAD_CARRY_BORROW (alu32_c)
465db791 506#define ALU32_HAD_OVERFLOW (alu32_v)
465db791
MM
507
508#define ALU32_RESULT (alu32_r)
36dbc8bb 509#define ALU32_CARRY_BORROW_RESULT (alu32_r)
465db791
MM
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) \
520natural64 alu64_r = (VAL); \
521int alu64_c = 0; \
522int alu64_v = 0
d6fea803
AC
523
524#define ALU64_SET(VAL) \
465db791
MM
525alu64_r = (VAL); \
526alu64_c = 0; \
527alu64_v = 0
528
36dbc8bb 529#define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY)
465db791 530
36dbc8bb 531#define ALU64_HAD_CARRY_BORROW (alu64_c)
465db791
MM
532#define ALU64_HAD_OVERFLOW (alu64_v)
533
534#define ALU64_RESULT (alu64_r)
36dbc8bb 535#define ALU64_CARRY_BORROW_RESULT (alu64_r)
465db791
MM
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)
d6fea803 552
d6fea803
AC
553
554
36dbc8bb 555/* Basic operation - add (overflowing) */
d6fea803 556
465db791
MM
557#define ALU8_ADD(VAL) \
558do { \
36dbc8bb
DE
559 unsigned8 alu8add_val = (VAL); \
560 ALU8_ADDC (alu8add_val); \
d6fea803
AC
561} while (0)
562
465db791
MM
563#define ALU16_ADD(VAL) \
564do { \
36dbc8bb
DE
565 unsigned16 alu16add_val = (VAL); \
566 ALU16_ADDC (alu8add_val); \
d6fea803
AC
567} while (0)
568
465db791
MM
569#define ALU32_ADD(VAL) \
570do { \
36dbc8bb
DE
571 unsigned32 alu32add_val = (VAL); \
572 ALU32_ADDC (alu32add_val); \
465db791
MM
573} while (0)
574
575#define ALU64_ADD(VAL) \
576do { \
36dbc8bb
DE
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) \
588do { \
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) \
595do { \
596 unsigned16 alu16addc_val = (VAL); \
597 alu16_cr += (unsigned16)(alu16addc_val); \
598 alu16_vr += (signed16)(alu16addc_val); \
d6fea803
AC
599} while (0)
600
36dbc8bb
DE
601#define ALU32_ADDC(VAL) \
602do { \
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) \
611do { \
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)
d6fea803
AC
620
621
622
36dbc8bb
DE
623/* Compound operation - add carrying (and overflowing) with carry-in */
624
625#define ALU8_ADDC_C(VAL,C) \
465db791 626do { \
36dbc8bb
DE
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; \
465db791 631} while (0)
d6fea803 632
36dbc8bb 633#define ALU16_ADDC_C(VAL,C) \
465db791 634do { \
36dbc8bb
DE
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; \
d6fea803
AC
639} while (0)
640
36dbc8bb 641#define ALU32_ADDC_C(VAL,C) \
465db791 642do { \
36dbc8bb
DE
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;\
d6fea803
AC
650} while (0)
651
36dbc8bb 652#define ALU64_ADDC_C(VAL,C) \
465db791 653do { \
36dbc8bb
DE
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;\
d6fea803
AC
661} while (0)
662
36dbc8bb 663#define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C)
d6fea803
AC
664
665
666
36dbc8bb 667/* Basic operation - subtract (overflowing) */
d6fea803 668
465db791
MM
669#define ALU8_SUB(VAL) \
670do { \
36dbc8bb
DE
671 unsigned8 alu8sub_val = (VAL); \
672 ALU8_ADDC_C (~alu8sub_val, 1); \
d6fea803
AC
673} while (0)
674
465db791
MM
675#define ALU16_SUB(VAL) \
676do { \
36dbc8bb
DE
677 unsigned16 alu16sub_val = (VAL); \
678 ALU16_ADDC_C (~alu16sub_val, 1); \
d6fea803
AC
679} while (0)
680
465db791
MM
681#define ALU32_SUB(VAL) \
682do { \
36dbc8bb
DE
683 unsigned32 alu32sub_val = (VAL); \
684 ALU32_ADDC_C (~alu32sub_val, 1); \
465db791
MM
685} while (0)
686
687#define ALU64_SUB(VAL) \
688do { \
36dbc8bb
DE
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) \
700do { \
701 unsigned8 alu8subc_val = (VAL); \
702 ALU8_ADDC_C (~alu8subc_val, 1); \
d6fea803
AC
703} while (0)
704
36dbc8bb
DE
705#define ALU16_SUBC(VAL) \
706do { \
707 unsigned16 alu16subc_val = (VAL); \
708 ALU16_ADDC_C (~alu16subc_val, 1); \
709} while (0)
d6fea803 710
36dbc8bb
DE
711#define ALU32_SUBC(VAL) \
712do { \
713 unsigned32 alu32subc_val = (VAL); \
714 ALU32_ADDC_C (~alu32subc_val, 1); \
715} while (0)
716
717#define ALU64_SUBC(VAL) \
718do { \
719 unsigned64 alu64subc_val = (VAL); \
720 ALU64_ADDC_C (~alu64subc_val, 1); \
721} while (0)
d6fea803 722
36dbc8bb 723#define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC)
d6fea803
AC
724
725
36dbc8bb
DE
726
727/* Compound operation - subtract carrying (and overflowing), extended */
728
729#define ALU8_SUBC_X(VAL,C) \
465db791 730do { \
36dbc8bb
DE
731 unsigned8 alu8subcx_val = (VAL); \
732 unsigned8 alu8subcx_c = (C); \
733 ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c); \
d6fea803
AC
734} while (0)
735
36dbc8bb 736#define ALU16_SUBC_X(VAL,C) \
465db791 737do { \
36dbc8bb
DE
738 unsigned16 alu16subcx_val = (VAL); \
739 unsigned16 alu16subcx_c = (C); \
740 ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c); \
d6fea803
AC
741} while (0)
742
36dbc8bb 743#define ALU32_SUBC_X(VAL,C) \
465db791 744do { \
36dbc8bb
DE
745 unsigned32 alu32subcx_val = (VAL); \
746 unsigned32 alu32subcx_c = (C); \
747 ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c); \
d6fea803
AC
748} while (0)
749
36dbc8bb
DE
750#define ALU64_SUBC_X(VAL,C) \
751do { \
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) \
764do { \
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) \
771do { \
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) \
778do { \
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) \
787do { \
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) \
802do { \
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) \
811do { \
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) \
820do { \
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) \
828do { \
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() \
842do { \
843 signed alu8neg_val = (ALU8_RESULT); \
844 ALU8_SET (1); \
845 ALU8_ADDC (~alu8neg_val); \
846} while (0)
847
848#define ALU16_NEG() \
849do { \
850 signed alu16neg_val = (ALU16_RESULT); \
851 ALU16_SET (1); \
852 ALU16_ADDC (~alu16neg_val); \
853} while (0)
854
855#define ALU32_NEG() \
856do { \
857 unsigned32 alu32neg_val = (ALU32_RESULT); \
858 ALU32_SET (1); \
859 ALU32_ADDC (~alu32neg_val); \
860} while(0)
861
862#define ALU64_NEG() \
465db791 863do { \
36dbc8bb
DE
864 unsigned64 alu64neg_val = (ALU64_RESULT); \
865 ALU64_SET (1); \
866 ALU64_ADDC (~alu64neg_val); \
465db791 867} while (0)
d6fea803 868
36dbc8bb 869#define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG)
d6fea803
AC
870
871
872
36dbc8bb
DE
873
874/* Basic operation - negate carrying (and overflowing) */
875
876#define ALU8_NEGC() \
877do { \
878 signed alu8negc_val = (ALU8_RESULT); \
879 ALU8_SET (1); \
880 ALU8_ADDC (~alu8negc_val); \
881} while (0)
882
883#define ALU16_NEGC() \
884do { \
885 signed alu16negc_val = (ALU16_RESULT); \
886 ALU16_SET (1); \
887 ALU16_ADDC (~alu16negc_val); \
888} while (0)
889
890#define ALU32_NEGC() \
891do { \
892 unsigned32 alu32negc_val = (ALU32_RESULT); \
893 ALU32_SET (1); \
894 ALU32_ADDC (~alu32negc_val); \
895} while(0)
896
897#define ALU64_NEGC() \
898do { \
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() \
912do { \
913 signed alu8negb_val = (ALU8_RESULT); \
914 ALU8_SET (0); \
915 ALU8_SUBB (alu8negb_val); \
916} while (0)
917
918#define ALU16_NEGB() \
919do { \
920 signed alu16negb_val = (ALU16_RESULT); \
921 ALU16_SET (0); \
922 ALU16_SUBB (alu16negb_val); \
923} while (0)
924
925#define ALU32_NEGB() \
926do { \
927 unsigned32 alu32negb_val = (ALU32_RESULT); \
928 ALU32_SET (0); \
929 ALU32_SUBB (alu32negb_val); \
930} while(0)
931
932#define ALU64_NEGB() \
933do { \
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) \
947do { \
948 error("ALU16_OR"); \
949} while (0)
950
465db791
MM
951#define ALU16_OR(VAL) \
952do { \
953 error("ALU16_OR"); \
d6fea803
AC
954} while (0)
955
465db791
MM
956#define ALU32_OR(VAL) \
957do { \
958 alu32_r |= (VAL); \
959 alu32_c = 0; \
960 alu32_v = 0; \
d6fea803
AC
961} while (0)
962
465db791
MM
963#define ALU64_OR(VAL) \
964do { \
965 alu64_r |= (VAL); \
966 alu64_c = 0; \
967 alu64_v = 0; \
d6fea803
AC
968} while (0)
969
970#define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL)
971
972
973
465db791
MM
974#define ALU16_XOR(VAL) \
975do { \
976 error("ALU16_XOR"); \
d6fea803
AC
977} while (0)
978
465db791
MM
979#define ALU32_XOR(VAL) \
980do { \
981 alu32_r ^= (VAL); \
982 alu32_c = 0; \
983 alu32_v = 0; \
d6fea803
AC
984} while (0)
985
465db791
MM
986#define ALU64_XOR(VAL) \
987do { \
988 alu64_r ^= (VAL); \
989 alu64_c = 0; \
990 alu64_v = 0; \
d6fea803
AC
991} while (0)
992
993#define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL)
994
995
996
997
465db791
MM
998#define ALU16_AND(VAL) \
999do { \
1000 error("ALU_AND16"); \
d6fea803
AC
1001} while (0)
1002
465db791
MM
1003#define ALU32_AND(VAL) \
1004do { \
1005 alu32_r &= (VAL); \
1006 alu32_r = 0; \
1007 alu32_v = 0; \
d6fea803
AC
1008} while (0)
1009
465db791
MM
1010#define ALU64_AND(VAL) \
1011do { \
1012 alu64_r &= (VAL); \
1013 alu64_r = 0; \
1014 alu64_v = 0; \
d6fea803
AC
1015} while (0)
1016
1017#define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL)
1018
1019
1020
1021
465db791
MM
1022#define ALU16_NOT(VAL) \
1023do { \
1024 error("ALU_NOT16"); \
d6fea803
AC
1025} while (0)
1026
465db791
MM
1027#define ALU32_NOT \
1028do { \
1029 alu32_r = ~alu32_r; \
1030 alu32_c = 0; \
1031 alu32_v = 0; \
d6fea803
AC
1032} while (0)
1033
465db791
MM
1034#define ALU64_NOT \
1035do { \
1036 alu64_r = ~alu64_r; \
1037 alu64_c = 0; \
1038 alu64_v = 0; \
d6fea803
AC
1039} while (0)
1040
1041#define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT)
1042
d6fea803 1043#endif
This page took 0.111179 seconds and 4 git commands to generate.