diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5b8244ff..5e4cd871 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,6 +12,7 @@ set(SRCS common/x64/abi.cpp common/x64/cpu_detect.cpp common/x64/emitter.cpp + frontend/arm_types.cpp frontend/disassembler/disassembler_arm.cpp frontend/disassembler/disassembler_thumb.cpp frontend/ir/ir.cpp diff --git a/src/frontend/arm_types.cpp b/src/frontend/arm_types.cpp new file mode 100644 index 00000000..3fe4813f --- /dev/null +++ b/src/frontend/arm_types.cpp @@ -0,0 +1,42 @@ +/* This file is part of the dynarmic project. + * Copyright (c) 2016 MerryMage + * This software may be used and distributed according to the terms of the GNU + * General Public License version 2 or any later version. + */ + +#include "common/string_util.h" +#include "frontend/arm_types.h" + +namespace Dynarmic { +namespace Arm { + +const char* CondToString(Cond cond, bool explicit_al) { + constexpr std::array cond_strs = { + "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al" + }; + return (!explicit_al && cond == Cond::AL) ? "" : cond_strs.at(static_cast(cond)); +} + +const char* RegToString(Reg reg) { + constexpr std::array reg_strs = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" + }; + return reg_strs.at(static_cast(reg)); +} + +std::string RegListToString(RegList reg_list) { + std::string ret = ""; + bool first_reg = true; + for (size_t i = 0; i < 16; i++) { + if (Common::Bit(i, reg_list)) { + if (!first_reg) + ret += ", "; + ret += RegToString(static_cast(i)); + first_reg = false; + } + } + return ret; +} + +} // namespace Arm +} // namespace Dynarmic diff --git a/src/frontend/arm_types.h b/src/frontend/arm_types.h index 1b419b87..89fccec7 100644 --- a/src/frontend/arm_types.h +++ b/src/frontend/arm_types.h @@ -21,13 +21,6 @@ enum class Cond { EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV }; -inline const char* CondToString(Cond cond, bool explicit_al = false) { - constexpr std::array cond_strs = { - "eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc", "hi", "ls", "ge", "lt", "gt", "le", "al" - }; - return (!explicit_al && cond == Cond::AL) ? "" : cond_strs.at(static_cast(cond)); -} - enum class Reg { R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15, SP = R13, @@ -36,22 +29,6 @@ enum class Reg { INVALID_REG = 99 }; -inline Reg operator+(Reg reg, int number) { - ASSERT(reg != Reg::INVALID_REG); - - int new_reg = static_cast(reg) + number; - ASSERT(new_reg >= 0 && new_reg <= 15); - - return static_cast(new_reg); -} - -inline const char* RegToString(Reg reg) { - constexpr std::array reg_strs = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" - }; - return reg_strs.at(static_cast(reg)); -} - enum class ExtReg { S0, S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13, S14, S15, @@ -63,15 +40,6 @@ enum class ExtReg { D24, D25, D26, D27, D28, D29, D30, D31, }; -inline ExtReg operator+(ExtReg reg, int number) { - ExtReg new_reg = static_cast(static_cast(reg) + number); - - ASSERT((reg >= ExtReg::S0 && reg <= ExtReg::S31 && new_reg >= ExtReg::S0 && new_reg <= ExtReg::S31) - || (reg >= ExtReg::D0 && reg <= ExtReg::D31 && new_reg >= ExtReg::D0 && new_reg <= ExtReg::D31)); - - return new_reg; -} - using Imm3 = u32; using Imm4 = u32; using Imm5 = u32; @@ -151,5 +119,27 @@ struct LocationDescriptorHash { } }; +const char* CondToString(Cond cond, bool explicit_al = false); +const char* RegToString(Reg reg); +std::string RegListToString(RegList reg_list); + +inline Reg operator+(Reg reg, int number) { + ASSERT(reg != Reg::INVALID_REG); + + int new_reg = static_cast(reg) + number; + ASSERT(new_reg >= 0 && new_reg <= 15); + + return static_cast(new_reg); +} + +inline ExtReg operator+(ExtReg reg, int number) { + ExtReg new_reg = static_cast(static_cast(reg) + number); + + ASSERT((reg >= ExtReg::S0 && reg <= ExtReg::S31 && new_reg >= ExtReg::S0 && new_reg <= ExtReg::S31) + || (reg >= ExtReg::D0 && reg <= ExtReg::D31 && new_reg >= ExtReg::D0 && new_reg <= ExtReg::D31)); + + return new_reg; +} + } // namespace Arm } // namespace Dynarmic diff --git a/src/frontend/disassembler/disassembler_thumb.cpp b/src/frontend/disassembler/disassembler_thumb.cpp index 49afc573..1a3fd998 100644 --- a/src/frontend/disassembler/disassembler_thumb.cpp +++ b/src/frontend/disassembler/disassembler_thumb.cpp @@ -22,20 +22,6 @@ public: return value >= 0 ? "+" : "-"; } - std::string RegListStr(RegList reg_list) { - std::string ret = ""; - bool first_reg = true; - for (size_t i = 0; i < 16; i++) { - if (Common::Bit(i, reg_list)) { - if (!first_reg) - ret += ", "; - ret += RegToString(static_cast(i)); - first_reg = false; - } - } - return ret; - } - std::string thumb16_LSL_imm(Imm5 imm5, Reg m, Reg d) { return Common::StringFromFormat("lsls %s, %s, #%u", RegToString(d), RegToString(m), imm5); } @@ -271,12 +257,12 @@ public: std::string thumb16_PUSH(bool M, RegList reg_list) { if (M) reg_list |= 1 << 14; - return "push " + RegListStr(reg_list); + return "push " + RegListToString(reg_list); } std::string thumb16_POP(bool P, RegList reg_list) { if (P) reg_list |= 1 << 15; - return "pop " + RegListStr(reg_list); + return "pop " + RegListToString(reg_list); } std::string thumb16_SETEND(bool E) { @@ -296,12 +282,12 @@ public: } std::string thumb16_STMIA(Reg n, RegList reg_list) { - return Common::StringFromFormat("stm %s!, %s", RegToString(n), RegListStr(reg_list).c_str()); + return Common::StringFromFormat("stm %s!, %s", RegToString(n), RegListToString(reg_list).c_str()); } std::string thumb16_LDMIA(Reg n, RegList reg_list) { bool write_back = !Dynarmic::Common::Bit(static_cast(n), reg_list); - return Common::StringFromFormat("ldm %s%s, %s", RegToString(n), write_back ? "!" : "", RegListStr(reg_list).c_str()); + return Common::StringFromFormat("ldm %s%s, %s", RegToString(n), write_back ? "!" : "", RegListToString(reg_list).c_str()); } std::string thumb16_BX(Reg m) {