#pragma once #include "Emu/CPU/CPUInstrTable.h" enum CodeFieldType { FIELD_IMM, FIELD_R_GPR, FIELD_R_FPR, FIELD_R_VPR, FIELD_R_CR, FIELD_BRANCH, }; template class CodeField : public CodeFieldBase { static_assert(from <= to, "too big 'from' value"); static_assert(to <= 31, "too big 'to' value"); public: CodeField(CodeFieldType type = FIELD_IMM) : CodeFieldBase(type) { } static const u32 size = to - from + 1; static const u32 shift = 31 - to; static const u32 mask = ((1ULL << ((to - from) + 1)) - 1) << shift; static __forceinline void encode(u32& data, u32 value) { data &= ~mask; data |= (value << shift) & mask; } static __forceinline u32 decode(u32 data) { return (data & mask) >> shift; } virtual u32 operator ()(u32 data) const { return decode(data); } virtual void operator()(u32& data, u32 value) const { encode(data, value); } }; static CodeField<0, 31> GetCode; template class DoubleCodeField : public CodeField { static_assert(from2 <= to2, "too big from2 value"); static_assert(to2 <= 31, "too big to2 value"); public: DoubleCodeField(CodeFieldType type = FIELD_IMM) : CodeField(type) { } static const u32 shift2 = 31 - to2; static const u32 mask2 = ((1 << ((to2 - from2) + 1)) - 1) << shift2; static __forceinline void encode(u32& data, u32 value) { data &= ~(CodeField::mask | mask2); data |= ((value << CodeField::shift) & CodeField::mask) | (((value >> offset) << shift2) & mask2); } static __forceinline u32 decode(u32 data) { return ((data & CodeField::mask) >> CodeField::shift) | (((data & mask2) >> shift2) << offset); } virtual u32 operator ()(u32 data) const { return decode(data); } virtual void operator()(u32& data, u32 value) const { encode(data, value); } }; template class CodeFieldSigned : public CodeField { public: CodeFieldSigned(CodeFieldType type = FIELD_IMM) : CodeField(type) { } static const int size = _size; static __forceinline u32 decode(u32 data) { return sign((data & CodeField::mask) >> CodeField::shift); } virtual u32 operator ()(u32 data) const { return decode(data); } }; template class CodeFieldOffset : public CodeField { static const int offset = _offset; public: CodeFieldOffset(CodeFieldType type = FIELD_IMM) : CodeField(type) { } static __forceinline u32 decode(u32 data) { return ((data & CodeField::mask) >> CodeField::shift) << offset; } static __forceinline void encode(u32& data, u32 value) { data &= ~CodeField::mask; data |= ((value >> offset) << CodeField::shift) & CodeField::mask; } virtual u32 operator ()(u32 data) const { return decode(data); } virtual void operator ()(u32& data, u32 value) const { return encode(data, value); } }; template class CodeFieldSignedOffset : public CodeFieldSigned { static const int offset = _offset; public: CodeFieldSignedOffset(CodeFieldType type = FIELD_IMM) : CodeFieldSigned(type) { } static __forceinline u32 decode(u32 data) { return sign((data & CodeField::mask) >> CodeField::shift) << offset; } static __forceinline void encode(u32& data, u32 value) { data &= ~CodeField::mask; data |= ((value >> offset) << CodeField::shift) & CodeField::mask; } virtual u32 operator ()(u32 data) const { return decode(data); } virtual void operator ()(u32& data, u32 value) const { return encode(data, value); } };