Files
Xenia-Canary/src/xenia/cpu/ppc/ppc_decode_data.h
2020-02-11 06:45:57 -06:00

702 lines
18 KiB
C++

/**
******************************************************************************
* 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 <cstdint>
#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 {
uint32_t LEV() const { return bits_.LEV; }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 5;
uint32_t LEV : 7;
uint32_t : 20;
} bits_;
};
};
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<int32_t>(XEEXTS16(DS())); }
int32_t SIMM() const { return d(); }
uint32_t UIMM() const { return static_cast<uint32_t>(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<int32_t>(XEEXTS16(DS() << 2)); }
private:
uint32_t address_;
union {
uint32_t value_;
struct {
uint32_t : 2;
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<uint32_t>(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<uint32_t>(XEEXTS26(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<int32_t>(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<int32_t>(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_