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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [sim/] [common/] [sim-alu.h] - Blame information for rev 1774

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

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

powered by: WebSVN 2.1.0

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