#include "instructions/RabbitizerInstruction.h"
#include "common/RabbitizerConfig.h"
#include "instructions/RabbitizerRegister.h"
#define RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, ...) \
case (caseBits): \
self->uniqueId = RABBITIZER_INSTR_ID_##prefix##_##name; \
break;
#define RABBITIZER_DEF_INSTR_ID_ALTNAME(prefix, caseBits, name, altname, ...) \
RABBITIZER_DEF_INSTR_ID(prefix, caseBits, name, __VA_ARGS__)
void RabbitizerInstruction_processUniqueId_Normal(RabbitizerInstruction *self) {
uint32_t opcode = RAB_INSTR_GET_opcode(self);
self->_mandatorybits = RAB_INSTR_PACK_opcode(self->_mandatorybits, opcode);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_NORMAL;
switch (opcode) {
#include "tables/instr_id/cpu/cpu_normal.inc"
}
if (RabbitizerConfig_Cfg.pseudos.enablePseudos) {
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_beq:
if (RAB_INSTR_GET_rt(self) == 0) {
if (RAB_INSTR_GET_rs(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoB) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_b;
}
} else {
if (RabbitizerConfig_Cfg.pseudos.pseudoBeqz) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_beqz;
}
}
}
break;
case RABBITIZER_INSTR_ID_cpu_bne:
if (RAB_INSTR_GET_rt(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoBnez) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_bnez;
}
}
break;
default:
break;
}
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
void RabbitizerInstruction_processUniqueId_Special(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_SPECIAL;
switch (function) {
#include "tables/instr_id/cpu/cpu_special.inc"
}
if (RabbitizerInstruction_isNop(self)) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_nop;
} else if (RabbitizerConfig_Cfg.pseudos.enablePseudos) {
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_or:
if (RAB_INSTR_GET_rt(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoMove) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_move;
}
}
break;
case RABBITIZER_INSTR_ID_cpu_nor:
if (RAB_INSTR_GET_rt(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoNot) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_not;
}
}
break;
case RABBITIZER_INSTR_ID_cpu_sub:
if (RAB_INSTR_GET_rs(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoNeg) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_neg;
}
}
break;
case RABBITIZER_INSTR_ID_cpu_subu:
if (RAB_INSTR_GET_rs(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoNegu) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_negu;
}
}
break;
default:
break;
}
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_div:
if ((!RabbitizerConfig_Cfg.toolchainTweaks.gnuMode) ||
(RabbitizerConfig_Cfg.toolchainTweaks.sn64DivFix && !self->inHandwrittenFunction)) {
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[RABBITIZER_INSTR_ID_cpu_sn64_div];
}
break;
case RABBITIZER_INSTR_ID_cpu_divu:
if ((!RabbitizerConfig_Cfg.toolchainTweaks.gnuMode) ||
(RabbitizerConfig_Cfg.toolchainTweaks.sn64DivFix && !self->inHandwrittenFunction)) {
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[RABBITIZER_INSTR_ID_cpu_sn64_divu];
}
break;
default:
break;
}
}
void RabbitizerInstruction_processUniqueId_Regimm(RabbitizerInstruction *self) {
uint32_t rt = RAB_INSTR_GET_rt(self);
self->_mandatorybits = RAB_INSTR_PACK_rt(self->_mandatorybits, rt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_REGIMM;
switch (rt) {
#include "tables/instr_id/cpu/cpu_regimm.inc"
}
if (RabbitizerConfig_Cfg.pseudos.enablePseudos) {
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_bgezal:
if (RAB_INSTR_GET_rs(self) == 0) {
if (RabbitizerConfig_Cfg.pseudos.pseudoBal) {
self->uniqueId = RABBITIZER_INSTR_ID_cpu_bal;
}
}
break;
default:
break;
}
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
void RabbitizerInstruction_processUniqueId_Coprocessor0_BC0(RabbitizerInstruction *self) {
uint32_t fmt = RAB_INSTR_GET_bc_fmt(self);
self->_mandatorybits = RAB_INSTR_PACK_bc_fmt(self->_mandatorybits, fmt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP0_BC0;
switch (fmt) {
#include "tables/instr_id/cpu/cpu_cop0_bc0.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor0_Tlb(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP0_TLB;
switch (function) {
#include "tables/instr_id/cpu/cpu_cop0_tlb.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor0(RabbitizerInstruction *self) {
uint32_t fmt = RAB_INSTR_GET_fmt(self);
self->_mandatorybits = RAB_INSTR_PACK_fmt(self->_mandatorybits, fmt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP0;
self->_handwrittenCategory = true;
switch (fmt) {
#include "tables/instr_id/cpu/cpu_cop0.inc"
case 0x08:
RabbitizerInstruction_processUniqueId_Coprocessor0_BC0(self);
break;
case 0x10:
RabbitizerInstruction_processUniqueId_Coprocessor0_Tlb(self);
break;
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
void RabbitizerInstruction_processUniqueId_Coprocessor1_BC1(RabbitizerInstruction *self) {
uint32_t fmt = RAB_INSTR_GET_bc_fmt(self);
self->_mandatorybits = RAB_INSTR_PACK_bc_fmt(self->_mandatorybits, fmt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1_BC1;
switch (fmt) {
#include "tables/instr_id/cpu/cpu_cop1_bc1.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuS(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1_FPUS;
switch (function) {
#include "tables/instr_id/cpu/cpu_cop1_fpu_s.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuD(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1_FPUD;
switch (function) {
#include "tables/instr_id/cpu/cpu_cop1_fpu_d.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuW(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1_FPUW;
switch (function) {
#include "tables/instr_id/cpu/cpu_cop1_fpu_w.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor1_FpuL(RabbitizerInstruction *self) {
uint32_t function = RAB_INSTR_GET_function(self);
self->_mandatorybits = RAB_INSTR_PACK_function(self->_mandatorybits, function);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1_FPUL;
switch (function) {
#include "tables/instr_id/cpu/cpu_cop1_fpu_l.inc"
}
}
void RabbitizerInstruction_processUniqueId_Coprocessor1(RabbitizerInstruction *self) {
uint8_t fmt = RAB_INSTR_GET_fmt(self);
self->_mandatorybits = RAB_INSTR_PACK_fmt(self->_mandatorybits, fmt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP1;
switch (fmt) {
#include "tables/instr_id/cpu/cpu_cop1.inc"
case 0x08: RabbitizerInstruction_processUniqueId_Coprocessor1_BC1(self);
break;
case 0x10:
RabbitizerInstruction_processUniqueId_Coprocessor1_FpuS(self);
break;
case 0x11:
RabbitizerInstruction_processUniqueId_Coprocessor1_FpuD(self);
break;
case 0x14:
RabbitizerInstruction_processUniqueId_Coprocessor1_FpuW(self);
break;
case 0x15:
RabbitizerInstruction_processUniqueId_Coprocessor1_FpuL(self);
break;
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
void RabbitizerInstruction_processUniqueId_Coprocessor2(RabbitizerInstruction *self) {
uint32_t fmt = RAB_INSTR_GET_fmt(self);
self->_mandatorybits = RAB_INSTR_PACK_fmt(self->_mandatorybits, fmt);
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_COP2;
self->_handwrittenCategory = true;
switch (fmt) {
#include "tables/instr_id/cpu/cpu_cop2.inc"
default:
break;
}
self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId];
}
#undef RABBITIZER_DEF_INSTR_ID
#undef RABBITIZER_DEF_INSTR_ID_ALTNAME
void RabbitizerInstruction_processUniqueId(RabbitizerInstruction *self) {
uint32_t opcode = RAB_INSTR_GET_opcode(self);
self->_mandatorybits = RAB_INSTR_PACK_opcode(self->_mandatorybits, opcode);
self->uniqueId = RABBITIZER_INSTR_ID_cpu_INVALID;
self->instrIdType = RAB_INSTR_ID_TYPE_CPU_INVALID;
switch (opcode) {
default:
RabbitizerInstruction_processUniqueId_Normal(self);
break;
case 0x00:
RabbitizerInstruction_processUniqueId_Special(self);
break;
case 0x01:
RabbitizerInstruction_processUniqueId_Regimm(self);
break;
case 0x10:
RabbitizerInstruction_processUniqueId_Coprocessor0(self);
break;
case 0x11:
RabbitizerInstruction_processUniqueId_Coprocessor1(self);
break;
case 0x12:
RabbitizerInstruction_processUniqueId_Coprocessor2(self);
break;
}
}