From 4e21593a8b3046584a5ba7978dce43314d898407 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:36:27 -0400 Subject: [PATCH 1/8] A32: Implement Thumb-1 variant of NOP --- src/frontend/A32/decoder/thumb16.h | 3 +++ src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 3 files changed, 12 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index 6fddedd9..a063ff78 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -87,6 +87,9 @@ 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 + // Miscellaneous 16-bit instructions INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6 INST(&V::thumb16_SXTB, "SXTB", "1011001001mmmddd"), // v6 diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index 9ed44da0..2ae57711 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -246,6 +246,10 @@ public: return fmt::format("sub sp, sp, #{}", imm32); } + std::string thumb16_NOP() { + return "nop"; + } + std::string thumb16_SXTH(Reg m, Reg d) { return fmt::format("sxth {}, {}", d, m); } diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index e940184a..31ef1c94 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -667,6 +667,11 @@ struct ThumbTranslatorVisitor final { return true; } + // NOP + bool thumb16_NOP() { + return true; + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) { From 489083438be9ab14ba930194292ad74cb89008b6 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:40:12 -0400 Subject: [PATCH 2/8] A32/translate_thumb: Add helper function for raising exceptions Similar to the variant within the ARM-mode translator visitor. This will be used in subsequent changes to implement the hint instructions introduced in ARMv7. --- src/frontend/A32/translate/translate_thumb.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index 31ef1c94..bfd478a7 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(); From 2396d6ace9e0a4c62bc81260e9086c11a9473cda Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:43:39 -0400 Subject: [PATCH 3/8] A32: Implement Thumb-1 variant of SEV --- src/frontend/A32/decoder/thumb16.h | 1 + src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index a063ff78..7d73ecc7 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -89,6 +89,7 @@ std::optional>> DecodeThumb16(u16 // Hint instructions INST(&V::thumb16_NOP, "NOP", "1011111100000000"), // v6T2 + INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7 // Miscellaneous 16-bit instructions INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6 diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index 2ae57711..b08e69f8 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -250,6 +250,10 @@ public: return "nop"; } + std::string thumb16_SEV() { + return "sev"; + } + std::string thumb16_SXTH(Reg m, Reg d) { return fmt::format("sxth {}, {}", d, m); } diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index bfd478a7..8172f62e 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -679,6 +679,11 @@ struct ThumbTranslatorVisitor final { return true; } + // SEV + bool thumb16_SEV() { + return RaiseException(Exception::SendEvent); + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) { From b6a6a23f8d5b75106b8c00cc9f0f2b5e1fecd32c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:46:26 -0400 Subject: [PATCH 4/8] A32: Implement Thumb-1 variant of WFE --- src/frontend/A32/decoder/thumb16.h | 1 + src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index 7d73ecc7..77bcd797 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -90,6 +90,7 @@ std::optional>> DecodeThumb16(u16 // Hint instructions INST(&V::thumb16_NOP, "NOP", "1011111100000000"), // v6T2 INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7 + INST(&V::thumb16_WFE, "WFE", "1011111100100000"), // v7 // Miscellaneous 16-bit instructions INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6 diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index b08e69f8..6949b07e 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -254,6 +254,10 @@ public: return "sev"; } + std::string thumb16_WFE() { + return "wfe"; + } + std::string thumb16_SXTH(Reg m, Reg d) { return fmt::format("sxth {}, {}", d, m); } diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index 8172f62e..bb9ddc1e 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -684,6 +684,11 @@ struct ThumbTranslatorVisitor final { return RaiseException(Exception::SendEvent); } + // WFE + bool thumb16_WFE() { + return RaiseException(Exception::WaitForEvent); + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) { From 293d5355b6f43ffd28eace4cb9da3ed668d9ac59 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:48:04 -0400 Subject: [PATCH 5/8] A32: Implement Thumb-1 variant of WFI --- src/frontend/A32/decoder/thumb16.h | 1 + src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index 77bcd797..934e4c80 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -91,6 +91,7 @@ std::optional>> DecodeThumb16(u16 INST(&V::thumb16_NOP, "NOP", "1011111100000000"), // v6T2 INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7 INST(&V::thumb16_WFE, "WFE", "1011111100100000"), // v7 + INST(&V::thumb16_WFI, "WFI", "1011111100110000"), // v7 // Miscellaneous 16-bit instructions INST(&V::thumb16_SXTH, "SXTH", "1011001000mmmddd"), // v6 diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index 6949b07e..12aa0238 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -258,6 +258,10 @@ public: return "wfe"; } + std::string thumb16_WFI() { + return "wfi"; + } + std::string thumb16_SXTH(Reg m, Reg d) { return fmt::format("sxth {}, {}", d, m); } diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index bb9ddc1e..bdefe327 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -689,6 +689,11 @@ struct ThumbTranslatorVisitor final { return RaiseException(Exception::WaitForEvent); } + // WFI + bool thumb16_WFI() { + return RaiseException(Exception::WaitForInterrupt); + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) { From 245d41ac9354d5a52231453fb6e20671e6e508b1 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:50:47 -0400 Subject: [PATCH 6/8] A32: Implement Thumb-1 variant of YIELD --- src/frontend/A32/decoder/thumb16.h | 1 + src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 3 files changed, 10 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index 934e4c80..cdc6834e 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -92,6 +92,7 @@ std::optional>> DecodeThumb16(u16 INST(&V::thumb16_SEV, "SEV", "1011111101000000"), // v7 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 diff --git a/src/frontend/A32/disassembler/disassembler_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index 12aa0238..a496abc2 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -262,6 +262,10 @@ public: 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_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index bdefe327..9ecadbfa 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -694,6 +694,11 @@ struct ThumbTranslatorVisitor final { return RaiseException(Exception::WaitForInterrupt); } + // YIELD + bool thumb16_YIELD() { + return RaiseException(Exception::Yield); + } + // SXTH , // Rd cannot encode R15. bool thumb16_SXTH(Reg m, Reg d) { From ae7aa581b84f4a428193d2031a2204643fa9ed0b Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 10:57:26 -0400 Subject: [PATCH 7/8] A32: Implement the ARM-mode variant of SEVL --- include/dynarmic/A32/config.h | 2 ++ include/dynarmic/A64/config.h | 2 +- src/frontend/A32/decoder/arm.inc | 1 + src/frontend/A32/disassembler/disassembler_arm.cpp | 3 +++ src/frontend/A32/translate/translate_arm/hint.cpp | 4 ++++ src/frontend/A32/translate/translate_arm/translate_arm.h | 1 + 6 files changed, 12 insertions(+), 1 deletion(-) 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/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/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(); From 64ffdb6d140d9d2e7ec21eb131d6a0f435621596 Mon Sep 17 00:00:00 2001 From: Lioncash Date: Fri, 3 May 2019 11:00:03 -0400 Subject: [PATCH 8/8] A32: Implement Thumb-1 variant of SEVL While we're at it, also add the Thumb-2 encoding to the encoding table to make sure it isn't forgotten about in the future. --- src/frontend/A32/decoder/thumb16.h | 1 + src/frontend/A32/decoder/thumb32.h | 1 + src/frontend/A32/disassembler/disassembler_thumb.cpp | 4 ++++ src/frontend/A32/translate/translate_thumb.cpp | 5 +++++ 4 files changed, 11 insertions(+) diff --git a/src/frontend/A32/decoder/thumb16.h b/src/frontend/A32/decoder/thumb16.h index cdc6834e..e93a7556 100644 --- a/src/frontend/A32/decoder/thumb16.h +++ b/src/frontend/A32/decoder/thumb16.h @@ -90,6 +90,7 @@ std::optional>> DecodeThumb16(u16 // 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 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_thumb.cpp b/src/frontend/A32/disassembler/disassembler_thumb.cpp index a496abc2..a53475db 100644 --- a/src/frontend/A32/disassembler/disassembler_thumb.cpp +++ b/src/frontend/A32/disassembler/disassembler_thumb.cpp @@ -254,6 +254,10 @@ public: return "sev"; } + std::string thumb16_SEVL() { + return "sevl"; + } + std::string thumb16_WFE() { return "wfe"; } diff --git a/src/frontend/A32/translate/translate_thumb.cpp b/src/frontend/A32/translate/translate_thumb.cpp index 9ecadbfa..fae7ccf5 100644 --- a/src/frontend/A32/translate/translate_thumb.cpp +++ b/src/frontend/A32/translate/translate_thumb.cpp @@ -684,6 +684,11 @@ struct ThumbTranslatorVisitor final { return RaiseException(Exception::SendEvent); } + // SEVL + bool thumb16_SEVL() { + return RaiseException(Exception::SendEventLocal); + } + // WFE bool thumb16_WFE() { return RaiseException(Exception::WaitForEvent);