OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [VER_5_3/] [gdb-5.3/] [sim/] [common/] [sim-alu.h] - Blame information for rev 1783

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.