Deprecate getGenericBranchOffset, add getBranchOffsetGeneric and getBranchVramGeneric

This commit is contained in:
angie 2022-10-13 17:41:50 -03:00
parent 34f2e2e6a5
commit c1a6abe186
7 changed files with 82 additions and 20 deletions

View File

@ -155,7 +155,10 @@ namespace rabbitizer {
uint32_t getInstrIndexAsVram() const;
int32_t getBranchOffset() const;
//! @deprecated
int32_t getGenericBranchOffset(uint32_t currentVram) const;
int32_t getBranchOffsetGeneric() const;
int32_t getBranchVramGeneric() const;
std::string getOpcodeName() const;

View File

@ -703,6 +703,26 @@ int32_t InstructionBase::getGenericBranchOffset(uint32_t currentVram) const {
return RabbitizerInstruction_getGenericBranchOffset(&this->instr, currentVram);
}
int32_t InstructionBase::getBranchOffsetGeneric() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::cpu_branch_target_label) && !hasOperandAlias(OperandType::cpu_label)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have either 'branch_target_label' or 'label' operands.");
}
#endif
return RabbitizerInstruction_getBranchOffsetGeneric(&this->instr);
}
int32_t InstructionBase::getBranchVramGeneric() const {
#ifdef RAB_SANITY_CHECKS
if (!hasOperandAlias(OperandType::cpu_branch_target_label) && !hasOperandAlias(OperandType::cpu_label)) {
// TODO: make a rabbitizer exception class
throw std::runtime_error("Instruction '" + getOpcodeName() + "' does not have either 'branch_target_label' or 'label' operands.");
}
#endif
return RabbitizerInstruction_getBranchVramGeneric(&this->instr);
}
std::string InstructionBase::getOpcodeName() const {
return InstrId::getOpcodeName(getUniqueId());

View File

@ -179,6 +179,10 @@ NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getBranchOffset(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getGenericBranchOffset(const RabbitizerInstruction *self, uint32_t currentVram);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getBranchOffsetGeneric(const RabbitizerInstruction *self);
NODISCARD NON_NULL(1) PURE
int32_t RabbitizerInstruction_getBranchVramGeneric(const RabbitizerInstruction *self);
/* General getters */

View File

@ -44,12 +44,13 @@ class Instruction:
def __init__(self, word: int, vram: int=0, category: Enum=InstrCategory.CPU) -> None: ...
def getRaw(self) -> int: ...
#! deprecated
def getImmediate(self) -> int: ...
def getImmediate(self) -> int: ... #! deprecated
def getProcessedImmediate(self) -> int: ...
def getInstrIndexAsVram(self) -> int: ...
def getBranchOffset(self) -> int: ...
def getGenericBranchOffset(self, currentVram: int) -> int: ...
def getGenericBranchOffset(self, currentVram: int) -> int: ... #! deprecated
def getBranchOffsetGeneric(self) -> int: ...
def getBranchVramGeneric(self) -> int: ...
def getOpcodeName(self) -> str: ...
def blankOut(self) -> None: ...

View File

@ -170,6 +170,9 @@ static PyObject *rabbitizer_type_Instruction_getGenericBranchOffset(PyRabbitizer
return PyLong_FromLong(RabbitizerInstruction_getGenericBranchOffset(&self->instr, currentVram));
}
DEF_METHOD_GET_INT(getBranchOffsetGeneric)
DEF_METHOD_GET_INT(getBranchVramGeneric)
static PyObject *rabbitizer_type_Instruction_blankOut(PyRabbitizerInstruction *self, UNUSED PyObject *closure) {
RabbitizerInstruction_blankOut(&self->instr);
Py_RETURN_NONE;
@ -388,6 +391,8 @@ static PyMethodDef rabbitizer_type_Instruction_methods[] = {
METHOD_NO_ARGS(getInstrIndexAsVram, ""),
METHOD_NO_ARGS(getBranchOffset, ""),
METHOD_ARGS(getGenericBranchOffset, ""),
METHOD_NO_ARGS(getBranchOffsetGeneric, ""),
METHOD_NO_ARGS(getBranchVramGeneric, ""),
METHOD_NO_ARGS(getOpcodeName, ""),
METHOD_NO_ARGS(blankOut, ""),

View File

@ -64,6 +64,20 @@ int32_t RabbitizerInstruction_getGenericBranchOffset(const RabbitizerInstruction
return RabbitizerInstruction_getBranchOffset(self);
}
int32_t RabbitizerInstruction_getBranchOffsetGeneric(const RabbitizerInstruction *self) {
if (RabbitizerInstruction_hasOperandAlias(self, RAB_OPERAND_cpu_label)) {
return RabbitizerInstruction_getInstrIndexAsVram(self) - self->vram;
}
return RabbitizerInstruction_getBranchOffset(self);
}
int32_t RabbitizerInstruction_getBranchVramGeneric(const RabbitizerInstruction *self) {
if (RabbitizerInstruction_hasOperandAlias(self, RAB_OPERAND_cpu_label)) {
return RabbitizerInstruction_getInstrIndexAsVram(self);
}
return RabbitizerInstruction_getBranchOffset(self) + self->vram;
}
/* General getters */
void RabbitizerInstruction_blankOut(RabbitizerInstruction *self) {

View File

@ -48,32 +48,47 @@ bool RabbitizerInstruction_isNop(const RabbitizerInstruction *self) {
}
bool RabbitizerInstruction_isUnconditionalBranch(const RabbitizerInstruction *self) {
if (self->uniqueId == RABBITIZER_INSTR_ID_cpu_b) {
return true;
switch (self->uniqueId) {
case RABBITIZER_INSTR_ID_cpu_b:
case RABBITIZER_INSTR_ID_rsp_b:
return true;
case RABBITIZER_INSTR_ID_cpu_beq:
case RABBITIZER_INSTR_ID_rsp_beq:
// in case the b pseudoinstruction is disabled
return RAB_INSTR_GET_rt(self) == 0 && RAB_INSTR_GET_rs(self) == 0;
case RABBITIZER_INSTR_ID_cpu_j:
case RABBITIZER_INSTR_ID_rsp_j:
return RabbitizerConfig_Cfg.toolchainTweaks.treatJAsUnconditionalBranch;
default:
return false;
}
if (self->uniqueId == RABBITIZER_INSTR_ID_cpu_beq && RAB_INSTR_GET_rt(self) == 0 && RAB_INSTR_GET_rs(self) == 0) {
return true;
}
if (RabbitizerConfig_Cfg.toolchainTweaks.treatJAsUnconditionalBranch && self->uniqueId == RABBITIZER_INSTR_ID_cpu_j) {
return true;
}
return false;
}
bool RabbitizerInstruction_isJrRa(const RabbitizerInstruction *self) {
if (self->uniqueId == RABBITIZER_INSTR_ID_cpu_jr) {
// TODO: abi stuffs
return RAB_INSTR_GET_rs(self) == RABBITIZER_REG_GPR_O32_ra;
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;
default:
return false;
}
return false;
}
bool RabbitizerInstruction_isJrNotRa(const RabbitizerInstruction *self) {
if (self->uniqueId == RABBITIZER_INSTR_ID_cpu_jr) {
// TODO: abi stuffs
return RAB_INSTR_GET_rs(self) != RABBITIZER_REG_GPR_O32_ra;
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;
default:
return false;
}
return false;
}
bool RabbitizerInstruction_hasDelaySlot(const RabbitizerInstruction *self) {