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