use registerdescriptors

This commit is contained in:
angie 2022-12-19 18:38:05 -03:00
parent 21000319cd
commit 75fe4e4fe3
7 changed files with 143 additions and 103 deletions

View File

@ -8,6 +8,8 @@
#include <stdint.h>
#include "common/Utils.h"
#include "RabbitizerRegisterDescriptor.h"
#ifdef __cplusplus
extern "C" {
@ -61,6 +63,35 @@ NODISCARD PURE RETURNS_NON_NULL
const char *RabbitizerRegister_getNameR5900VI(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Gpr(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop0(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop1(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop1Control(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop2(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspGpr(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop0(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop2(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop2Control(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspVector(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_R5900VF(uint8_t regValue);
NODISCARD PURE RETURNS_NON_NULL
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_R5900VI(uint8_t regValue);
#ifdef __cplusplus
}
#endif

View File

@ -15,7 +15,7 @@ setup(
"src/instructions/RabbitizerInstructionCpu/RabbitizerInstructionCpu_OperandType.c",
"src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp.c", "src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c", "src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_OperandType.c",
"src/instructions/RabbitizerInstructionR5900/RabbitizerInstructionR5900.c", "src/instructions/RabbitizerInstructionR5900/RabbitizerInstructionR5900_ProcessUniqueId.c", "src/instructions/RabbitizerInstructionR5900/RabbitizerInstructionR5900_OperandType.c",
"src/instructions/RabbitizerInstrDescriptor.c", "src/instructions/RabbitizerInstrId.c", "src/instructions/RabbitizerRegister.c", "src/instructions/RabbitizerInstrSuffix.c", "src/instructions/RabbitizerInstrCategory.c",
"src/instructions/RabbitizerInstrDescriptor.c", "src/instructions/RabbitizerInstrId.c", "src/instructions/RabbitizerRegister.c", "src/instructions/RabbitizerRegisterDescriptor.c", "src/instructions/RabbitizerInstrSuffix.c", "src/instructions/RabbitizerInstrCategory.c",
"src/analysis/RabbitizerTrackedRegisterState.c", "src/analysis/RabbitizerRegistersTracker.c", "src/analysis/RabbitizerLoPairingInfo.c",
"src/common/Utils.c", "src/common/RabbitizerVersion.c", "src/common/RabbitizerConfig.c"],
include_dirs=["include", "rabbitizer"],

View File

@ -9,8 +9,6 @@
#include "common/RabbitizerConfig.h"
#include "instructions/RabbitizerRegister.h"
// TODO: abi checks
void RabbitizerRegistersTracker_init(RabbitizerRegistersTracker *self, const RabbitizerRegistersTracker *other) {
size_t i;
@ -145,79 +143,17 @@ void RabbitizerRegistersTracker_overwriteRegisters(RabbitizerRegistersTracker *s
void RabbitizerRegistersTracker_unsetRegistersAfterFuncCall(RabbitizerRegistersTracker *self, UNUSED const RabbitizerInstruction *instr,
const RabbitizerInstruction *prevInstr) {
RabbitizerTrackedRegisterState *state = NULL;
if (!RabbitizerInstrDescriptor_doesLink(prevInstr->descriptor)) {
return;
}
if (RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_O32 || RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_NUMERIC) {
for (size_t reg = 0; reg < ARRAY_COUNT(self->registers); reg++) {
switch (reg) {
case RABBITIZER_REG_GPR_O32_at:
case RABBITIZER_REG_GPR_O32_v0:
case RABBITIZER_REG_GPR_O32_v1:
case RABBITIZER_REG_GPR_O32_a0:
case RABBITIZER_REG_GPR_O32_a1:
case RABBITIZER_REG_GPR_O32_a2:
case RABBITIZER_REG_GPR_O32_a3:
case RABBITIZER_REG_GPR_O32_t0:
case RABBITIZER_REG_GPR_O32_t1:
case RABBITIZER_REG_GPR_O32_t2:
case RABBITIZER_REG_GPR_O32_t3:
case RABBITIZER_REG_GPR_O32_t4:
case RABBITIZER_REG_GPR_O32_t5:
case RABBITIZER_REG_GPR_O32_t6:
case RABBITIZER_REG_GPR_O32_t7:
case RABBITIZER_REG_GPR_O32_t8:
case RABBITIZER_REG_GPR_O32_t9:
case RABBITIZER_REG_GPR_O32_ra:
state = &self->registers[reg];
#if 0
if (state.hasLuiValue) {
self->_printDebugInfo_clearRegister(instr, reg)
}
#endif
RabbitizerTrackedRegisterState_clear(state);
break;
for (size_t reg = 0; reg < ARRAY_COUNT(self->registers); reg++) {
const RabbitizerRegisterDescriptor *regDescriptor = RabbitizerRegister_getDescriptor_Gpr(reg);
default:
break;
}
}
} else if (RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_N32 || RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_N64) {
for (size_t reg = 0; reg < ARRAY_COUNT(self->registers); reg++) {
switch (reg) {
case RABBITIZER_REG_GPR_N32_at:
case RABBITIZER_REG_GPR_N32_v0:
case RABBITIZER_REG_GPR_N32_v1:
case RABBITIZER_REG_GPR_N32_a0:
case RABBITIZER_REG_GPR_N32_a1:
case RABBITIZER_REG_GPR_N32_a2:
case RABBITIZER_REG_GPR_N32_a3:
case RABBITIZER_REG_GPR_N32_a4:
case RABBITIZER_REG_GPR_N32_a5:
case RABBITIZER_REG_GPR_N32_a6:
case RABBITIZER_REG_GPR_N32_a7:
case RABBITIZER_REG_GPR_N32_t0:
case RABBITIZER_REG_GPR_N32_t1:
case RABBITIZER_REG_GPR_N32_t2:
case RABBITIZER_REG_GPR_N32_t3:
case RABBITIZER_REG_GPR_N32_t8:
case RABBITIZER_REG_GPR_N32_t9:
case RABBITIZER_REG_GPR_N32_ra:
state = &self->registers[reg];
#if 0
if (state.hasLuiValue) {
self->_printDebugInfo_clearRegister(instr, reg)
}
#endif
RabbitizerTrackedRegisterState_clear(state);
break;
if (RabbitizerRegisterDescriptor_isClobberedByFuncCall(regDescriptor)) {
RabbitizerTrackedRegisterState *state = &self->registers[reg];
default:
break;
}
RabbitizerTrackedRegisterState_clear(state);
}
}
}
@ -300,6 +236,7 @@ void RabbitizerRegistersTracker_processConstant(RabbitizerRegistersTracker *self
bool RabbitizerRegistersTracker_getLuiOffsetForLo(RabbitizerRegistersTracker *self, const RabbitizerInstruction *instr, int instrOffset, int *dstOffset,
bool *dstIsGp) {
const RabbitizerTrackedRegisterState *state = &self->registers[RAB_INSTR_GET_rs(instr)];
const RabbitizerRegisterDescriptor *regDescriptor;
if (state->hasLuiValue && !state->luiSetOnBranchLikely) {
*dstOffset = state->luiOffset;
@ -307,8 +244,8 @@ bool RabbitizerRegistersTracker_getLuiOffsetForLo(RabbitizerRegistersTracker *se
return true;
}
// TODO: abi
if (RAB_INSTR_GET_rs(instr) == 28) { // $gp
regDescriptor = RabbitizerRegister_getDescriptor_Gpr(RAB_INSTR_GET_rs(instr));
if (RabbitizerRegisterDescriptor_isGp(regDescriptor)) {
*dstOffset = 0;
*dstIsGp = true;
return true;
@ -328,6 +265,7 @@ RabbitizerLoPairingInfo RabbitizerRegistersTracker_preprocessLoAndGetInfo(Rabbit
int instrOffset) {
const RabbitizerTrackedRegisterState *state = &self->registers[RAB_INSTR_GET_rs(instr)];
RabbitizerLoPairingInfo pairingInfo;
const RabbitizerRegisterDescriptor *regDescriptor;
RabbitizerLoPairingInfo_Init(&pairingInfo);
@ -338,7 +276,8 @@ RabbitizerLoPairingInfo RabbitizerRegistersTracker_preprocessLoAndGetInfo(Rabbit
return pairingInfo;
}
if ((RAB_INSTR_GET_rs(instr) == RABBITIZER_REG_GPR_O32_gp) || (RAB_INSTR_GET_rs(instr) == RABBITIZER_REG_GPR_N32_gp)) {
regDescriptor = RabbitizerRegister_getDescriptor_Gpr(RAB_INSTR_GET_rs(instr));
if (RabbitizerRegisterDescriptor_isGp(regDescriptor)) {
pairingInfo.value = state->value;
pairingInfo.isGpRel = true;
pairingInfo.shouldProcess = true;

View File

@ -63,9 +63,11 @@ bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *se
bool RabbitizerInstruction_isReturn(const RabbitizerInstruction *self) {
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_jr:
case RABBITIZER_INSTR_ID_rsp_jr:
// TODO: abi stuffs
return RAB_INSTR_GET_rs(self) == RABBITIZER_REG_GPR_O32_ra;
case RABBITIZER_INSTR_ID_rsp_jr: {
const RabbitizerRegisterDescriptor *regDescriptor = RabbitizerRegister_getDescriptor_Gpr(RAB_INSTR_GET_rs(self));
return RabbitizerRegisterDescriptor_isRa(regDescriptor);
}
default:
return false;
@ -75,9 +77,11 @@ bool RabbitizerInstruction_isReturn(const RabbitizerInstruction *self) {
bool RabbitizerInstruction_isJumptableJump(const RabbitizerInstruction *self) {
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_jr:
case RABBITIZER_INSTR_ID_rsp_jr:
// TODO: abi stuffs
return RAB_INSTR_GET_rs(self) != RABBITIZER_REG_GPR_O32_ra;
case RABBITIZER_INSTR_ID_rsp_jr: {
const RabbitizerRegisterDescriptor *regDescriptor = RabbitizerRegister_getDescriptor_Gpr(RAB_INSTR_GET_rs(self));
return !RabbitizerRegisterDescriptor_isRa(regDescriptor);
}
default:
return false;

View File

@ -232,19 +232,9 @@ size_t RabbitizerOperandType_process_cpu_immediate_base(const RabbitizerInstruct
size_t RabbitizerOperandType_process_cpu_maybe_rd_rs(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength) {
size_t totalSize = 0;
uint8_t rd = RAB_INSTR_GET_rd(self);
bool shouldOutputRd = true;
const RabbitizerRegisterDescriptor *regDescriptor = RabbitizerRegister_getDescriptor_Gpr(rd);
if (RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_NUMERIC || RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_O32) {
if (rd == RABBITIZER_REG_GPR_O32_ra) {
shouldOutputRd = false;
}
} else {
if (rd == RABBITIZER_REG_GPR_N32_ra) {
shouldOutputRd = false;
}
}
if (shouldOutputRd) {
if (!RabbitizerRegisterDescriptor_isRa(regDescriptor)) {
RABUTILS_BUFFER_ADVANCE(dst, totalSize, RabbitizerOperandType_process_cpu_rd(self, dst, immOverride, immOverrideLength));
RABUTILS_BUFFER_WRITE_CHAR(dst, totalSize, ',');

View File

@ -173,19 +173,9 @@ size_t RabbitizerOperandType_process_rsp_immediate_base(const RabbitizerInstruct
size_t RabbitizerOperandType_process_rsp_maybe_rd_rs(const RabbitizerInstruction *self, char *dst, const char *immOverride, size_t immOverrideLength) {
size_t totalSize = 0;
uint8_t rd = RAB_INSTR_GET_rd(self);
bool shouldOutputRd = true;
const RabbitizerRegisterDescriptor *regDescriptor = RabbitizerRegister_getDescriptor_Gpr(rd);
if (RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_NUMERIC || RabbitizerConfig_Cfg.regNames.gprAbiNames == RABBITIZER_ABI_O32) {
if (rd == RABBITIZER_REG_GPR_O32_ra) {
shouldOutputRd = false;
}
} else {
if (rd == RABBITIZER_REG_GPR_N32_ra) {
shouldOutputRd = false;
}
}
if (shouldOutputRd) {
if (!RabbitizerRegisterDescriptor_isRa(regDescriptor)) {
RABUTILS_BUFFER_ADVANCE(dst, totalSize, RabbitizerOperandType_process_rsp_rd(self, dst, immOverride, immOverrideLength));
RABUTILS_BUFFER_WRITE_CHAR(dst, totalSize, ',');

View File

@ -107,3 +107,89 @@ const char *RabbitizerRegister_getNameR5900VI(uint8_t regValue) {
return RabbitizerRegister_R5900VI_Names[regValue][RabbitizerConfig_Cfg.regNames.namedRegisters ? 1 : 0];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Gpr(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_GprO32_Names));
switch (RabbitizerConfig_Cfg.regNames.gprAbiNames) {
default:
case RABBITIZER_ABI_NUMERIC:
case RABBITIZER_ABI_O32:
return &RabbitizerRegister_GprO32_Descriptors[regValue];
case RABBITIZER_ABI_N32:
case RABBITIZER_ABI_N64:
return &RabbitizerRegister_GprN32_Descriptors[regValue];
}
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop0(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_Cop0_Names));
return &RabbitizerRegister_Cop0_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop1(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_Cop1O32_Names));
switch (RabbitizerConfig_Cfg.regNames.fprAbiNames) {
default:
case RABBITIZER_ABI_NUMERIC:
case RABBITIZER_ABI_O32:
return &RabbitizerRegister_Cop1O32_Descriptors[regValue];
case RABBITIZER_ABI_N32:
return &RabbitizerRegister_Cop1N32_Descriptors[regValue];
case RABBITIZER_ABI_N64:
return &RabbitizerRegister_Cop1N64_Descriptors[regValue];
}
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop1Control(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_Cop1Control_Names));
return &RabbitizerRegister_Cop1Control_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_Cop2(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_Cop2_Names));
return &RabbitizerRegister_Cop2_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspGpr(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_RspGpr_Names));
return &RabbitizerRegister_RspGpr_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop0(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_RspCop0_Names));
return &RabbitizerRegister_RspCop0_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop2(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_RspCop2_Names));
return &RabbitizerRegister_RspCop2_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspCop2Control(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_RspCop2Control_Names));
return &RabbitizerRegister_RspCop2Control_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_RspVector(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_RspVector_Names));
return &RabbitizerRegister_RspVector_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_R5900VF(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_R5900VF_Names));
return &RabbitizerRegister_R5900VF_Descriptors[regValue];
}
const RabbitizerRegisterDescriptor *RabbitizerRegister_getDescriptor_R5900VI(uint8_t regValue) {
assert(regValue < ARRAY_COUNT(RabbitizerRegister_R5900VI_Names));
return &RabbitizerRegister_R5900VI_Descriptors[regValue];
}