1/* The common simulator framework for GDB, the GNU Debugger.
2
3   Copyright 2002, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
4
5   Contributed by Andrew Cagney and Red Hat.
6
7   This file is part of GDB.
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; either version 3 of the License, or
12   (at your option) any later version.
13
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License for more details.
18
19   You should have received a copy of the GNU General Public License
20   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
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   arithmetic 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   	occurred.
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 referred to as carry and borrow)
88   	occurred.
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 arithmetic - 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 arithmetic is computed `modulo (Un)'.
158
159   X[p]: Is bit P of X.  X[0] denotes the least significant 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   arithmetic.  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 occurs 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 occurs 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 occurs 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 occurred 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   arithmetic.  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 occurs:
318
319		X + Y >= Un, Y < Un
320	==>	(Un - X) <= Y < Un               # rearrange
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 occurred:
325
326               (X + Y) mod Un < X mod Un
327
328   Consider Y when carry does not occur:
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 occurred:
336
337	        ! ( (X + Y) mod Un < X mod Un)
338
339   hence we get carry by computing in N bit unsigned arithmetic.
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 precision 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) occurs 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) \
434unsigned alu8_cr = (unsigned8) (VAL); \
435signed alu8_vr = (signed8) (alu8_cr)
436
437#define ALU8_SET(VAL) \
438alu8_cr = (unsigned8) (VAL); \
439alu8_vr = (signed8) (alu8_cr)
440
441#define ALU8_SET_CARRY_BORROW(CARRY)					\
442do {									\
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) \
466signed alu16_cr = (unsigned16) (VAL); \
467unsigned alu16_vr = (signed16) (alu16_cr)
468
469#define ALU16_SET(VAL) \
470alu16_cr = (unsigned16) (VAL); \
471alu16_vr = (signed16) (alu16_cr)
472
473#define ALU16_SET_CARRY_BORROW(CARRY)					\
474do {									\
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 arithmetic, carry
495   method 4 and overflow method 4 are used. */
496
497#define ALU32_BEGIN(VAL) \
498unsigned32 alu32_r = (VAL); \
499int alu32_c = 0; \
500int alu32_v = 0
501
502#define ALU32_SET(VAL) \
503alu32_r = (VAL); \
504alu32_c = 0; \
505alu32_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   arithmetic, it is still used. */
522
523#define ALU64_BEGIN(VAL) \
524unsigned64 alu64_r = (VAL); \
525int alu64_c = 0; \
526int alu64_v = 0
527
528#define ALU64_SET(VAL) \
529alu64_r = (VAL); \
530alu64_c = 0; \
531alu64_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)							\
562do {									\
563  unsigned8 alu8add_val = (VAL);					\
564  ALU8_ADDC (alu8add_val);						\
565} while (0)
566
567#define ALU16_ADD(VAL)							\
568do {									\
569  unsigned16 alu16add_val = (VAL);					\
570  ALU16_ADDC (alu8add_val);						\
571} while (0)
572
573#define ALU32_ADD(VAL)							\
574do {									\
575  unsigned32 alu32add_val = (VAL);					\
576  ALU32_ADDC (alu32add_val);						\
577} while (0)
578
579#define ALU64_ADD(VAL)							\
580do {									\
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)							\
592do {									\
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)							\
599do {									\
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)							\
606do {									\
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)							\
615do {									\
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)						\
630do {									\
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)						\
638do {									\
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)						\
646do {									\
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)						\
657do {									\
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)							\
674do {									\
675  unsigned8 alu8sub_val = (VAL);					\
676  ALU8_ADDC_C (~alu8sub_val, 1);					\
677} while (0)
678
679#define ALU16_SUB(VAL)							\
680do {									\
681  unsigned16 alu16sub_val = (VAL);					\
682  ALU16_ADDC_C (~alu16sub_val, 1);					\
683} while (0)
684
685#define ALU32_SUB(VAL)							\
686do {									\
687  unsigned32 alu32sub_val = (VAL);					\
688  ALU32_ADDC_C (~alu32sub_val, 1);					\
689} while (0)
690
691#define ALU64_SUB(VAL)							\
692do {									\
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)							\
704do {									\
705  unsigned8 alu8subc_val = (VAL);					\
706  ALU8_ADDC_C (~alu8subc_val, 1);					\
707} while (0)
708
709#define ALU16_SUBC(VAL)							\
710do {									\
711  unsigned16 alu16subc_val = (VAL);					\
712  ALU16_ADDC_C (~alu16subc_val, 1);					\
713} while (0)
714
715#define ALU32_SUBC(VAL)							\
716do {									\
717  unsigned32 alu32subc_val = (VAL);					\
718  ALU32_ADDC_C (~alu32subc_val, 1);					\
719} while (0)
720
721#define ALU64_SUBC(VAL)							\
722do {									\
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)						\
734do {									\
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)						\
741do {									\
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)						\
748do {									\
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)						\
755do {									\
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)							\
768do {									\
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)							\
775do {									\
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)							\
782do {									\
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)							\
791do {									\
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)						\
806do {									\
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)						\
815do {									\
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)						\
824do {									\
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)						\
832do {									\
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()							\
846do {									\
847  signed alu8neg_val = (ALU8_RESULT);					\
848  ALU8_SET (1);								\
849  ALU8_ADDC (~alu8neg_val);						\
850} while (0)
851
852#define ALU16_NEG()							\
853do {									\
854  signed alu16neg_val = (ALU16_RESULT);				\
855  ALU16_SET (1);							\
856  ALU16_ADDC (~alu16neg_val);						\
857} while (0)
858
859#define ALU32_NEG()							\
860do {									\
861  unsigned32 alu32neg_val = (ALU32_RESULT);				\
862  ALU32_SET (1);							\
863  ALU32_ADDC (~alu32neg_val);						\
864} while(0)
865
866#define ALU64_NEG()							\
867do {									\
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()							\
881do {									\
882  signed alu8negc_val = (ALU8_RESULT);					\
883  ALU8_SET (1);								\
884  ALU8_ADDC (~alu8negc_val);						\
885} while (0)
886
887#define ALU16_NEGC()							\
888do {									\
889  signed alu16negc_val = (ALU16_RESULT);				\
890  ALU16_SET (1);							\
891  ALU16_ADDC (~alu16negc_val);						\
892} while (0)
893
894#define ALU32_NEGC()							\
895do {									\
896  unsigned32 alu32negc_val = (ALU32_RESULT);				\
897  ALU32_SET (1);							\
898  ALU32_ADDC (~alu32negc_val);						\
899} while(0)
900
901#define ALU64_NEGC()							\
902do {									\
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()							\
916do {									\
917  signed alu8negb_val = (ALU8_RESULT);					\
918  ALU8_SET (0);								\
919  ALU8_SUBB (alu8negb_val);						\
920} while (0)
921
922#define ALU16_NEGB()							\
923do {									\
924  signed alu16negb_val = (ALU16_RESULT);				\
925  ALU16_SET (0);							\
926  ALU16_SUBB (alu16negb_val);						\
927} while (0)
928
929#define ALU32_NEGB()							\
930do {									\
931  unsigned32 alu32negb_val = (ALU32_RESULT);				\
932  ALU32_SET (0);							\
933  ALU32_SUBB (alu32negb_val);						\
934} while(0)
935
936#define ALU64_NEGB()							\
937do {									\
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)							\
951do {									\
952  error("ALU16_OR");							\
953} while (0)
954
955#define ALU16_OR(VAL)							\
956do {									\
957  error("ALU16_OR");							\
958} while (0)
959
960#define ALU32_OR(VAL)							\
961do {									\
962  alu32_r |= (VAL);							\
963  alu32_c = 0;								\
964  alu32_v = 0;								\
965} while (0)
966
967#define ALU64_OR(VAL)							\
968do {									\
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)							\
979do {									\
980  error("ALU16_XOR");							\
981} while (0)
982
983#define ALU32_XOR(VAL)							\
984do {									\
985  alu32_r ^= (VAL);							\
986  alu32_c = 0;								\
987  alu32_v = 0;								\
988} while (0)
989
990#define ALU64_XOR(VAL)							\
991do {									\
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)							\
1003do {									\
1004  error("ALU_AND16");							\
1005} while (0)
1006
1007#define ALU32_AND(VAL)							\
1008do {									\
1009  alu32_r &= (VAL);							\
1010  alu32_r = 0;								\
1011  alu32_v = 0;								\
1012} while (0)
1013
1014#define ALU64_AND(VAL)							\
1015do {									\
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)							\
1027do {									\
1028  error("ALU_NOT16");							\
1029} while (0)
1030
1031#define ALU32_NOT							\
1032do {									\
1033  alu32_r = ~alu32_r;							\
1034  alu32_c = 0;								\
1035  alu32_v = 0;								\
1036} while (0)
1037
1038#define ALU64_NOT							\
1039do {									\
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
1048