/** ****************************************************************************** * Xenia : Xbox 360 Emulator Research Project * ****************************************************************************** * Copyright 2015 Ben Vanik. All rights reserved. * * Released under the BSD license - see LICENSE in the root for more details. * ****************************************************************************** */ #ifndef XENIA_CPU_PPC_PPC_DECODE_DATA_H_ #define XENIA_CPU_PPC_PPC_DECODE_DATA_H_ #include #include "xenia/base/math.h" #include "xenia/base/string_buffer.h" #include "xenia/cpu/ppc/ppc_instr.h" #include "xenia/cpu/ppc/ppc_opcode_info.h" namespace xe { namespace cpu { namespace ppc { constexpr int64_t XEEXTS16(uint32_t v) { return (int64_t)((int16_t)v); } constexpr int64_t XEEXTS26(uint32_t v) { return (int64_t)(v & 0x02000000 ? (int32_t)v | 0xFC000000 : (int32_t)(v)); } constexpr uint64_t XEEXTZ16(uint32_t v) { return (uint64_t)((uint16_t)v); } static inline uint64_t XEMASK(uint32_t mstart, uint32_t mstop) { // if mstart ≤ mstop then // mask[mstart:mstop] = ones // mask[all other bits] = zeros // else // mask[mstart:63] = ones // mask[0:mstop] = ones // mask[all other bits] = zeros mstart &= 0x3F; mstop &= 0x3F; uint64_t value = (UINT64_MAX >> mstart) ^ ((mstop >= 63) ? 0 : UINT64_MAX >> (mstop + 1)); return mstart <= mstop ? value : ~value; } struct PPCDecodeData { struct FormatSC {}; struct FormatD { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } uint32_t RS() const { return RT(); } uint32_t FD() const { return RT(); } uint32_t FS() const { return RT(); } uint32_t TO() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t RA0() const { return RA(); } uint32_t DS() const { return bits_.DS; } int32_t d() const { return static_cast(XEEXTS16(DS())); } int32_t SIMM() const { return d(); } uint32_t UIMM() const { return static_cast(XEEXTZ16(DS())); } uint32_t CRFD() const { return bits_.RT >> 2; } uint32_t L() const { return bits_.RT & 0x1; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t DS : 16; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatDS { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } uint32_t RS() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t RA0() const { return RA(); } uint32_t DS() const { return bits_.DS; } int32_t ds() const { return static_cast(XEEXTS16(DS() << 2)); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t DS : 14; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatB { uint32_t BO() const { return bits_.BO; } uint32_t BI() const { return bits_.BI; } uint32_t BD() const { return bits_.BD; } uint32_t ADDR() const { return static_cast(XEEXTS16(BD() << 2)) + (AA() ? 0 : address_); } bool AA() const { return bits_.AA ? true : false; } bool LK() const { return bits_.LK ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t LK : 1; uint32_t AA : 1; uint32_t BD : 14; uint32_t BI : 5; uint32_t BO : 5; uint32_t : 6; } bits_; }; }; struct FormatI { uint32_t LI() const { return bits_.LI; } uint32_t ADDR() const { return static_cast(XEEXTS16(LI() << 2)) + (AA() ? 0 : address_); } bool AA() const { return bits_.AA ? true : false; } bool LK() const { return bits_.LK ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t LK : 1; uint32_t AA : 1; uint32_t LI : 24; uint32_t : 6; } bits_; }; }; struct FormatX { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } uint32_t RS() const { return RT(); } uint32_t FD() const { return RT(); } uint32_t FS() const { return RT(); } uint32_t VD() const { return RT(); } uint32_t VS() const { return RT(); } uint32_t TO() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t RA0() const { return RA(); } uint32_t FA() const { return RA(); } uint32_t RB() const { return bits_.RB; } uint32_t FB() const { return RB(); } uint32_t SH() const { return RB(); } uint32_t IMM() const { return RB(); } bool Rc() const { return bits_.Rc ? true : false; } uint32_t CRFD() const { return bits_.RT >> 2; } uint32_t L() const { return bits_.RT & 0x1; } uint32_t CRFS() const { return bits_.RA >> 2; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t : 10; uint32_t RB : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatXL { uint32_t BO() const { return bits_.BO; } uint32_t CRBD() const { return BO(); } uint32_t BI() const { return bits_.BI; } uint32_t CRBA() const { return BI(); } uint32_t BB() const { return bits_.BB; } uint32_t CRBB() const { return BB(); } bool LK() const { return bits_.LK ? true : false; } uint32_t CRFD() const { return CRBD() >> 2; } uint32_t CRFS() const { return CRBA() >> 2; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t LK : 1; uint32_t : 10; uint32_t BB : 5; uint32_t BI : 5; uint32_t BO : 5; uint32_t : 6; } bits_; }; }; struct FormatXFX { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } uint32_t RS() const { return RT(); } uint32_t SPR() const { return bits_.SPR; } uint32_t TBR() const { return ((bits_.SPR & 0x1F) << 5) | ((bits_.SPR >> 5) & 0x1F); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t : 1; uint32_t : 10; uint32_t SPR : 10; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatXFL { bool L() const { return bits_.L ? true : false; } uint32_t FM() const { return bits_.FM; } bool W() const { return bits_.W ? true : false; } uint32_t RB() const { return bits_.RB; } uint32_t FB() const { return RB(); } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t : 10; uint32_t RB : 5; uint32_t W : 1; uint32_t FM : 8; uint32_t L : 1; uint32_t : 6; } bits_; }; }; struct FormatXS { uint32_t RT() const { return bits_.RT; } uint32_t RS() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t SH() const { return (bits_.SH5 << 5) | bits_.SH; } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t SH5 : 1; uint32_t : 9; uint32_t SH : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatXO { uint32_t RT() const { return bits_.RT; } uint32_t RD() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t RB() const { return bits_.RB; } bool OE() const { return bits_.OE ? true : false; } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t : 9; uint32_t OE : 1; uint32_t RB : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatA { uint32_t FT() const { return bits_.FT; } uint32_t FD() const { return FT(); } uint32_t FS() const { return FT(); } uint32_t FA() const { return bits_.FA; } uint32_t FB() const { return bits_.FB; } uint32_t FC() const { return bits_.FC; } uint32_t XO() const { return bits_.XO; } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t XO : 5; uint32_t FC : 5; uint32_t FB : 5; uint32_t FA : 5; uint32_t FT : 5; uint32_t : 6; } bits_; }; }; struct FormatM { uint32_t RT() const { return bits_.RT; } uint32_t RS() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t SH() const { return bits_.SH; } uint32_t RB() const { return SH(); } uint32_t MB() const { return bits_.MB; } uint32_t ME() const { return bits_.ME; } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t ME : 5; uint32_t MB : 5; uint32_t SH : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatMD { uint32_t RT() const { return bits_.RT; } uint32_t RS() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t SH() const { return (bits_.SH5 << 5) | bits_.SH; } uint32_t MB() const { return (bits_.MB5 << 5) | bits_.MB; } uint32_t ME() const { return MB(); } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t SH5 : 1; uint32_t : 3; uint32_t MB5 : 1; uint32_t MB : 5; uint32_t SH : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatMDS { uint32_t RT() const { return bits_.RT; } uint32_t RS() const { return RT(); } uint32_t RA() const { return bits_.RA; } uint32_t RB() const { return bits_.RB; } uint32_t MB() const { return (bits_.MB5 << 5) | bits_.MB; } uint32_t ME() const { return MB(); } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t Rc : 1; uint32_t : 4; uint32_t MB5 : 1; uint32_t MB : 5; uint32_t RB : 5; uint32_t RA : 5; uint32_t RT : 5; uint32_t : 6; } bits_; }; }; struct FormatVX { uint32_t VD() const { return bits_.VD; } uint32_t VA() const { return bits_.VA; } uint32_t VB() const { return bits_.VB; } uint32_t UIMM() const { return VA(); } int32_t SIMM() const { return static_cast(XEEXTS16(VA())); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t : 11; uint32_t VB : 5; uint32_t VA : 5; uint32_t VD : 5; uint32_t : 6; } bits_; }; }; struct FormatVC { uint32_t VD() const { return bits_.VD; } uint32_t VA() const { return bits_.VA; } uint32_t VB() const { return bits_.VB; } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t : 10; uint32_t Rc : 1; uint32_t VB : 5; uint32_t VA : 5; uint32_t VD : 5; uint32_t : 6; } bits_; }; }; struct FormatVA { uint32_t VD() const { return bits_.VD; } uint32_t VA() const { return bits_.VA; } uint32_t VB() const { return bits_.VB; } uint32_t VC() const { return bits_.VC; } uint32_t SHB() const { return VC() & 0xF; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t : 6; uint32_t VC : 5; uint32_t VB : 5; uint32_t VA : 5; uint32_t VD : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VA() const { return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 1; uint32_t VA128h : 1; uint32_t : 4; uint32_t VA128H : 1; uint32_t VB128l : 5; uint32_t VA128l : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_1 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VS() const { return VD(); } uint32_t RA() const { return bits_.RA; } uint32_t RA0() const { return RA(); } uint32_t RB() const { return bits_.RB; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t : 2; uint32_t VD128h : 2; uint32_t : 7; uint32_t RB : 5; uint32_t RA : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_2 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VA() const { return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } uint32_t VC() const { return bits_.VC; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 1; uint32_t VA128h : 1; uint32_t VC : 3; uint32_t : 1; uint32_t VA128H : 1; uint32_t VB128l : 5; uint32_t VA128l : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_3 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } uint32_t UIMM() const { return bits_.UIMM; } int32_t SIMM() const { return static_cast(XEEXTS16(bits_.UIMM)); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 7; uint32_t VB128l : 5; uint32_t UIMM : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_4 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } uint32_t IMM() const { return bits_.IMM; } uint32_t z() const { return bits_.z; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 2; uint32_t z : 2; uint32_t : 3; uint32_t VB128l : 5; uint32_t IMM : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_5 { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VA() const { return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } uint32_t SH() const { return bits_.SH; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 1; uint32_t VA128h : 1; uint32_t SH : 4; uint32_t VA128H : 1; uint32_t VB128l : 5; uint32_t VA128l : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_R { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VA() const { return bits_.VA128l | (bits_.VA128h << 5) | (bits_.VA128H << 6); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } bool Rc() const { return bits_.Rc ? true : false; } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 1; uint32_t VA128h : 1; uint32_t Rc : 1; uint32_t : 3; uint32_t VA128H : 1; uint32_t VB128l : 5; uint32_t VA128l : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; struct FormatVX128_P { uint32_t VD() const { return bits_.VD128l | (bits_.VD128h << 5); } uint32_t VB() const { return bits_.VB128l | (bits_.VB128h << 5); } uint32_t UIMM() const { return bits_.PERMl | (bits_.PERMh << 5); } private: uint32_t address_; union { uint32_t value_; struct { uint32_t VB128h : 2; uint32_t VD128h : 2; uint32_t : 2; uint32_t PERMh : 3; uint32_t : 2; uint32_t VB128l : 5; uint32_t PERMl : 5; uint32_t VD128l : 5; uint32_t : 6; } bits_; }; }; union { struct { uint32_t address; uint32_t code; }; FormatSC SC; FormatD D; FormatDS DS; FormatB B; FormatI I; FormatX X; FormatXL XL; FormatXFX XFX; FormatXFL XFL; FormatXS XS; FormatXO XO; FormatA A; FormatM M; FormatMD MD; FormatMDS MDS; FormatX DCBZ; FormatVX VX; FormatVC VC; FormatVA VA; FormatVX128 VX128; FormatVX128_1 VX128_1; FormatVX128_2 VX128_2; FormatVX128_3 VX128_3; FormatVX128_4 VX128_4; FormatVX128_5 VX128_5; FormatVX128_R VX128_R; FormatVX128_P VX128_P; }; }; } // namespace ppc } // namespace cpu } // namespace xe #endif // XENIA_CPU_PPC_PPC_DECODE_DATA_H_