diff --git a/include/instructions/RabbitizerInstr.h b/include/instructions/RabbitizerInstr.h index ba5bed4..a86c03b 100644 --- a/include/instructions/RabbitizerInstr.h +++ b/include/instructions/RabbitizerInstr.h @@ -36,6 +36,7 @@ void RabbitizerInstr_Destroy(RabbitizerInstr* self); void RabbitizerInstr_ProcessUniqueId_Normal(RabbitizerInstr *self); void RabbitizerInstr_ProcessUniqueId_Special(RabbitizerInstr *self); void RabbitizerInstr_ProcessUniqueId_Regimm(RabbitizerInstr *self); +void RabbitizerInstr_ProcessUniqueId_Coprocessor0(RabbitizerInstr *self); const char *RabbitizerInstr_GetOpcodeName(const RabbitizerInstr *self); @@ -43,6 +44,12 @@ uint8_t RabbitizerInstr_GetFs(const RabbitizerInstr* self); uint8_t RabbitizerInstr_GetFt(const RabbitizerInstr* self); uint8_t RabbitizerInstr_GetFd(const RabbitizerInstr* self); +uint8_t RabbitizerInstr_GetFmt(const RabbitizerInstr *self); + +uint8_t RabbitizerInstr_GetNd(const RabbitizerInstr *self); +uint8_t RabbitizerInstr_GetTf(const RabbitizerInstr *self); +uint8_t RabbitizerInstr_GetFc(const RabbitizerInstr *self); + uint32_t RabbitizerInstr_GetImmediate(const RabbitizerInstr *self); uint32_t RabbitizerInstr_GetInstrIndex(const RabbitizerInstr *self); uint32_t RabbitizerInstr_GetInstrIndexAsVram(const RabbitizerInstr *self); diff --git a/src/instructions/RabbitizerInstr.c b/src/instructions/RabbitizerInstr.c index 2810dd0..f411d86 100644 --- a/src/instructions/RabbitizerInstr.c +++ b/src/instructions/RabbitizerInstr.c @@ -35,6 +35,19 @@ uint8_t RabbitizerInstr_GetFd(const RabbitizerInstr *self) { return self->sa; } +uint8_t RabbitizerInstr_GetFmt(const RabbitizerInstr *self) { + return self->rs; +} + +uint8_t RabbitizerInstr_GetNd(const RabbitizerInstr *self) { + return self->rt & 0x1; +} +uint8_t RabbitizerInstr_GetTf(const RabbitizerInstr *self) { + return (self->rt >> 1) & 0x1; +} +uint8_t RabbitizerInstr_GetFc(const RabbitizerInstr *self) { + return (self->function >> 4) & 0x3; +} uint32_t RabbitizerInstr_GetImmediate(const RabbitizerInstr *self) { return (self->rd << 11) | (self->sa << 6) | (self->function); diff --git a/src/instructions/RabbitizerInstr_ProcessUniqueId.c b/src/instructions/RabbitizerInstr_ProcessUniqueId.c index 86c6611..3130ee9 100644 --- a/src/instructions/RabbitizerInstr_ProcessUniqueId.c +++ b/src/instructions/RabbitizerInstr_ProcessUniqueId.c @@ -493,3 +493,73 @@ void RabbitizerInstr_ProcessUniqueId_Regimm(RabbitizerInstr *self) { self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId.cpuId]; } + + +void RabbitizerInstr_ProcessUniqueId_Coprocessor0(RabbitizerInstr *self) { + self->_handwrittenCategory = true; + + switch (RabbitizerInstr_GetFmt(self)) { + case 0b00000: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_mfc0; + break; + case 0b00001: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_dmfc0; + break; + case 0b00010: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_cfc0; + break; + // 0b00_011: "", + case 0b00100: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_mtc0; + break; + case 0b00101: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_dmtc0; + break; + case 0b00110: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_ctc0; + break; + // 0b00_111: "", + + case 0b01000: + if (RabbitizerInstr_GetTf(self)) { + if (RabbitizerInstr_GetNd(self)) { + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_bc0tl; + } else { + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_bc0t; + } + } else { + if (RabbitizerInstr_GetNd(self)) { + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_bc0fl; + } else { + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_bc0f; + } + } + break; + + default: + switch (self->function) { + case 0b000001: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_tlbr; + break; + case 0b000010: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_tlbwi; + break; + case 0b000110: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_tlbwr; + break; + case 0b001000: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_tlbp; + break; + case 0b011000: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_eret; + break; + + default: + self->uniqueId.cpuId = RABBITIZER_INSTR_CPU_ID_INVALID; + break; + } + break; + } + + self->descriptor = &RabbitizerInstrDescriptor_Descriptors[self->uniqueId.cpuId]; +}