diff options
author | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
---|---|---|
committer | Stan Shebs <shebs@codesourcery.com> | 1999-04-16 01:34:07 +0000 |
commit | 071ea11e85eb9d529cc5eb3d35f6247466a21b99 (patch) | |
tree | 5deda65b8d7b04d1f4cbc534c3206d328e1267ec /sim/common/sim-alu.h | |
parent | 1730ec6b1848f0f32154277f788fb29f88d8475b (diff) | |
download | gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.zip gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.gz gdb-071ea11e85eb9d529cc5eb3d35f6247466a21b99.tar.bz2 |
Initial creation of sourceware repository
Diffstat (limited to 'sim/common/sim-alu.h')
-rw-r--r-- | sim/common/sim-alu.h | 1043 |
1 files changed, 0 insertions, 1043 deletions
diff --git a/sim/common/sim-alu.h b/sim/common/sim-alu.h deleted file mode 100644 index 8473680..0000000 --- a/sim/common/sim-alu.h +++ /dev/null @@ -1,1043 +0,0 @@ -/* This file is part of the program psim. - - Copyright (C) 1994-1996, Andrew Cagney <cagney@highland.com.au> - Copyright (C) 1997, Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - */ - - -#ifndef _SIM_ALU_H_ -#define _SIM_ALU_H_ - -#include "symcat.h" - - -/* INTEGER ALU MODULE: - - This module provides an implementation of 2's complement arithmetic - including the recording of carry and overflow status bits. - - - EXAMPLE: - - Code using this module includes it into sim-main.h and then, as a - convention, defines macro's ALU*_END that records the result of any - aritmetic performed. Ex: - - #include "sim-alu.h" - #define ALU32_END(RES) \ - (RES) = ALU32_OVERFLOW_RESULT; \ - carry = ALU32_HAD_CARRY_BORROW; \ - overflow = ALU32_HAD_OVERFLOW - - The macro's are then used vis: - - { - ALU32_BEGIN (GPR[i]); - ALU32_ADDC (GPR[j]); - ALU32_END (GPR[k]); - } - - - NOTES: - - Macros exist for efficiently computing 8, 16, 32 and 64 bit - arithmetic - ALU8_*, ALU16_*, .... In addition, according to - TARGET_WORD_BITSIZE a set of short-hand macros are defined - ALU_* - - Initialization: - - ALU*_BEGIN(ACC): Declare initialize the ALU accumulator with ACC. - - Results: - - The calculation of the final result may be computed a number - of different ways. Three different overflow macro's are - defined, the most efficient one to use depends on which other - outputs from the alu are being used. - - ALU*_RESULT: Generic ALU result output. - - ALU*_HAD_OVERFLOW: Returns a nonzero value if signed overflow - occured. - - ALU*_OVERFLOW_RESULT: If the macro ALU*_HAD_OVERFLOW is being - used this is the most efficient result available. Ex: - - #define ALU16_END(RES) \ - if (ALU16_HAD_OVERFLOW) \ - sim_engine_halt (...); \ - (RES) = ALU16_OVERFLOW_RESULT - - ALU*_HAD_CARRY_BORROW: Returns a nonzero value if unsigned - overflow or underflow (also refered to as carry and borrow) - occured. - - ALU*_CARRY_BORROW_RESULT: If the macro ALU*_HAD_CARRY_BORROW is being - used this is the most efficient result available. Ex: - - #define ALU64_END(RES) \ - State.carry = ALU64_HAD_CARRY_BORROW; \ - (RES) = ALU64_CARRY_BORROW_RESULT - - - Addition: - - ALU*_ADD(VAL): Add VAL to the ALU accumulator. Record any - overflow as well as the final result. - - ALU*_ADDC(VAL): Add VAL to the ALU accumulator. Record any - carry-out or overflow as well as the final result. - - ALU*_ADDC_C(VAL,CI): Add VAL and CI (carry-in). Record any - carry-out or overflow as well as the final result. - - Subtraction: - - ALU*_SUB(VAL): Subtract VAL from the ALU accumulator. Record - any underflow as well as the final result. - - ALU*_SUBC(VAL): Subtract VAL from the ALU accumulator using - negated addition. Record any underflow or carry-out as well - as the final result. - - ALU*_SUBB(VAL): Subtract VAL from the ALU accumulator using - direct subtraction (ACC+~VAL+1). Record any underflow or - borrow-out as well as the final result. - - ALU*_SUBC_X(VAL,CI): Subtract VAL and CI (carry-in) from the - ALU accumulator using extended negated addition (ACC+~VAL+CI). - Record any underflow or carry-out as well as the final result. - - ALU*_SUBB_B(VAL,BI): Subtract VAL and BI (borrow-in) from the - ALU accumulator using direct subtraction. Record any - underflow or borrow-out as well as the final result. - - - */ - - - -/* Twos complement aritmetic - addition/subtraction - carry/borrow - (or you thought you knew the answer to 0-0) - - - - Notation and Properties: - - - Xn denotes the value X stored in N bits. - - MSBn (X): The most significant (sign) bit of X treated as an N bit - value. - - SEXTn (X): The infinite sign extension of X treated as an N bit - value. - - MAXn, MINn: The upper and lower bound of a signed, two's - complement N bit value. - - UMAXn: The upper bound of an unsigned N bit value (the lower - bound is always zero). - - Un: UMAXn + 1. Unsigned arrithmetic is computed `modulo (Un)'. - - X[p]: Is bit P of X. X[0] denotes the least signifant bit. - - ~X[p]: Is the inversion of bit X[p]. Also equal to 1-X[p], - (1+X[p])mod(2). - - - - Addition - Overflow - Introduction: - - - Overflow/Overflow indicates an error in computation of signed - arrithmetic. i.e. given X,Y in [MINn..MAXn]; overflow - indicates that the result X+Y > MAXn or X+Y < MIN_INTx. - - Hardware traditionally implements overflow by computing the XOR of - carry-in/carry-out of the most significant bit of the ALU. Here - other methods need to be found. - - - - Addition - Overflow - method 1: - - - Overflow occures when the sign (most significant bit) of the two N - bit operands is identical but different to the sign of the result: - - Rn = (Xn + Yn) - V = MSBn (~(Xn ^ Yn) & (Rn ^ Xn)) - - - - Addition - Overflow - method 2: - - - The two N bit operands are sign extended to M>N bits and then - added. Overflow occures when SIGN_BIT<n> and SIGN_BIT<m> do not - match. - - Rm = (SEXTn (Xn) + SEXTn (Yn)) - V = MSBn ((Rm >> (M - N)) ^ Rm) - - - - Addition - Overflow - method 3: - - - The two N bit operands are sign extended to M>N bits and then - added. Overflow occures when the result is outside of the sign - extended range [MINn .. MAXn]. - - - - Addition - Overflow - method 4: - - - Given the Result and Carry-out bits, the oVerflow from the addition - of X, Y and carry-In can be computed using the equation: - - Rn = (Xn + Yn) - V = (MSBn ((Xn ^ Yn) ^ Rn)) ^ C) - - As shown in the table below: - - I X Y R C | V | X^Y ^R ^C - ---------------+---+------------- - 0 0 0 0 0 | 0 | 0 0 0 - 0 0 1 1 0 | 0 | 1 0 0 - 0 1 0 1 0 | 0 | 1 0 0 - 0 1 1 0 1 | 1 | 0 0 1 - 1 0 0 1 0 | 1 | 0 1 1 - 1 0 1 0 1 | 0 | 1 1 0 - 1 1 0 0 1 | 0 | 1 1 0 - 1 1 1 1 1 | 0 | 0 1 0 - - - - Addition - Carry - Introduction: - - - Carry (poorly named) indicates that an overflow occured for - unsigned N bit addition. i.e. given X, Y in [0..UMAXn] then - carry indicates X+Y > UMAXn or X+Y >= Un. - - The following table lists the output for all given inputs into a - full-adder. - - I X Y R | C - ------------+--- - 0 0 0 0 | 0 - 0 0 1 1 | 0 - 0 1 0 1 | 0 - 0 1 1 0 | 1 - 1 0 0 1 | 0 - 1 0 1 0 | 1 - 1 1 0 0 | 1 - 1 1 1 1 | 1 - - (carry-In, X, Y, Result, Carry-out): - - - - Addition - Carry - method 1: - - - Looking at the terms X, Y and R we want an equation for C. - - XY\R 0 1 - +------- - 00 | 0 0 - 01 | 1 0 - 11 | 1 1 - 10 | 1 0 - - This giving us the sum-of-prod equation: - - MSBn ((Xn & Yn) | (Xn & ~Rn) | (Yn & ~Rn)) - - Verifying: - - I X Y R | C | X&Y X&~R Y&~R - ------------+---+--------------- - 0 0 0 0 | 0 | 0 0 0 - 0 0 1 1 | 0 | 0 0 0 - 0 1 0 1 | 0 | 0 0 0 - 0 1 1 0 | 1 | 1 1 1 - 1 0 0 1 | 0 | 0 0 0 - 1 0 1 0 | 1 | 0 0 1 - 1 1 0 0 | 1 | 0 1 0 - 1 1 1 1 | 1 | 1 0 0 - - - - Addition - Carry - method 2: - - - Given two signed N bit numbers, a carry can be detected by treating - the numbers as N bit unsigned and adding them using M>N unsigned - arrithmetic. Carry is indicated by bit (1 << N) being set (result - >= 2**N). - - - - Addition - Carry - method 3: - - - Given the oVerflow bit. The carry can be computed from: - - (~R&V) | (R&V) - - - - Addition - Carry - method 4: - - Given two signed numbers. Treating them as unsigned we have: - - 0 <= X < Un, 0 <= Y < Un - ==> X + Y < 2 Un - - Consider Y when carry occures: - - X + Y >= Un, Y < Un - ==> (Un - X) <= Y < Un # re-arange - ==> Un <= X + Y < Un + X < 2 Un # add Xn - ==> 0 <= (X + Y) mod Un < X mod Un - - or when carry as occured: - - (X + Y) mod Un < X mod Un - - Consider Y when carry does not occure: - - X + Y < Un - have X < Un, Y >= 0 - ==> X <= X + Y < Un - ==> X mod Un <= (X + Y) mod Un - - or when carry has not occured: - - ! ( (X + Y) mod Un < X mod Un) - - - - Subtraction - Introduction - - - There are two different ways of computing the signed two's - complement difference of two numbers. The first is based on - negative addition, the second on direct subtraction. - - - - Subtraction - Carry - Introduction - Negated Addition - - - The equation X - Y can be computed using: - - X + (-Y) - ==> X + ~Y + 1 # -Y = ~Y + 1 - - In addition to the result, the equation produces Carry-out. For - succeeding extended prrcision calculations, the more general - equation can be used: - - C[p]:R[p] = X[p] + ~Y[p] + C[p-1] - where C[0]:R[0] = X[0] + ~Y[0] + 1 - - - - Subtraction - Borrow - Introduction - Direct Subtraction - - - The alternative to negative addition is direct subtraction where - `X-Y is computed directly. In addition to the result of the - calculation, a Borrow bit is produced. In general terms: - - B[p]:R[p] = X[p] - Y[p] - B[p-1] - where B[0]:R[0] = X[0] - Y[0] - - The Borrow bit is the complement of the Carry bit produced by - Negated Addition above. A dodgy proof follows: - - Case 0: - C[0]:R[0] = X[0] + ~Y[0] + 1 - ==> C[0]:R[0] = X[0] + 1 - Y[0] + 1 # ~Y[0] = (1 - Y[0])? - ==> C[0]:R[0] = 2 + X[0] - Y[0] - ==> C[0]:R[0] = 2 + B[0]:R[0] - ==> C[0]:R[0] = (1 + B[0]):R[0] - ==> C[0] = ~B[0] # (1 + B[0]) mod 2 = ~B[0]? - - Case P: - C[p]:R[p] = X[p] + ~Y[p] + C[p-1] - ==> C[p]:R[p] = X[p] + 1 - Y[0] + 1 - B[p-1] - ==> C[p]:R[p] = 2 + X[p] - Y[0] - B[p-1] - ==> C[p]:R[p] = 2 + B[p]:R[p] - ==> C[p]:R[p] = (1 + B[p]):R[p] - ==> C[p] = ~B[p] - - The table below lists all possible inputs/outputs for a - full-subtractor: - - X Y I | R B - 0 0 0 | 0 0 - 0 0 1 | 1 1 - 0 1 0 | 1 1 - 0 1 1 | 0 1 - 1 0 0 | 1 0 - 1 0 1 | 0 0 - 1 1 0 | 0 0 - 1 1 1 | 1 1 - - - - Subtraction - Method 1 - - - Treating Xn and Yn as unsigned values then a borrow (unsigned - underflow) occures when: - - B = Xn < Yn - ==> C = Xn >= Yn - - */ - - - -/* 8 bit target expressions: - - Since the host's natural bitsize > 8 bits, carry method 2 and - overflow method 2 are used. */ - -#define ALU8_BEGIN(VAL) \ -unsigned alu8_cr = (unsigned8) (VAL); \ -signed alu8_vr = (signed8) (alu8_cr) - -#define ALU8_SET(VAL) \ -alu8_cr = (unsigned8) (VAL); \ -alu8_vr = (signed8) (alu8_cr) - -#define ALU8_SET_CARRY_BORROW(CARRY) \ -do { \ - if (CARRY) \ - alu8_cr |= ((signed)-1) << 8; \ - else \ - alu8_cr &= 0xff; \ -} while (0) - -#define ALU8_HAD_CARRY_BORROW (alu8_cr & LSBIT32(8)) -#define ALU8_HAD_OVERFLOW (((alu8_vr >> 8) ^ alu8_vr) & LSBIT32 (8-1)) - -#define ALU8_RESULT ((unsigned8) alu8_cr) -#define ALU8_CARRY_BORROW_RESULT ((unsigned8) alu8_cr) -#define ALU8_OVERFLOW_RESULT ((unsigned8) alu8_vr) - -/* #define ALU8_END ????? - target dependant */ - - - -/* 16 bit target expressions: - - Since the host's natural bitsize > 16 bits, carry method 2 and - overflow method 2 are used. */ - -#define ALU16_BEGIN(VAL) \ -signed alu16_cr = (unsigned16) (VAL); \ -unsigned alu16_vr = (signed16) (alu16_cr) - -#define ALU16_SET(VAL) \ -alu16_cr = (unsigned16) (VAL); \ -alu16_vr = (signed16) (alu16_cr) - -#define ALU16_SET_CARRY_BORROW(CARRY) \ -do { \ - if (CARRY) \ - alu16_cr |= ((signed)-1) << 16; \ - else \ - alu16_cr &= 0xffff; \ -} while (0) - -#define ALU16_HAD_CARRY_BORROW (alu16_cr & LSBIT32(16)) -#define ALU16_HAD_OVERFLOW (((alu16_vr >> 16) ^ alu16_vr) & LSBIT32 (16-1)) - -#define ALU16_RESULT ((unsigned16) alu16_cr) -#define ALU16_CARRY_BORROW_RESULT ((unsigned16) alu16_cr) -#define ALU16_OVERFLOW_RESULT ((unsigned16) alu16_vr) - -/* #define ALU16_END ????? - target dependant */ - - - -/* 32 bit target expressions: - - Since most hosts do not support 64 (> 32) bit arrithmetic, carry - method 4 and overflow method 4 are used. */ - -#define ALU32_BEGIN(VAL) \ -unsigned32 alu32_r = (VAL); \ -int alu32_c = 0; \ -int alu32_v = 0 - -#define ALU32_SET(VAL) \ -alu32_r = (VAL); \ -alu32_c = 0; \ -alu32_v = 0 - -#define ALU32_SET_CARRY_BORROW(CARRY) alu32_c = (CARRY) - -#define ALU32_HAD_CARRY_BORROW (alu32_c) -#define ALU32_HAD_OVERFLOW (alu32_v) - -#define ALU32_RESULT (alu32_r) -#define ALU32_CARRY_BORROW_RESULT (alu32_r) -#define ALU32_OVERFLOW_RESULT (alu32_r) - - - -/* 64 bit target expressions: - - Even though the host typically doesn't support native 64 bit - arrithmetic, it is still used. */ - -#define ALU64_BEGIN(VAL) \ -natural64 alu64_r = (VAL); \ -int alu64_c = 0; \ -int alu64_v = 0 - -#define ALU64_SET(VAL) \ -alu64_r = (VAL); \ -alu64_c = 0; \ -alu64_v = 0 - -#define ALU64_SET_CARRY_BORROW(CARRY) alu64_c = (CARRY) - -#define ALU64_HAD_CARRY_BORROW (alu64_c) -#define ALU64_HAD_OVERFLOW (alu64_v) - -#define ALU64_RESULT (alu64_r) -#define ALU64_CARRY_BORROW_RESULT (alu64_r) -#define ALU64_OVERFLOW_RESULT (alu64_r) - - - -/* Generic versions of above macros */ - -#define ALU_BEGIN XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_BEGIN) -#define ALU_SET XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET) -#define ALU_SET_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SET_CARRY) - -#define ALU_HAD_OVERFLOW XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_OVERFLOW) -#define ALU_HAD_CARRY XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_HAD_CARRY) - -#define ALU_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_RESULT) -#define ALU_OVERFLOW_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OVERFLOW_RESULT) -#define ALU_CARRY_RESULT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_CARRY_RESULT) - - - -/* Basic operation - add (overflowing) */ - -#define ALU8_ADD(VAL) \ -do { \ - unsigned8 alu8add_val = (VAL); \ - ALU8_ADDC (alu8add_val); \ -} while (0) - -#define ALU16_ADD(VAL) \ -do { \ - unsigned16 alu16add_val = (VAL); \ - ALU16_ADDC (alu8add_val); \ -} while (0) - -#define ALU32_ADD(VAL) \ -do { \ - unsigned32 alu32add_val = (VAL); \ - ALU32_ADDC (alu32add_val); \ -} while (0) - -#define ALU64_ADD(VAL) \ -do { \ - unsigned64 alu64add_val = (unsigned64) (VAL); \ - ALU64_ADDC (alu64add_val); \ -} while (0) - -#define ALU_ADD XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADD) - - - -/* Basic operation - add carrying (and overflowing) */ - -#define ALU8_ADDC(VAL) \ -do { \ - unsigned8 alu8addc_val = (VAL); \ - alu8_cr += (unsigned8)(alu8addc_val); \ - alu8_vr += (signed8)(alu8addc_val); \ -} while (0) - -#define ALU16_ADDC(VAL) \ -do { \ - unsigned16 alu16addc_val = (VAL); \ - alu16_cr += (unsigned16)(alu16addc_val); \ - alu16_vr += (signed16)(alu16addc_val); \ -} while (0) - -#define ALU32_ADDC(VAL) \ -do { \ - unsigned32 alu32addc_val = (VAL); \ - unsigned32 alu32addc_sign = alu32addc_val ^ alu32_r; \ - alu32_r += (alu32addc_val); \ - alu32_c = (alu32_r < alu32addc_val); \ - alu32_v = ((alu32addc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \ -} while (0) - -#define ALU64_ADDC(VAL) \ -do { \ - unsigned64 alu64addc_val = (unsigned64) (VAL); \ - unsigned64 alu64addc_sign = alu64addc_val ^ alu64_r; \ - alu64_r += (alu64addc_val); \ - alu64_c = (alu64_r < alu64addc_val); \ - alu64_v = ((alu64addc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63; \ -} while (0) - -#define ALU_ADDC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC) - - - -/* Compound operation - add carrying (and overflowing) with carry-in */ - -#define ALU8_ADDC_C(VAL,C) \ -do { \ - unsigned8 alu8addcc_val = (VAL); \ - unsigned8 alu8addcc_c = (C); \ - alu8_cr += (unsigned)(unsigned8)alu8addcc_val + alu8addcc_c; \ - alu8_vr += (signed)(signed8)(alu8addcc_val) + alu8addcc_c; \ -} while (0) - -#define ALU16_ADDC_C(VAL,C) \ -do { \ - unsigned16 alu16addcc_val = (VAL); \ - unsigned16 alu16addcc_c = (C); \ - alu16_cr += (unsigned)(unsigned16)alu16addcc_val + alu16addcc_c; \ - alu16_vr += (signed)(signed16)(alu16addcc_val) + alu16addcc_c; \ -} while (0) - -#define ALU32_ADDC_C(VAL,C) \ -do { \ - unsigned32 alu32addcc_val = (VAL); \ - unsigned32 alu32addcc_c = (C); \ - unsigned32 alu32addcc_sign = (alu32addcc_val ^ alu32_r); \ - alu32_r += (alu32addcc_val + alu32addcc_c); \ - alu32_c = ((alu32_r < alu32addcc_val) \ - || (alu32addcc_c && alu32_r == alu32addcc_val)); \ - alu32_v = ((alu32addcc_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31;\ -} while (0) - -#define ALU64_ADDC_C(VAL,C) \ -do { \ - unsigned64 alu64addcc_val = (VAL); \ - unsigned64 alu64addcc_c = (C); \ - unsigned64 alu64addcc_sign = (alu64addcc_val ^ alu64_r); \ - alu64_r += (alu64addcc_val + alu64addcc_c); \ - alu64_c = ((alu64_r < alu64addcc_val) \ - || (alu64addcc_c && alu64_r == alu64addcc_val)); \ - alu64_v = ((alu64addcc_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 63;\ -} while (0) - -#define ALU_ADDC_C XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_ADDC_C) - - - -/* Basic operation - subtract (overflowing) */ - -#define ALU8_SUB(VAL) \ -do { \ - unsigned8 alu8sub_val = (VAL); \ - ALU8_ADDC_C (~alu8sub_val, 1); \ -} while (0) - -#define ALU16_SUB(VAL) \ -do { \ - unsigned16 alu16sub_val = (VAL); \ - ALU16_ADDC_C (~alu16sub_val, 1); \ -} while (0) - -#define ALU32_SUB(VAL) \ -do { \ - unsigned32 alu32sub_val = (VAL); \ - ALU32_ADDC_C (~alu32sub_val, 1); \ -} while (0) - -#define ALU64_SUB(VAL) \ -do { \ - unsigned64 alu64sub_val = (VAL); \ - ALU64_ADDC_C (~alu64sub_val, 1); \ -} while (0) - -#define ALU_SUB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUB) - - - -/* Basic operation - subtract carrying (and overflowing) */ - -#define ALU8_SUBC(VAL) \ -do { \ - unsigned8 alu8subc_val = (VAL); \ - ALU8_ADDC_C (~alu8subc_val, 1); \ -} while (0) - -#define ALU16_SUBC(VAL) \ -do { \ - unsigned16 alu16subc_val = (VAL); \ - ALU16_ADDC_C (~alu16subc_val, 1); \ -} while (0) - -#define ALU32_SUBC(VAL) \ -do { \ - unsigned32 alu32subc_val = (VAL); \ - ALU32_ADDC_C (~alu32subc_val, 1); \ -} while (0) - -#define ALU64_SUBC(VAL) \ -do { \ - unsigned64 alu64subc_val = (VAL); \ - ALU64_ADDC_C (~alu64subc_val, 1); \ -} while (0) - -#define ALU_SUBC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC) - - - -/* Compound operation - subtract carrying (and overflowing), extended */ - -#define ALU8_SUBC_X(VAL,C) \ -do { \ - unsigned8 alu8subcx_val = (VAL); \ - unsigned8 alu8subcx_c = (C); \ - ALU8_ADDC_C (~alu8subcx_val, alu8subcx_c); \ -} while (0) - -#define ALU16_SUBC_X(VAL,C) \ -do { \ - unsigned16 alu16subcx_val = (VAL); \ - unsigned16 alu16subcx_c = (C); \ - ALU16_ADDC_C (~alu16subcx_val, alu16subcx_c); \ -} while (0) - -#define ALU32_SUBC_X(VAL,C) \ -do { \ - unsigned32 alu32subcx_val = (VAL); \ - unsigned32 alu32subcx_c = (C); \ - ALU32_ADDC_C (~alu32subcx_val, alu32subcx_c); \ -} while (0) - -#define ALU64_SUBC_X(VAL,C) \ -do { \ - unsigned64 alu64subcx_val = (VAL); \ - unsigned64 alu64subcx_c = (C); \ - ALU64_ADDC_C (~alu64subcx_val, alu64subcx_c); \ -} while (0) - -#define ALU_SUBC_X XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBC_X) - - - -/* Basic operation - subtract borrowing (and overflowing) */ - -#define ALU8_SUBB(VAL) \ -do { \ - unsigned8 alu8subb_val = (VAL); \ - alu8_cr -= (unsigned)(unsigned8)alu8subb_val; \ - alu8_vr -= (signed)(signed8)alu8subb_val; \ -} while (0) - -#define ALU16_SUBB(VAL) \ -do { \ - unsigned16 alu16subb_val = (VAL); \ - alu16_cr -= (unsigned)(unsigned16)alu16subb_val; \ - alu16_vr -= (signed)(signed16)alu16subb_val; \ -} while (0) - -#define ALU32_SUBB(VAL) \ -do { \ - unsigned32 alu32subb_val = (VAL); \ - unsigned32 alu32subb_sign = alu32subb_val ^ alu32_r; \ - alu32_c = (alu32_r < alu32subb_val); \ - alu32_r -= (alu32subb_val); \ - alu32_v = ((alu32subb_sign ^ - (unsigned32)alu32_c) ^ alu32_r) >> 31; \ -} while (0) - -#define ALU64_SUBB(VAL) \ -do { \ - unsigned64 alu64subb_val = (VAL); \ - unsigned64 alu64subb_sign = alu64subb_val ^ alu64_r; \ - alu64_c = (alu64_r < alu64subb_val); \ - alu64_r -= (alu64subb_val); \ - alu64_v = ((alu64subb_sign ^ - (unsigned64)alu64_c) ^ alu64_r) >> 31; \ -} while (0) - -#define ALU_SUBB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB) - - - -/* Compound operation - subtract borrowing (and overflowing) with borrow-in */ - -#define ALU8_SUBB_B(VAL,B) \ -do { \ - unsigned8 alu8subbb_val = (VAL); \ - unsigned8 alu8subbb_b = (B); \ - alu8_cr -= (unsigned)(unsigned8)alu8subbb_val; \ - alu8_cr -= (unsigned)(unsigned8)alu8subbb_b; \ - alu8_vr -= (signed)(signed8)alu8subbb_val + alu8subbb_b; \ -} while (0) - -#define ALU16_SUBB_B(VAL,B) \ -do { \ - unsigned16 alu16subbb_val = (VAL); \ - unsigned16 alu16subbb_b = (B); \ - alu16_cr -= (unsigned)(unsigned16)alu16subbb_val; \ - alu16_cr -= (unsigned)(unsigned16)alu16subbb_b; \ - alu16_vr -= (signed)(signed16)alu16subbb_val + alu16subbb_b; \ -} while (0) - -#define ALU32_SUBB_B(VAL,B) \ -do { \ - unsigned32 alu32subbb_val = (VAL); \ - unsigned32 alu32subbb_b = (B); \ - ALU32_ADDC_C (~alu32subbb_val, !alu32subbb_b); \ - alu32_c = !alu32_c; \ -} while (0) - -#define ALU64_SUBB_B(VAL,B) \ -do { \ - unsigned64 alu64subbb_val = (VAL); \ - unsigned64 alu64subbb_b = (B); \ - ALU64_ADDC_C (~alu64subbb_val, !alu64subbb_b); \ - alu64_c = !alu64_c; \ -} while (0) - -#define ALU_SUBB_B XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_SUBB_B) - - - -/* Basic operation - negate (overflowing) */ - -#define ALU8_NEG() \ -do { \ - signed alu8neg_val = (ALU8_RESULT); \ - ALU8_SET (1); \ - ALU8_ADDC (~alu8neg_val); \ -} while (0) - -#define ALU16_NEG() \ -do { \ - signed alu16neg_val = (ALU16_RESULT); \ - ALU16_SET (1); \ - ALU16_ADDC (~alu16neg_val); \ -} while (0) - -#define ALU32_NEG() \ -do { \ - unsigned32 alu32neg_val = (ALU32_RESULT); \ - ALU32_SET (1); \ - ALU32_ADDC (~alu32neg_val); \ -} while(0) - -#define ALU64_NEG() \ -do { \ - unsigned64 alu64neg_val = (ALU64_RESULT); \ - ALU64_SET (1); \ - ALU64_ADDC (~alu64neg_val); \ -} while (0) - -#define ALU_NEG XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEG) - - - - -/* Basic operation - negate carrying (and overflowing) */ - -#define ALU8_NEGC() \ -do { \ - signed alu8negc_val = (ALU8_RESULT); \ - ALU8_SET (1); \ - ALU8_ADDC (~alu8negc_val); \ -} while (0) - -#define ALU16_NEGC() \ -do { \ - signed alu16negc_val = (ALU16_RESULT); \ - ALU16_SET (1); \ - ALU16_ADDC (~alu16negc_val); \ -} while (0) - -#define ALU32_NEGC() \ -do { \ - unsigned32 alu32negc_val = (ALU32_RESULT); \ - ALU32_SET (1); \ - ALU32_ADDC (~alu32negc_val); \ -} while(0) - -#define ALU64_NEGC() \ -do { \ - unsigned64 alu64negc_val = (ALU64_RESULT); \ - ALU64_SET (1); \ - ALU64_ADDC (~alu64negc_val); \ -} while (0) - -#define ALU_NEGC XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGC) - - - - -/* Basic operation - negate borrowing (and overflowing) */ - -#define ALU8_NEGB() \ -do { \ - signed alu8negb_val = (ALU8_RESULT); \ - ALU8_SET (0); \ - ALU8_SUBB (alu8negb_val); \ -} while (0) - -#define ALU16_NEGB() \ -do { \ - signed alu16negb_val = (ALU16_RESULT); \ - ALU16_SET (0); \ - ALU16_SUBB (alu16negb_val); \ -} while (0) - -#define ALU32_NEGB() \ -do { \ - unsigned32 alu32negb_val = (ALU32_RESULT); \ - ALU32_SET (0); \ - ALU32_SUBB (alu32negb_val); \ -} while(0) - -#define ALU64_NEGB() \ -do { \ - unsigned64 alu64negb_val = (ALU64_RESULT); \ - ALU64_SET (0); \ - ALU64_SUBB (alu64negb_val); \ -} while (0) - -#define ALU_NEGB XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NEGB) - - - - -/* Other */ - -#define ALU8_OR(VAL) \ -do { \ - error("ALU16_OR"); \ -} while (0) - -#define ALU16_OR(VAL) \ -do { \ - error("ALU16_OR"); \ -} while (0) - -#define ALU32_OR(VAL) \ -do { \ - alu32_r |= (VAL); \ - alu32_c = 0; \ - alu32_v = 0; \ -} while (0) - -#define ALU64_OR(VAL) \ -do { \ - alu64_r |= (VAL); \ - alu64_c = 0; \ - alu64_v = 0; \ -} while (0) - -#define ALU_OR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_OR)(VAL) - - - -#define ALU16_XOR(VAL) \ -do { \ - error("ALU16_XOR"); \ -} while (0) - -#define ALU32_XOR(VAL) \ -do { \ - alu32_r ^= (VAL); \ - alu32_c = 0; \ - alu32_v = 0; \ -} while (0) - -#define ALU64_XOR(VAL) \ -do { \ - alu64_r ^= (VAL); \ - alu64_c = 0; \ - alu64_v = 0; \ -} while (0) - -#define ALU_XOR(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_XOR)(VAL) - - - - -#define ALU16_AND(VAL) \ -do { \ - error("ALU_AND16"); \ -} while (0) - -#define ALU32_AND(VAL) \ -do { \ - alu32_r &= (VAL); \ - alu32_r = 0; \ - alu32_v = 0; \ -} while (0) - -#define ALU64_AND(VAL) \ -do { \ - alu64_r &= (VAL); \ - alu64_r = 0; \ - alu64_v = 0; \ -} while (0) - -#define ALU_AND(VAL) XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_AND)(VAL) - - - - -#define ALU16_NOT(VAL) \ -do { \ - error("ALU_NOT16"); \ -} while (0) - -#define ALU32_NOT \ -do { \ - alu32_r = ~alu32_r; \ - alu32_c = 0; \ - alu32_v = 0; \ -} while (0) - -#define ALU64_NOT \ -do { \ - alu64_r = ~alu64_r; \ - alu64_c = 0; \ - alu64_v = 0; \ -} while (0) - -#define ALU_NOT XCONCAT3(ALU,WITH_TARGET_WORD_BITSIZE,_NOT) - -#endif |