#pragma once #include #include #include #include "status_bits.h" #define SR__RB (1 << 29) #define SR__MD (1 << 30) #define BANK(sr) (((sr) & SR__RB) && ((sr) & SR__MD)) #define REGN(sr, x) (((x) & (1 << 3)) ? (x) : ((x) ^ (BANK(sr) << 4))) #define REG(state, x) ((state)->general_register[REGN((state)->sr.value, (x))]) #define REGN_BANK(sr, x) (((x) & (1 << 3)) ? (x) : ((x) ^ ((!BANK(sr)) << 4))) #define REG_BANK(state, x) ((state)->general_register[REGN_BANK((state)->sr.value, (x))]) static_assert(REGN(0, 0 ) == 0 ); static_assert(REGN(0, 7 ) == 7 ); static_assert(REGN(0, 8 ) == 8 ); static_assert(REGN(0, 15) == 15); static_assert(REGN(SR__MD | SR__RB, 0 ) == 16); static_assert(REGN(SR__MD | SR__RB, 7 ) == 23); static_assert(REGN(SR__MD | SR__RB, 8 ) == 8 ); static_assert(REGN(SR__MD | SR__RB, 15) == 15); static_assert(REGN_BANK(0, 0 ) == 16); static_assert(REGN_BANK(0, 7 ) == 23); static_assert(REGN_BANK(0, 8 ) == 8 ); static_assert(REGN_BANK(0, 15) == 15); static_assert(REGN_BANK(SR__MD | SR__RB, 0 ) == 0 ); static_assert(REGN_BANK(SR__MD | SR__RB, 7 ) == 7 ); static_assert(REGN_BANK(SR__MD | SR__RB, 8 ) == 8 ); static_assert(REGN_BANK(SR__MD | SR__RB, 15) == 15); union floating_point_registers { uint32_t fr[32]; uint32_t fp[16][2]; uint64_t dr[16]; uint32_t fv[8][4]; uint32_t fm[2][16]; }; static_assert((sizeof (union floating_point_registers)) == 32 * 4); #define FR_N(state, x) ((x) ^ ((state)->fpscr.fr << 4)) #define FR_(state, x) ((state)->floating_point_register.fr[FR_N(state, x)]) #define FP_N(state, x) ((x) ^ ((state)->fpscr.fr << 3)) #define FP_(state, x) ((state)->floating_point_register.fp[FP_N(state, x)]) #define DR2_N(state, x) ((x) ^ ((state)->fpscr.fr << 3)) #define DR2_(state, x) ((state)->floating_point_register.dr[DR2_N(state, x)]) #define XD2_N(state, x) ((x) ^ ((!(state)->fpscr.fr) << 3)) #define XD2_(state, x) ((state)->floating_point_register.dr[XD2_N(state, x)]) #define FV4_N(state, x) ((x) ^ ((state)->fpscr.fr << 2)) #define FV4_(state, x) ((state)->floating_point_register.dr[FV4_N(state, x)]) #define XMTRX_N(state) (!(state)->fpscr.fr) #define XMTRX(state) ((state)->floating_point_register.fm[XMTRX_N(state)]) struct architectural_state { uint32_t general_register[24]; // system_register uint32_t mach; uint32_t macl; uint32_t pr[3]; uint32_t pc[3]; union { struct fpscr_bits bits; uint32_t value; } fpscr; uint32_t fpul; // // control_register union { struct sr_bits bits; uint32_t value; } sr; uint32_t ssr; uint32_t spc; uint32_t gbr; uint32_t vbr; uint32_t sgr; uint32_t dbr; // union floating_point_registers floating_point_register; bool is_delay_slot; }; //