rpcsx/rpcs3/Emu/Cell/SPUDecoder.h

167 lines
4 KiB
C++

#pragma once
#include "Emu/Cell/SPUOpcodes.h"
#include "Emu/Cell/Decoder.h"
#define START_OPCODES_GROUP_(group, reg) \
case(##group##): \
temp=##reg##;\
switch(temp)\
{
#define START_OPCODES_GROUP(group, reg) START_OPCODES_GROUP_(##group##, ##reg##())
#define END_OPCODES_GROUP(group) \
default:\
m_op.UNK(m_code, opcode, temp);\
break;\
}\
break
#define ADD_OPCODE(name, regs) case(##name##):m_op.##name####regs##; return
#define ADD_NULL_OPCODE(name) ADD_OPCODE(##name##, ())
class SPU_Decoder : public Decoder
{
u32 m_code;
SPU_Opcodes& m_op;
OP_REG RC() const { return GetField(4, 10); }
OP_REG RT() const { return GetField(25, 31); }
OP_REG RA() const { return GetField(18, 24); }
OP_REG RB() const { return GetField(11, 17); }
OP_sIMM i7() const { return GetField(11, 17); }
OP_sIMM i10() const { return GetField(8, 17); }
OP_sIMM i16() const { return GetField(9, 24); }
OP_sIMM i18() const { return GetField(7, 24); }
OP_sIMM ROH() const { return GetField(16, 17); }
OP_sIMM ROL() const { return GetField(25, 31); }
OP_sIMM RO() const { return ROL()/* | (ROH() << 8)*/; }
OP_uIMM RR() const { return GetField(0, 10); }
OP_uIMM RRR() const { return GetField(0, 3); }
OP_uIMM RI7() const { return GetField(0, 10); }
OP_uIMM RI10() const { return GetField(0, 7); }
OP_uIMM RI16() const { return GetField(0, 8); }
OP_uIMM RI18() const { return GetField(0, 6); }
__forceinline u32 GetField(const u32 p) const
{
return (m_code >> (31 - p)) & 0x1;
}
__forceinline u32 GetField(const u32 from, const u32 to) const
{
return (m_code >> (31 - to)) & ((1 << ((to - from) + 1)) - 1);
}
OP_sIMM exts18(OP_sIMM i18) const
{
if(i18 & 0x20000) return i18 - 0x40000;
return i18;
}
OP_sIMM exts16(OP_sIMM i16) const
{
return (s32)(s16)i16;
}
OP_sIMM exts10(OP_sIMM i10) const
{
if(i10 & 0x200) return i10 - 0x400;
return i10;
}
OP_sIMM exts7(OP_sIMM i7) const
{
if(i7 & 0x40) return i7 - 0x80;
return i7;
}
public:
SPU_Decoder(SPU_Opcodes& op) : m_op(op)
{
}
~SPU_Decoder()
{
m_op.Exit();
delete &m_op;
}
virtual void Decode(const u32 code)
{
m_code = code;
switch(RR()) //& RI7 //0 - 10
{
ADD_OPCODE(STOP,(GetField(18, 31)));
ADD_OPCODE(LNOP,());
ADD_OPCODE(RDCH,(RT(), RA()));
ADD_OPCODE(RCHCNT,(RT(), RA()));
ADD_OPCODE(SF,(RT(), RA(), RB()));
ADD_OPCODE(SHLI,(RT(), RA(), i7()));
ADD_OPCODE(A,(RT(), RA(), RB()));
ADD_OPCODE(SPU_AND,(RT(), RA(), RB()));
ADD_OPCODE(LQX,(RT(), RA(), RB()));
ADD_OPCODE(WRCH,(RA(), RT()));
ADD_OPCODE(STQX,(RT(), RA(), RB()));
ADD_OPCODE(BI,(RA()));
ADD_OPCODE(BISL,(RT(), RA()));
ADD_OPCODE(HBR,(GetField(11), RO(), RA()));
ADD_OPCODE(CWX,(RT(), RA(), RB()));
ADD_OPCODE(ROTQBY,(RT(), RA(), RB()));
ADD_OPCODE(ROTQBYI,(RT(), RA(), i7()));
ADD_OPCODE(SHLQBYI,(RT(), RA(), i7()));
ADD_OPCODE(SPU_NOP,(RT()));
ADD_OPCODE(CLGT,(RT(), RA(), RB()));
}
switch(RI16()) //0 - 8
{
ADD_OPCODE(BRZ,(RT(), exts16(i16())));
ADD_OPCODE(BRHZ,(RT(), exts16(i16())));
ADD_OPCODE(BRHNZ,(RT(), exts16(i16())));
ADD_OPCODE(STQR,(RT(), i16()));
ADD_OPCODE(BR,(exts16(i16())));
ADD_OPCODE(FSMBI,(RT(), i16()));
ADD_OPCODE(BRSL,(RT(), exts16(i16())));
ADD_OPCODE(IL,(RT(), exts16(i16())));
ADD_OPCODE(LQR,(RT(), exts16(i16())));
}
switch(RI10()) //0 - 7
{
ADD_OPCODE(SPU_ORI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(AI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(AHI,(RT(), RA(), exts10(i10())));
ADD_OPCODE(STQD,(RT(), exts10(i10()) << 4, RA()));
ADD_OPCODE(LQD,(RT(), exts10(i10()) << 4, RA()));
ADD_OPCODE(CLGTI,(RT(), RA(), i10()));
ADD_OPCODE(CLGTHI,(RT(), RA(), i10()));
ADD_OPCODE(CEQI,(RT(), RA(), i10()));
}
switch(RI18()) //0 - 6
{
ADD_OPCODE(HBRR,(RO(), exts16(i16())));
ADD_OPCODE(ILA,(RT(), i18()));
}
switch(RRR()) //0 - 3
{
ADD_OPCODE(SELB,(RC(), RA(), RB(), RT()));
ADD_OPCODE(SHUFB,(RC(), RA(), RB(), RT()));
}
m_op.UNK(m_code, 0, 0);
}
};
#undef START_OPCODES_GROUP_
#undef START_OPCODES_GROUP
#undef ADD_OPCODE
#undef ADD_NULL_OPCODE
#undef END_OPCODES_GROUP