#ifndef _SIM_ALU_H_
#define _SIM_ALU_H_
#include "symcat.h"
#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 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 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)
#define ALU64_BEGIN(VAL) \
unsigned64 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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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)
#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