diff --git a/.gitattributes b/.gitattributes index f5776cd..3347d52 100644 --- a/.gitattributes +++ b/.gitattributes @@ -24,3 +24,4 @@ rabbitizer/RegGprN32.pyi linguist-generated=true rabbitizer/RegCop1O32.pyi linguist-generated=true rabbitizer/RegCop1N32.pyi linguist-generated=true rabbitizer/RegCop1N64.pyi linguist-generated=true +rabbitizer/TrinaryValue.pyi linguist-generated=true diff --git a/CHANGELOG.md b/CHANGELOG.md index 3def34f..83b1910 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added + +- Implement `neg` pseudo. + ### Changed - `Instruction.getProcessedImmediate` now raises an exception if the diff --git a/cplusplus/include/generated/UniqueId_enum_class.hpp b/cplusplus/include/generated/UniqueId_enum_class.hpp index 3af44ba..fad5c9a 100644 --- a/cplusplus/include/generated/UniqueId_enum_class.hpp +++ b/cplusplus/include/generated/UniqueId_enum_class.hpp @@ -123,6 +123,7 @@ enum class UniqueId { cpu_nop, cpu_move, cpu_not, + cpu_neg, cpu_negu, cpu_bltz, cpu_bgez, @@ -385,6 +386,7 @@ enum class UniqueId { rsp_nop, rsp_move, rsp_not, + rsp_neg, rsp_negu, rsp_bltz, rsp_bgez, diff --git a/include/common/RabbitizerConfig.h b/include/common/RabbitizerConfig.h index 97add91..1be6ae7 100644 --- a/include/common/RabbitizerConfig.h +++ b/include/common/RabbitizerConfig.h @@ -32,6 +32,7 @@ typedef struct RabbitizerConfig_PseudoInstr { bool pseudoB; bool pseudoMove; bool pseudoNot; + bool pseudoNeg; bool pseudoNegu; bool pseudoBal; } RabbitizerConfig_PseudoInstr; diff --git a/include/generated/InstrDescriptor_Descriptors_array.h b/include/generated/InstrDescriptor_Descriptors_array.h index c3293b8..4a5f07a 100644 --- a/include/generated/InstrDescriptor_Descriptors_array.h +++ b/include/generated/InstrDescriptor_Descriptors_array.h @@ -123,6 +123,7 @@ const RabbitizerInstrDescriptor RabbitizerInstrDescriptor_Descriptors[] = { [RABBITIZER_INSTR_ID_cpu_nop] = { .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R, .isPseudo=true }, [RABBITIZER_INSTR_ID_cpu_move] = { .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRs=true, .maybeIsMove=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_cpu_not] = { .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRs=true, .isPseudo=true }, + [RABBITIZER_INSTR_ID_cpu_neg] = { .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRt=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_cpu_negu] = { .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRt=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_cpu_bltz] = { .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .readsRs=true }, [RABBITIZER_INSTR_ID_cpu_bgez] = { .operands={RAB_OPERAND_cpu_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .isBranch=true, .readsRs=true }, @@ -385,6 +386,7 @@ const RabbitizerInstrDescriptor RabbitizerInstrDescriptor_Descriptors[] = { [RABBITIZER_INSTR_ID_rsp_nop] = { .operands={0}, .instrType=RABBITIZER_INSTR_TYPE_R, .isPseudo=true }, [RABBITIZER_INSTR_ID_rsp_move] = { .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRs=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_rsp_not] = { .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rs}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRs=true, .isPseudo=true }, + [RABBITIZER_INSTR_ID_rsp_neg] = { .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRt=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_rsp_negu] = { .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt}, .instrType=RABBITIZER_INSTR_TYPE_R, .modifiesRd=true, .readsRt=true, .isPseudo=true }, [RABBITIZER_INSTR_ID_rsp_bltz] = { .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .readsRs=true, .isBranch=true }, [RABBITIZER_INSTR_ID_rsp_bgez] = { .operands={RAB_OPERAND_rsp_rs, RAB_OPERAND_cpu_branch_target_label}, .instrType=RABBITIZER_INSTR_TYPE_REGIMM, .readsRs=true, .isBranch=true }, diff --git a/include/generated/InstrId_Names_array.h b/include/generated/InstrId_Names_array.h index bb5ca50..5aae7a0 100644 --- a/include/generated/InstrId_Names_array.h +++ b/include/generated/InstrId_Names_array.h @@ -123,6 +123,7 @@ const char *RabbitizerInstrId_Names[] = { [RABBITIZER_INSTR_ID_cpu_nop] = "nop", [RABBITIZER_INSTR_ID_cpu_move] = "move", [RABBITIZER_INSTR_ID_cpu_not] = "not", + [RABBITIZER_INSTR_ID_cpu_neg] = "neg", [RABBITIZER_INSTR_ID_cpu_negu] = "negu", [RABBITIZER_INSTR_ID_cpu_bltz] = "bltz", [RABBITIZER_INSTR_ID_cpu_bgez] = "bgez", @@ -385,6 +386,7 @@ const char *RabbitizerInstrId_Names[] = { [RABBITIZER_INSTR_ID_rsp_nop] = "nop", [RABBITIZER_INSTR_ID_rsp_move] = "move", [RABBITIZER_INSTR_ID_rsp_not] = "not", + [RABBITIZER_INSTR_ID_rsp_neg] = "neg", [RABBITIZER_INSTR_ID_rsp_negu] = "negu", [RABBITIZER_INSTR_ID_rsp_bltz] = "bltz", [RABBITIZER_INSTR_ID_rsp_bgez] = "bgez", diff --git a/include/generated/InstrId_enum.h b/include/generated/InstrId_enum.h index 32e27c5..31e4efa 100644 --- a/include/generated/InstrId_enum.h +++ b/include/generated/InstrId_enum.h @@ -123,6 +123,7 @@ typedef enum RabbitizerInstrId { RABBITIZER_INSTR_ID_cpu_nop, RABBITIZER_INSTR_ID_cpu_move, RABBITIZER_INSTR_ID_cpu_not, + RABBITIZER_INSTR_ID_cpu_neg, RABBITIZER_INSTR_ID_cpu_negu, RABBITIZER_INSTR_ID_cpu_bltz, RABBITIZER_INSTR_ID_cpu_bgez, @@ -385,6 +386,7 @@ typedef enum RabbitizerInstrId { RABBITIZER_INSTR_ID_rsp_nop, RABBITIZER_INSTR_ID_rsp_move, RABBITIZER_INSTR_ID_rsp_not, + RABBITIZER_INSTR_ID_rsp_neg, RABBITIZER_INSTR_ID_rsp_negu, RABBITIZER_INSTR_ID_rsp_bltz, RABBITIZER_INSTR_ID_rsp_bgez, diff --git a/rabbitizer/Config.pyi b/rabbitizer/Config.pyi index 2560458..662b9c3 100644 --- a/rabbitizer/Config.pyi +++ b/rabbitizer/Config.pyi @@ -22,6 +22,7 @@ class _RabbitizerConfig: pseudos_pseudoB: bool = True pseudos_pseudoMove: bool = True pseudos_pseudoNot: bool = True + pseudos_pseudoNeg: bool = True pseudos_pseudoNegu: bool = True pseudos_pseudoBal: bool = True diff --git a/rabbitizer/InstrId.pyi b/rabbitizer/InstrId.pyi index 2e86e71..48658bf 100644 --- a/rabbitizer/InstrId.pyi +++ b/rabbitizer/InstrId.pyi @@ -124,6 +124,7 @@ class InstrId: cpu_nop: Enum cpu_move: Enum cpu_not: Enum + cpu_neg: Enum cpu_negu: Enum cpu_bltz: Enum cpu_bgez: Enum @@ -366,6 +367,7 @@ class InstrId: rsp_nop: Enum rsp_move: Enum rsp_not: Enum + rsp_neg: Enum rsp_negu: Enum rsp_bltz: Enum rsp_bgez: Enum diff --git a/rabbitizer/rabbitizer_global_config.c b/rabbitizer/rabbitizer_global_config.c index 07ba6b1..55151ea 100644 --- a/rabbitizer/rabbitizer_global_config.c +++ b/rabbitizer/rabbitizer_global_config.c @@ -113,6 +113,7 @@ DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoBnez) DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoB) DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoMove) DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoNot) +DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoNeg) DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoNegu) DEF_MEMBER_GET_SET_BOOL(pseudos, pseudoBal) @@ -140,6 +141,7 @@ static PyGetSetDef rabbitizer_global_config_GetSets[] = { MEMBER_GET_SET(pseudos, pseudoB, "", NULL), MEMBER_GET_SET(pseudos, pseudoMove, "", NULL), MEMBER_GET_SET(pseudos, pseudoNot, "", NULL), + MEMBER_GET_SET(pseudos, pseudoNeg, "", NULL), MEMBER_GET_SET(pseudos, pseudoNegu, "", NULL), MEMBER_GET_SET(pseudos, pseudoBal, "", NULL), diff --git a/rust/src/config.rs b/rust/src/config.rs index 686fa31..86e749c 100644 --- a/rust/src/config.rs +++ b/rust/src/config.rs @@ -25,6 +25,7 @@ pub struct PseudoInstr { pub pseudo_b: bool, pub pseudo_move: bool, pub pseudo_not: bool, + pub pseudo_neg: bool, pub pseudo_negu: bool, pub pseudo_bal: bool, } diff --git a/rust/src/instr_id_enum.rs b/rust/src/instr_id_enum.rs index 0c19129..776dd50 100644 --- a/rust/src/instr_id_enum.rs +++ b/rust/src/instr_id_enum.rs @@ -123,6 +123,7 @@ pub enum InstrId { cpu_nop, cpu_move, cpu_not, + cpu_neg, cpu_negu, cpu_bltz, cpu_bgez, @@ -385,6 +386,7 @@ pub enum InstrId { rsp_nop, rsp_move, rsp_not, + rsp_neg, rsp_negu, rsp_bltz, rsp_bgez, diff --git a/src/common/RabbitizerConfig.c b/src/common/RabbitizerConfig.c index 23f5887..351be72 100644 --- a/src/common/RabbitizerConfig.c +++ b/src/common/RabbitizerConfig.c @@ -34,6 +34,7 @@ RabbitizerConfig RabbitizerConfig_Cfg = { .pseudoB = true, .pseudoMove = true, .pseudoNot = true, + .pseudoNeg = true, .pseudoNegu = true, .pseudoBal = true, }, diff --git a/src/instructions/RabbitizerInstruction/RabbitizerInstruction_ProcessUniqueId.c b/src/instructions/RabbitizerInstruction/RabbitizerInstruction_ProcessUniqueId.c index c3f6455..3b1266a 100644 --- a/src/instructions/RabbitizerInstruction/RabbitizerInstruction_ProcessUniqueId.c +++ b/src/instructions/RabbitizerInstruction/RabbitizerInstruction_ProcessUniqueId.c @@ -86,6 +86,14 @@ void RabbitizerInstruction_processUniqueId_Special(RabbitizerInstruction *self) } 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) { diff --git a/src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c b/src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c index adb8017..774c8f2 100644 --- a/src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c +++ b/src/instructions/RabbitizerInstructionRsp/RabbitizerInstructionRsp_ProcessUniqueId.c @@ -115,6 +115,12 @@ void RabbitizerInstructionRsp_processUniqueId_Special(RabbitizerInstruction *sel self->uniqueId = RABBITIZER_INSTR_ID_rsp_not; } } + } else if (self->uniqueId == RABBITIZER_INSTR_ID_rsp_sub) { + if (RAB_INSTR_GET_rs(self) == 0) { + if (RabbitizerConfig_Cfg.pseudos.pseudoNeg) { + self->uniqueId = RABBITIZER_INSTR_ID_rsp_neg; + } + } } else if (self->uniqueId == RABBITIZER_INSTR_ID_rsp_subu) { if (RAB_INSTR_GET_rs(self) == 0) { if (RabbitizerConfig_Cfg.pseudos.pseudoNegu) { diff --git a/tables/tables/instr_id/cpu/cpu_special.inc b/tables/tables/instr_id/cpu/cpu_special.inc index 0ffd98d..053c974 100644 --- a/tables/tables/instr_id/cpu/cpu_special.inc +++ b/tables/tables/instr_id/cpu/cpu_special.inc @@ -524,6 +524,16 @@ .isPseudo=true ) // Not + // OP rd, rt + RABBITIZER_DEF_INSTR_ID( + cpu, -0x22, neg, + .operands={RAB_OPERAND_cpu_rd, RAB_OPERAND_cpu_rt}, + .instrType=RABBITIZER_INSTR_TYPE_R, + .modifiesRd=true, + .readsRt=true, + .isPseudo=true + ) + // OP rd, rt RABBITIZER_DEF_INSTR_ID( cpu, -0x23, negu, diff --git a/tables/tables/instr_id/rsp/rsp_special.inc b/tables/tables/instr_id/rsp/rsp_special.inc index 571d37a..e7d9565 100644 --- a/tables/tables/instr_id/rsp/rsp_special.inc +++ b/tables/tables/instr_id/rsp/rsp_special.inc @@ -204,6 +204,16 @@ .isPseudo=true ) // Not + // OP rd, rt + RABBITIZER_DEF_INSTR_ID( + rsp, -0x22, neg, + .operands={RAB_OPERAND_rsp_rd, RAB_OPERAND_rsp_rt}, + .instrType=RABBITIZER_INSTR_TYPE_R, + .modifiesRd=true, + .readsRt=true, + .isPseudo=true + ) + // OP rd, rt RABBITIZER_DEF_INSTR_ID( rsp, -0x23, negu,