ArmTypes: Add RegListToString and reorganise
This commit is contained in:
parent
975f011fc0
commit
46e4864707
4 changed files with 69 additions and 50 deletions
|
@ -12,6 +12,7 @@ set(SRCS
|
||||||
common/x64/abi.cpp
|
common/x64/abi.cpp
|
||||||
common/x64/cpu_detect.cpp
|
common/x64/cpu_detect.cpp
|
||||||
common/x64/emitter.cpp
|
common/x64/emitter.cpp
|
||||||
|
frontend/arm_types.cpp
|
||||||
frontend/disassembler/disassembler_arm.cpp
|
frontend/disassembler/disassembler_arm.cpp
|
||||||
frontend/disassembler/disassembler_thumb.cpp
|
frontend/disassembler/disassembler_thumb.cpp
|
||||||
frontend/ir/ir.cpp
|
frontend/ir/ir.cpp
|
||||||
|
|
42
src/frontend/arm_types.cpp
Normal file
42
src/frontend/arm_types.cpp
Normal file
|
@ -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<const char*, 15> 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<size_t>(cond));
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* RegToString(Reg reg) {
|
||||||
|
constexpr std::array<const char*, 16> reg_strs = {
|
||||||
|
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"
|
||||||
|
};
|
||||||
|
return reg_strs.at(static_cast<size_t>(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<Reg>(i));
|
||||||
|
first_reg = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Arm
|
||||||
|
} // namespace Dynarmic
|
|
@ -21,13 +21,6 @@ enum class Cond {
|
||||||
EQ, NE, CS, CC, MI, PL, VS, VC, HI, LS, GE, LT, GT, LE, AL, NV
|
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<const char*, 15> 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<size_t>(cond));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class Reg {
|
enum class Reg {
|
||||||
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15,
|
R0, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10, R11, R12, R13, R14, R15,
|
||||||
SP = R13,
|
SP = R13,
|
||||||
|
@ -36,22 +29,6 @@ enum class Reg {
|
||||||
INVALID_REG = 99
|
INVALID_REG = 99
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Reg operator+(Reg reg, int number) {
|
|
||||||
ASSERT(reg != Reg::INVALID_REG);
|
|
||||||
|
|
||||||
int new_reg = static_cast<int>(reg) + number;
|
|
||||||
ASSERT(new_reg >= 0 && new_reg <= 15);
|
|
||||||
|
|
||||||
return static_cast<Reg>(new_reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const char* RegToString(Reg reg) {
|
|
||||||
constexpr std::array<const char*, 16> reg_strs = {
|
|
||||||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc"
|
|
||||||
};
|
|
||||||
return reg_strs.at(static_cast<size_t>(reg));
|
|
||||||
}
|
|
||||||
|
|
||||||
enum class ExtReg {
|
enum class ExtReg {
|
||||||
S0, S1, S2, S3, S4, S5, S6, S7,
|
S0, S1, S2, S3, S4, S5, S6, S7,
|
||||||
S8, S9, S10, S11, S12, S13, S14, S15,
|
S8, S9, S10, S11, S12, S13, S14, S15,
|
||||||
|
@ -63,15 +40,6 @@ enum class ExtReg {
|
||||||
D24, D25, D26, D27, D28, D29, D30, D31,
|
D24, D25, D26, D27, D28, D29, D30, D31,
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ExtReg operator+(ExtReg reg, int number) {
|
|
||||||
ExtReg new_reg = static_cast<ExtReg>(static_cast<int>(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 Imm3 = u32;
|
||||||
using Imm4 = u32;
|
using Imm4 = u32;
|
||||||
using Imm5 = 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<int>(reg) + number;
|
||||||
|
ASSERT(new_reg >= 0 && new_reg <= 15);
|
||||||
|
|
||||||
|
return static_cast<Reg>(new_reg);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline ExtReg operator+(ExtReg reg, int number) {
|
||||||
|
ExtReg new_reg = static_cast<ExtReg>(static_cast<int>(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 Arm
|
||||||
} // namespace Dynarmic
|
} // namespace Dynarmic
|
||||||
|
|
|
@ -22,20 +22,6 @@ public:
|
||||||
return value >= 0 ? "+" : "-";
|
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<Reg>(i));
|
|
||||||
first_reg = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string thumb16_LSL_imm(Imm5 imm5, Reg m, Reg d) {
|
std::string thumb16_LSL_imm(Imm5 imm5, Reg m, Reg d) {
|
||||||
return Common::StringFromFormat("lsls %s, %s, #%u", RegToString(d), RegToString(m), imm5);
|
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) {
|
std::string thumb16_PUSH(bool M, RegList reg_list) {
|
||||||
if (M) reg_list |= 1 << 14;
|
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) {
|
std::string thumb16_POP(bool P, RegList reg_list) {
|
||||||
if (P) reg_list |= 1 << 15;
|
if (P) reg_list |= 1 << 15;
|
||||||
return "pop " + RegListStr(reg_list);
|
return "pop " + RegListToString(reg_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string thumb16_SETEND(bool E) {
|
std::string thumb16_SETEND(bool E) {
|
||||||
|
@ -296,12 +282,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string thumb16_STMIA(Reg n, RegList reg_list) {
|
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) {
|
std::string thumb16_LDMIA(Reg n, RegList reg_list) {
|
||||||
bool write_back = !Dynarmic::Common::Bit(static_cast<size_t>(n), reg_list);
|
bool write_back = !Dynarmic::Common::Bit(static_cast<size_t>(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) {
|
std::string thumb16_BX(Reg m) {
|
||||||
|
|
Loading…
Reference in a new issue