diff --git a/include/dynarmic/A32/config.h b/include/dynarmic/A32/config.h index c0bda863..1857c1bb 100644 --- a/include/dynarmic/A32/config.h +++ b/include/dynarmic/A32/config.h @@ -26,6 +26,8 @@ enum class Exception { UnpredictableInstruction, /// A SEV instruction was executed. The event register of all PEs should be set. SendEvent, + /// A SEVL instruction was executed. The event register of the current PE should be set. + SendEventLocal, /// A WFI instruction was executed. You may now enter a low-power state. WaitForInterrupt, /// A WFE instruction was executed. You may now enter a low-power state if the event register is clear. diff --git a/include/dynarmic/A64/config.h b/include/dynarmic/A64/config.h index f1f6c305..425004b5 100644 --- a/include/dynarmic/A64/config.h +++ b/include/dynarmic/A64/config.h @@ -34,7 +34,7 @@ enum class Exception { WaitForEvent, /// A SEV instruction was executed. The event register of all PEs should be set. SendEvent, - /// A SEV instruction was executed. The event register of the current PE should be set. + /// A SEVL instruction was executed. The event register of the current PE should be set. SendEventLocal, /// A YIELD instruction was executed. Yield, diff --git a/src/frontend/A32/decoder/arm.inc b/src/frontend/A32/decoder/arm.inc index 3017f97d..b131e39d 100644 --- a/src/frontend/A32/decoder/arm.inc +++ b/src/frontend/A32/decoder/arm.inc @@ -97,6 +97,7 @@ INST(arm_UXTAH, "UXTAH", "cccc01101111nnnnddddrr000111mmmm INST(arm_PLD_imm, "PLD (imm)", "11110101uz01nnnn1111iiiiiiiiiiii") // v5E for PLD; v7 for PLDW INST(arm_PLD_reg, "PLD (reg)", "11110111uz01nnnn1111iiiiitt0mmmm") // v5E for PLD; v7 for PLDW INST(arm_SEV, "SEV", "----0011001000001111000000000100") // v6K +INST(arm_SEVL, "SEVL", "----0011001000001111000000000101") // v8 INST(arm_WFE, "WFE", "----0011001000001111000000000010") // v6K INST(arm_WFI, "WFI", "----0011001000001111000000000011") // v6K INST(arm_YIELD, "YIELD", "----0011001000001111000000000001") // v6K diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index 6fddedd9..e93a7556 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -87,6 +87,14 @@ std::optional>> DecodeThumb16(u16 INST(&V::thumb16_ADD_sp_t2, "ADD (SP plus imm, T2)", "101100000vvvvvvv"), // v4T INST(&V::thumb16_SUB_sp, "SUB (SP minus imm)", "101100001vvvvvvv"), // v4T + // Hint instructions + INST(&V::thumb16_NOP, "NOP", "1011111100000000"), // v6T2 + INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7 + INST(&V::thumb16_SEVL, "SEVL", "1011111101010000"), // v8 + INST(&V::thumb16_WFE, "WFE", "1011111100100000"), // v7 + INST(&V::thumb16_WFI, "WFI", "1011111100110000"), // v7 + INST(&V::thumb16_YIELD, "YIELD", "1011111100010000"), // v7 + // Miscellaneous 16-bit instructions INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6 INST(&V::thumb16_SXTB, "SXTB", "1011001001mmmddd"), // v6 diff --git a/src/frontend/A32/decoder/thumb32.h b/src/frontend/A32/decoder/thumb32.h index 88fc2be6..55f6d2bb 100644 --- a/src/frontend/A32/decoder/thumb32.h +++ b/src/frontend/A32/decoder/thumb32.h @@ -127,6 +127,7 @@ std::optional>> DecodeThumb32(u32 //INST(&V::thumb32_WFE, "WFE", "111100111010----10-0-00000000010"), //INST(&V::thumb32_WFI, "WFI", "111100111010----10-0-00000000011"), //INST(&V::thumb32_SEV, "SEV", "111100111010----10-0-00000000100"), + //INST(&V::thumb32_SEVL, "SEVL", "111100111010----10-0-00000000101"), //INST(&V::thumb32_DBG, "DBG", "111100111010----10-0-0001111----"), //INST(&V::thumb32_CPS, "CPS", "111100111010----10-0------------"), diff --git a/src/frontend/A32/disassembler/disassembler_arm.cpp b/src/frontend/A32/disassembler/disassembler_arm.cpp index 42bbcf50..3ba0edca 100644 --- a/src/frontend/A32/disassembler/disassembler_arm.cpp +++ b/src/frontend/A32/disassembler/disassembler_arm.cpp @@ -451,6 +451,9 @@ public: std::string arm_SEV() { return "sev"; } + std::string arm_SEVL() { + return "sevl"; + } std::string arm_WFE() { return "wfe"; } diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index 9ed44da0..a53475db 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -246,6 +246,30 @@ public: return fmt::format("sub sp, sp, #{}", imm32); } + std::string thumb16_NOP() { + return "nop"; + } + + std::string thumb16_SEV() { + return "sev"; + } + + std::string thumb16_SEVL() { + return "sevl"; + } + + std::string thumb16_WFE() { + return "wfe"; + } + + std::string thumb16_WFI() { + return "wfi"; + } + + std::string thumb16_YIELD() { + return "yield"; + } + std::string thumb16_SXTH(Reg m, Reg d) { return fmt::format("sxth {}, {}", d, m); } diff --git a/src/frontend/A32/translate/translate_arm/hint.cpp b/src/frontend/A32/translate/translate_arm/hint.cpp index 8a098359..546a3f70 100644 --- a/src/frontend/A32/translate/translate_arm/hint.cpp +++ b/src/frontend/A32/translate/translate_arm/hint.cpp @@ -33,6 +33,10 @@ bool ArmTranslatorVisitor::arm_SEV() { return RaiseException(Exception::SendEvent); } +bool ArmTranslatorVisitor::arm_SEVL() { + return RaiseException(Exception::SendEventLocal); +} + bool ArmTranslatorVisitor::arm_WFE() { return RaiseException(Exception::WaitForEvent); } diff --git a/src/frontend/A32/translate/translate_arm/translate_arm.h b/src/frontend/A32/translate/translate_arm/translate_arm.h index 5f941cc1..ddfd1850 100644 --- a/src/frontend/A32/translate/translate_arm/translate_arm.h +++ b/src/frontend/A32/translate/translate_arm/translate_arm.h @@ -167,6 +167,7 @@ struct ArmTranslatorVisitor final { bool arm_PLD_imm(bool add, bool R, Reg n, Imm<12> imm12); bool arm_PLD_reg(bool add, bool R, Reg n, Imm<5> imm5, ShiftType shift, Reg m); bool arm_SEV(); + bool arm_SEVL(); bool arm_WFE(); bool arm_WFI(); bool arm_YIELD(); diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index e940184a..fae7ccf5 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -41,6 +41,13 @@ struct ThumbTranslatorVisitor final { return false; } + bool RaiseException(Exception exception) { + ir.BranchWritePC(ir.Imm32(ir.current_location.PC() + 2)); + ir.ExceptionRaised(exception); + ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}}); + return false; + } + // LSLS , , # bool thumb16_LSL_imm(Imm<5> imm5, Reg m, Reg d) { const u8 shift_n = imm5.ZeroExtend(); @@ -667,6 +674,36 @@ struct ThumbTranslatorVisitor final { return true; } + // NOP + bool thumb16_NOP() { + return true; + } + + // SEV + bool thumb16_SEV() { + return RaiseException(Exception::SendEvent); + } + + // SEVL + bool thumb16_SEVL() { + return RaiseException(Exception::SendEventLocal); + } + + // WFE + bool thumb16_WFE() { + return RaiseException(Exception::WaitForEvent); + } + + // WFI + bool thumb16_WFI() { + return RaiseException(Exception::WaitForInterrupt); + } + + // YIELD + bool thumb16_YIELD() { + return RaiseException(Exception::Yield); + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) {