1 /* 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 0 0 0 0 0 | 0 | 0 0 0 227 0 0 1 1 0 | 0 | 1 0 0 228 0 1 0 1 0 | 0 | 1 0 0 229 0 1 1 0 1 | 1 | 0 0 1 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 0 0 0 0 | 0 250 0 0 1 1 | 0 251 0 1 0 1 | 0 252 0 1 1 0 | 1 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 0 0 0 0 | 0 | 0 0 0 283 0 0 1 1 | 0 | 0 0 0 284 0 1 0 1 | 0 | 0 0 0 285 0 1 1 0 | 1 | 1 1 1 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 0 <= X < Un, 0 <= Y < Un 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 0 0 0 | 0 0 407 0 0 1 | 1 1 408 0 1 0 | 1 1 409 0 1 1 | 0 1 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 1050