mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-03-08 05:26:28 +00:00
IR: Split off A32 specific opcodes
This commit is contained in:
@@ -27,16 +27,16 @@ IR::Value IREmitter::GetRegister(A32::Reg reg) {
|
||||
if (reg == A32::Reg::PC) {
|
||||
return Imm32(PC());
|
||||
}
|
||||
return Inst(Opcode::GetRegister, { IR::Value(reg) });
|
||||
return Inst(Opcode::A32GetRegister, { IR::Value(reg) });
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetExtendedRegister(A32::ExtReg reg) {
|
||||
if (A32::IsSingleExtReg(reg)) {
|
||||
return Inst(Opcode::GetExtendedRegister32, {IR::Value(reg)});
|
||||
return Inst(Opcode::A32GetExtendedRegister32, {IR::Value(reg)});
|
||||
}
|
||||
|
||||
if (A32::IsDoubleExtReg(reg)) {
|
||||
return Inst(Opcode::GetExtendedRegister64, {IR::Value(reg)});
|
||||
return Inst(Opcode::A32GetExtendedRegister64, {IR::Value(reg)});
|
||||
}
|
||||
|
||||
ASSERT_MSG(false, "Invalid reg.");
|
||||
@@ -44,14 +44,14 @@ IR::Value IREmitter::GetExtendedRegister(A32::ExtReg reg) {
|
||||
|
||||
void IREmitter::SetRegister(const A32::Reg reg, const IR::Value& value) {
|
||||
ASSERT(reg != A32::Reg::PC);
|
||||
Inst(Opcode::SetRegister, { IR::Value(reg), value });
|
||||
Inst(Opcode::A32SetRegister, { IR::Value(reg), value });
|
||||
}
|
||||
|
||||
void IREmitter::SetExtendedRegister(const A32::ExtReg reg, const IR::Value& value) {
|
||||
if (A32::IsSingleExtReg(reg)) {
|
||||
Inst(Opcode::SetExtendedRegister32, {IR::Value(reg), value});
|
||||
Inst(Opcode::A32SetExtendedRegister32, {IR::Value(reg), value});
|
||||
} else if (A32::IsDoubleExtReg(reg)) {
|
||||
Inst(Opcode::SetExtendedRegister64, {IR::Value(reg), value});
|
||||
Inst(Opcode::A32SetExtendedRegister64, {IR::Value(reg), value});
|
||||
} else {
|
||||
ASSERT_MSG(false, "Invalid reg.");
|
||||
}
|
||||
@@ -66,15 +66,15 @@ void IREmitter::ALUWritePC(const IR::Value& value) {
|
||||
void IREmitter::BranchWritePC(const IR::Value& value) {
|
||||
if (!current_location.TFlag()) {
|
||||
auto new_pc = And(value, Imm32(0xFFFFFFFC));
|
||||
Inst(Opcode::SetRegister, { IR::Value(A32::Reg::PC), new_pc });
|
||||
Inst(Opcode::A32SetRegister, { IR::Value(A32::Reg::PC), new_pc });
|
||||
} else {
|
||||
auto new_pc = And(value, Imm32(0xFFFFFFFE));
|
||||
Inst(Opcode::SetRegister, { IR::Value(A32::Reg::PC), new_pc });
|
||||
Inst(Opcode::A32SetRegister, { IR::Value(A32::Reg::PC), new_pc });
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::BXWritePC(const IR::Value& value) {
|
||||
Inst(Opcode::BXWritePC, {value});
|
||||
Inst(Opcode::A32BXWritePC, {value});
|
||||
}
|
||||
|
||||
void IREmitter::LoadWritePC(const IR::Value& value) {
|
||||
@@ -84,159 +84,155 @@ void IREmitter::LoadWritePC(const IR::Value& value) {
|
||||
}
|
||||
|
||||
void IREmitter::CallSupervisor(const IR::Value& value) {
|
||||
Inst(Opcode::CallSupervisor, {value});
|
||||
}
|
||||
|
||||
void IREmitter::PushRSB(const A32::LocationDescriptor& return_location) {
|
||||
Inst(Opcode::PushRSB, {IR::Value(return_location.UniqueHash())});
|
||||
Inst(Opcode::A32CallSupervisor, {value});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetCpsr() {
|
||||
return Inst(Opcode::GetCpsr, {});
|
||||
return Inst(Opcode::A32GetCpsr, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetCpsr(const IR::Value& value) {
|
||||
Inst(Opcode::SetCpsr, {value});
|
||||
Inst(Opcode::A32SetCpsr, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetCpsrNZCV(const IR::Value& value) {
|
||||
Inst(Opcode::SetCpsrNZCV, {value});
|
||||
Inst(Opcode::A32SetCpsrNZCV, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetCpsrNZCVQ(const IR::Value& value) {
|
||||
Inst(Opcode::SetCpsrNZCVQ, {value});
|
||||
Inst(Opcode::A32SetCpsrNZCVQ, {value});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetCFlag() {
|
||||
return Inst(Opcode::GetCFlag, {});
|
||||
return Inst(Opcode::A32GetCFlag, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetNFlag(const IR::Value& value) {
|
||||
Inst(Opcode::SetNFlag, {value});
|
||||
Inst(Opcode::A32SetNFlag, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetZFlag(const IR::Value& value) {
|
||||
Inst(Opcode::SetZFlag, {value});
|
||||
Inst(Opcode::A32SetZFlag, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetCFlag(const IR::Value& value) {
|
||||
Inst(Opcode::SetCFlag, {value});
|
||||
Inst(Opcode::A32SetCFlag, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetVFlag(const IR::Value& value) {
|
||||
Inst(Opcode::SetVFlag, {value});
|
||||
Inst(Opcode::A32SetVFlag, {value});
|
||||
}
|
||||
|
||||
void IREmitter::OrQFlag(const IR::Value& value) {
|
||||
Inst(Opcode::OrQFlag, {value});
|
||||
Inst(Opcode::A32OrQFlag, {value});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetGEFlags() {
|
||||
return Inst(Opcode::GetGEFlags, {});
|
||||
return Inst(Opcode::A32GetGEFlags, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetGEFlags(const IR::Value& value) {
|
||||
Inst(Opcode::SetGEFlags, {value});
|
||||
Inst(Opcode::A32SetGEFlags, {value});
|
||||
}
|
||||
|
||||
void IREmitter::SetGEFlagsCompressed(const IR::Value& value) {
|
||||
Inst(Opcode::SetGEFlagsCompressed, {value});
|
||||
Inst(Opcode::A32SetGEFlagsCompressed, {value});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetFpscr() {
|
||||
return Inst(Opcode::GetFpscr, {});
|
||||
return Inst(Opcode::A32GetFpscr, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetFpscr(const IR::Value& new_fpscr) {
|
||||
Inst(Opcode::SetFpscr, {new_fpscr});
|
||||
Inst(Opcode::A32SetFpscr, {new_fpscr});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::GetFpscrNZCV() {
|
||||
return Inst(Opcode::GetFpscrNZCV, {});
|
||||
return Inst(Opcode::A32GetFpscrNZCV, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetFpscrNZCV(const IR::Value& new_fpscr_nzcv) {
|
||||
Inst(Opcode::SetFpscrNZCV, {new_fpscr_nzcv});
|
||||
Inst(Opcode::A32SetFpscrNZCV, {new_fpscr_nzcv});
|
||||
}
|
||||
|
||||
void IREmitter::ClearExclusive() {
|
||||
Inst(Opcode::ClearExclusive, {});
|
||||
Inst(Opcode::A32ClearExclusive, {});
|
||||
}
|
||||
|
||||
void IREmitter::SetExclusive(const IR::Value& vaddr, size_t byte_size) {
|
||||
ASSERT(byte_size == 1 || byte_size == 2 || byte_size == 4 || byte_size == 8 || byte_size == 16);
|
||||
Inst(Opcode::SetExclusive, {vaddr, Imm8(u8(byte_size))});
|
||||
Inst(Opcode::A32SetExclusive, {vaddr, Imm8(u8(byte_size))});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ReadMemory8(const IR::Value& vaddr) {
|
||||
return Inst(Opcode::ReadMemory8, {vaddr});
|
||||
return Inst(Opcode::A32ReadMemory8, {vaddr});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ReadMemory16(const IR::Value& vaddr) {
|
||||
auto value = Inst(Opcode::ReadMemory16, {vaddr});
|
||||
auto value = Inst(Opcode::A32ReadMemory16, {vaddr});
|
||||
return current_location.EFlag() ? ByteReverseHalf(value) : value;
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ReadMemory32(const IR::Value& vaddr) {
|
||||
auto value = Inst(Opcode::ReadMemory32, {vaddr});
|
||||
auto value = Inst(Opcode::A32ReadMemory32, {vaddr});
|
||||
return current_location.EFlag() ? ByteReverseWord(value) : value;
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ReadMemory64(const IR::Value& vaddr) {
|
||||
auto value = Inst(Opcode::ReadMemory64, {vaddr});
|
||||
auto value = Inst(Opcode::A32ReadMemory64, {vaddr});
|
||||
return current_location.EFlag() ? ByteReverseDual(value) : value;
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory8(const IR::Value& vaddr, const IR::Value& value) {
|
||||
Inst(Opcode::WriteMemory8, {vaddr, value});
|
||||
Inst(Opcode::A32WriteMemory8, {vaddr, value});
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory16(const IR::Value& vaddr, const IR::Value& value) {
|
||||
if (current_location.EFlag()) {
|
||||
auto v = ByteReverseHalf(value);
|
||||
Inst(Opcode::WriteMemory16, {vaddr, v});
|
||||
Inst(Opcode::A32WriteMemory16, {vaddr, v});
|
||||
} else {
|
||||
Inst(Opcode::WriteMemory16, {vaddr, value});
|
||||
Inst(Opcode::A32WriteMemory16, {vaddr, value});
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory32(const IR::Value& vaddr, const IR::Value& value) {
|
||||
if (current_location.EFlag()) {
|
||||
auto v = ByteReverseWord(value);
|
||||
Inst(Opcode::WriteMemory32, {vaddr, v});
|
||||
Inst(Opcode::A32WriteMemory32, {vaddr, v});
|
||||
} else {
|
||||
Inst(Opcode::WriteMemory32, {vaddr, value});
|
||||
Inst(Opcode::A32WriteMemory32, {vaddr, value});
|
||||
}
|
||||
}
|
||||
|
||||
void IREmitter::WriteMemory64(const IR::Value& vaddr, const IR::Value& value) {
|
||||
if (current_location.EFlag()) {
|
||||
auto v = ByteReverseDual(value);
|
||||
Inst(Opcode::WriteMemory64, {vaddr, v});
|
||||
Inst(Opcode::A32WriteMemory64, {vaddr, v});
|
||||
} else {
|
||||
Inst(Opcode::WriteMemory64, {vaddr, value});
|
||||
Inst(Opcode::A32WriteMemory64, {vaddr, value});
|
||||
}
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ExclusiveWriteMemory8(const IR::Value& vaddr, const IR::Value& value) {
|
||||
return Inst(Opcode::ExclusiveWriteMemory8, {vaddr, value});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory8, {vaddr, value});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ExclusiveWriteMemory16(const IR::Value& vaddr, const IR::Value& value) {
|
||||
if (current_location.EFlag()) {
|
||||
auto v = ByteReverseHalf(value);
|
||||
return Inst(Opcode::ExclusiveWriteMemory16, {vaddr, v});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory16, {vaddr, v});
|
||||
} else {
|
||||
return Inst(Opcode::ExclusiveWriteMemory16, {vaddr, value});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory16, {vaddr, value});
|
||||
}
|
||||
}
|
||||
|
||||
IR::Value IREmitter::ExclusiveWriteMemory32(const IR::Value& vaddr, const IR::Value& value) {
|
||||
if (current_location.EFlag()) {
|
||||
auto v = ByteReverseWord(value);
|
||||
return Inst(Opcode::ExclusiveWriteMemory32, {vaddr, v});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory32, {vaddr, v});
|
||||
} else {
|
||||
return Inst(Opcode::ExclusiveWriteMemory32, {vaddr, value});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory32, {vaddr, value});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,9 +240,9 @@ IR::Value IREmitter::ExclusiveWriteMemory64(const IR::Value& vaddr, const IR::Va
|
||||
if (current_location.EFlag()) {
|
||||
auto vlo = ByteReverseWord(value_lo);
|
||||
auto vhi = ByteReverseWord(value_hi);
|
||||
return Inst(Opcode::ExclusiveWriteMemory64, {vaddr, vlo, vhi});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory64, {vaddr, vlo, vhi});
|
||||
} else {
|
||||
return Inst(Opcode::ExclusiveWriteMemory64, {vaddr, value_lo, value_hi});
|
||||
return Inst(Opcode::A32ExclusiveWriteMemory64, {vaddr, value_lo, value_hi});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +255,7 @@ void IREmitter::CoprocInternalOperation(size_t coproc_no, bool two, size_t opc1,
|
||||
static_cast<u8>(CRn),
|
||||
static_cast<u8>(CRm),
|
||||
static_cast<u8>(opc2)};
|
||||
Inst(Opcode::CoprocInternalOperation, {IR::Value(coproc_info)});
|
||||
Inst(Opcode::A32CoprocInternalOperation, {IR::Value(coproc_info)});
|
||||
}
|
||||
|
||||
void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2, const IR::Value& word) {
|
||||
@@ -270,7 +266,7 @@ void IREmitter::CoprocSendOneWord(size_t coproc_no, bool two, size_t opc1, A32::
|
||||
static_cast<u8>(CRn),
|
||||
static_cast<u8>(CRm),
|
||||
static_cast<u8>(opc2)};
|
||||
Inst(Opcode::CoprocSendOneWord, {IR::Value(coproc_info), word});
|
||||
Inst(Opcode::A32CoprocSendOneWord, {IR::Value(coproc_info), word});
|
||||
}
|
||||
|
||||
void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm, const IR::Value& word1, const IR::Value& word2) {
|
||||
@@ -279,7 +275,7 @@ void IREmitter::CoprocSendTwoWords(size_t coproc_no, bool two, size_t opc, A32::
|
||||
static_cast<u8>(two ? 1 : 0),
|
||||
static_cast<u8>(opc),
|
||||
static_cast<u8>(CRm)};
|
||||
Inst(Opcode::CoprocSendTwoWords, {IR::Value(coproc_info), word1, word2});
|
||||
Inst(Opcode::A32CoprocSendTwoWords, {IR::Value(coproc_info), word1, word2});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A32::CoprocReg CRn, A32::CoprocReg CRm, size_t opc2) {
|
||||
@@ -290,7 +286,7 @@ IR::Value IREmitter::CoprocGetOneWord(size_t coproc_no, bool two, size_t opc1, A
|
||||
static_cast<u8>(CRn),
|
||||
static_cast<u8>(CRm),
|
||||
static_cast<u8>(opc2)};
|
||||
return Inst(Opcode::CoprocGetOneWord, {IR::Value(coproc_info)});
|
||||
return Inst(Opcode::A32CoprocGetOneWord, {IR::Value(coproc_info)});
|
||||
}
|
||||
|
||||
IR::Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A32::CoprocReg CRm) {
|
||||
@@ -299,7 +295,7 @@ IR::Value IREmitter::CoprocGetTwoWords(size_t coproc_no, bool two, size_t opc, A
|
||||
static_cast<u8>(two ? 1 : 0),
|
||||
static_cast<u8>(opc),
|
||||
static_cast<u8>(CRm)};
|
||||
return Inst(Opcode::CoprocGetTwoWords, {IR::Value(coproc_info)});
|
||||
return Inst(Opcode::A32CoprocGetTwoWords, {IR::Value(coproc_info)});
|
||||
}
|
||||
|
||||
void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const IR::Value& address, bool has_option, u8 option) {
|
||||
@@ -310,7 +306,7 @@ void IREmitter::CoprocLoadWords(size_t coproc_no, bool two, bool long_transfer,
|
||||
static_cast<u8>(CRd),
|
||||
static_cast<u8>(has_option ? 1 : 0),
|
||||
static_cast<u8>(option)};
|
||||
Inst(Opcode::CoprocLoadWords, {IR::Value(coproc_info), address});
|
||||
Inst(Opcode::A32CoprocLoadWords, {IR::Value(coproc_info), address});
|
||||
}
|
||||
|
||||
void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer, A32::CoprocReg CRd, const IR::Value& address, bool has_option, u8 option) {
|
||||
@@ -321,7 +317,7 @@ void IREmitter::CoprocStoreWords(size_t coproc_no, bool two, bool long_transfer,
|
||||
static_cast<u8>(CRd),
|
||||
static_cast<u8>(has_option ? 1 : 0),
|
||||
static_cast<u8>(option)};
|
||||
Inst(Opcode::CoprocStoreWords, {IR::Value(coproc_info), address});
|
||||
Inst(Opcode::A32CoprocStoreWords, {IR::Value(coproc_info), address});
|
||||
}
|
||||
|
||||
} // namespace IR
|
||||
|
||||
@@ -43,7 +43,6 @@ public:
|
||||
void BXWritePC(const IR::Value& value);
|
||||
void LoadWritePC(const IR::Value& value);
|
||||
void CallSupervisor(const IR::Value& value);
|
||||
void PushRSB(const A32::LocationDescriptor& return_location);
|
||||
|
||||
IR::Value GetCpsr();
|
||||
void SetCpsr(const IR::Value& value);
|
||||
|
||||
@@ -31,6 +31,10 @@ Value IREmitter::Imm64(u64 imm64) {
|
||||
return Value(imm64);
|
||||
}
|
||||
|
||||
void IREmitter::PushRSB(const LocationDescriptor& return_location) {
|
||||
Inst(Opcode::PushRSB, {IR::Value(return_location.Value())});
|
||||
}
|
||||
|
||||
Value IREmitter::Pack2x32To1x64(const Value& lo, const Value& hi) {
|
||||
return Inst(Opcode::Pack2x32To1x64, {lo, hi});
|
||||
}
|
||||
|
||||
@@ -67,6 +67,8 @@ public:
|
||||
Value Imm32(u32 value);
|
||||
Value Imm64(u64 value);
|
||||
|
||||
void PushRSB(const LocationDescriptor& return_location);
|
||||
|
||||
Value Pack2x32To1x64(const Value& lo, const Value& hi);
|
||||
Value LeastSignificantWord(const Value& value);
|
||||
ResultAndCarry MostSignificantWord(const Value& value);
|
||||
|
||||
@@ -41,10 +41,10 @@ bool Inst::IsShift() const {
|
||||
|
||||
bool Inst::IsSharedMemoryRead() const {
|
||||
switch (op) {
|
||||
case Opcode::ReadMemory8:
|
||||
case Opcode::ReadMemory16:
|
||||
case Opcode::ReadMemory32:
|
||||
case Opcode::ReadMemory64:
|
||||
case Opcode::A32ReadMemory8:
|
||||
case Opcode::A32ReadMemory16:
|
||||
case Opcode::A32ReadMemory32:
|
||||
case Opcode::A32ReadMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -54,10 +54,10 @@ bool Inst::IsSharedMemoryRead() const {
|
||||
|
||||
bool Inst::IsSharedMemoryWrite() const {
|
||||
switch (op) {
|
||||
case Opcode::WriteMemory8:
|
||||
case Opcode::WriteMemory16:
|
||||
case Opcode::WriteMemory32:
|
||||
case Opcode::WriteMemory64:
|
||||
case Opcode::A32WriteMemory8:
|
||||
case Opcode::A32WriteMemory16:
|
||||
case Opcode::A32WriteMemory32:
|
||||
case Opcode::A32WriteMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -71,10 +71,10 @@ bool Inst::IsSharedMemoryReadOrWrite() const {
|
||||
|
||||
bool Inst::IsExclusiveMemoryWrite() const {
|
||||
switch (op) {
|
||||
case Opcode::ExclusiveWriteMemory8:
|
||||
case Opcode::ExclusiveWriteMemory16:
|
||||
case Opcode::ExclusiveWriteMemory32:
|
||||
case Opcode::ExclusiveWriteMemory64:
|
||||
case Opcode::A32ExclusiveWriteMemory8:
|
||||
case Opcode::A32ExclusiveWriteMemory16:
|
||||
case Opcode::A32ExclusiveWriteMemory32:
|
||||
case Opcode::A32ExclusiveWriteMemory64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -96,12 +96,12 @@ bool Inst::IsMemoryReadOrWrite() const {
|
||||
|
||||
bool Inst::ReadsFromCPSR() const {
|
||||
switch (op) {
|
||||
case Opcode::GetCpsr:
|
||||
case Opcode::GetNFlag:
|
||||
case Opcode::GetZFlag:
|
||||
case Opcode::GetCFlag:
|
||||
case Opcode::GetVFlag:
|
||||
case Opcode::GetGEFlags:
|
||||
case Opcode::A32GetCpsr:
|
||||
case Opcode::A32GetNFlag:
|
||||
case Opcode::A32GetZFlag:
|
||||
case Opcode::A32GetCFlag:
|
||||
case Opcode::A32GetVFlag:
|
||||
case Opcode::A32GetGEFlags:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -111,16 +111,16 @@ bool Inst::ReadsFromCPSR() const {
|
||||
|
||||
bool Inst::WritesToCPSR() const {
|
||||
switch (op) {
|
||||
case Opcode::SetCpsr:
|
||||
case Opcode::SetCpsrNZCV:
|
||||
case Opcode::SetCpsrNZCVQ:
|
||||
case Opcode::SetNFlag:
|
||||
case Opcode::SetZFlag:
|
||||
case Opcode::SetCFlag:
|
||||
case Opcode::SetVFlag:
|
||||
case Opcode::OrQFlag:
|
||||
case Opcode::SetGEFlags:
|
||||
case Opcode::SetGEFlagsCompressed:
|
||||
case Opcode::A32SetCpsr:
|
||||
case Opcode::A32SetCpsrNZCV:
|
||||
case Opcode::A32SetCpsrNZCVQ:
|
||||
case Opcode::A32SetNFlag:
|
||||
case Opcode::A32SetZFlag:
|
||||
case Opcode::A32SetCFlag:
|
||||
case Opcode::A32SetVFlag:
|
||||
case Opcode::A32OrQFlag:
|
||||
case Opcode::A32SetGEFlags:
|
||||
case Opcode::A32SetGEFlagsCompressed:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -130,9 +130,9 @@ bool Inst::WritesToCPSR() const {
|
||||
|
||||
bool Inst::ReadsFromCoreRegister() const {
|
||||
switch (op) {
|
||||
case Opcode::GetRegister:
|
||||
case Opcode::GetExtendedRegister32:
|
||||
case Opcode::GetExtendedRegister64:
|
||||
case Opcode::A32GetRegister:
|
||||
case Opcode::A32GetExtendedRegister32:
|
||||
case Opcode::A32GetExtendedRegister64:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -142,10 +142,10 @@ bool Inst::ReadsFromCoreRegister() const {
|
||||
|
||||
bool Inst::WritesToCoreRegister() const {
|
||||
switch (op) {
|
||||
case Opcode::SetRegister:
|
||||
case Opcode::SetExtendedRegister32:
|
||||
case Opcode::SetExtendedRegister64:
|
||||
case Opcode::BXWritePC:
|
||||
case Opcode::A32SetRegister:
|
||||
case Opcode::A32SetExtendedRegister32:
|
||||
case Opcode::A32SetExtendedRegister64:
|
||||
case Opcode::A32BXWritePC:
|
||||
return true;
|
||||
|
||||
default:
|
||||
@@ -155,8 +155,8 @@ bool Inst::WritesToCoreRegister() const {
|
||||
|
||||
bool Inst::ReadsFromFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::GetFpscr:
|
||||
case Opcode::GetFpscrNZCV:
|
||||
case Opcode::A32GetFpscr:
|
||||
case Opcode::A32GetFpscrNZCV:
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
@@ -182,8 +182,8 @@ bool Inst::ReadsFromFPSCR() const {
|
||||
|
||||
bool Inst::WritesToFPSCR() const {
|
||||
switch (op) {
|
||||
case Opcode::SetFpscr:
|
||||
case Opcode::SetFpscrNZCV:
|
||||
case Opcode::A32SetFpscr:
|
||||
case Opcode::A32SetFpscrNZCV:
|
||||
case Opcode::FPAbs32:
|
||||
case Opcode::FPAbs64:
|
||||
case Opcode::FPAdd32:
|
||||
@@ -209,24 +209,24 @@ bool Inst::WritesToFPSCR() const {
|
||||
|
||||
bool Inst::CausesCPUException() const {
|
||||
return op == Opcode::Breakpoint ||
|
||||
op == Opcode::CallSupervisor;
|
||||
op == Opcode::A32CallSupervisor;
|
||||
}
|
||||
|
||||
bool Inst::AltersExclusiveState() const {
|
||||
return op == Opcode::ClearExclusive ||
|
||||
op == Opcode::SetExclusive ||
|
||||
return op == Opcode::A32ClearExclusive ||
|
||||
op == Opcode::A32SetExclusive ||
|
||||
IsExclusiveMemoryWrite();
|
||||
}
|
||||
|
||||
bool Inst::IsCoprocessorInstruction() const {
|
||||
switch (op) {
|
||||
case Opcode::CoprocInternalOperation:
|
||||
case Opcode::CoprocSendOneWord:
|
||||
case Opcode::CoprocSendTwoWords:
|
||||
case Opcode::CoprocGetOneWord:
|
||||
case Opcode::CoprocGetTwoWords:
|
||||
case Opcode::CoprocLoadWords:
|
||||
case Opcode::CoprocStoreWords:
|
||||
case Opcode::A32CoprocInternalOperation:
|
||||
case Opcode::A32CoprocSendOneWord:
|
||||
case Opcode::A32CoprocSendTwoWords:
|
||||
case Opcode::A32CoprocGetOneWord:
|
||||
case Opcode::A32CoprocGetTwoWords:
|
||||
case Opcode::A32CoprocLoadWords:
|
||||
case Opcode::A32CoprocStoreWords:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
||||
@@ -27,8 +27,10 @@ struct Meta {
|
||||
|
||||
static const std::map<Opcode, Meta> opcode_info {{
|
||||
#define OPCODE(name, type, ...) { Opcode::name, { #name, type, { __VA_ARGS__ } } },
|
||||
#define A32OPC(name, type, ...) { Opcode::A32##name, { #name, type, { __VA_ARGS__ } } },
|
||||
#include "opcodes.inc"
|
||||
#undef OPCODE
|
||||
#undef A32OPC
|
||||
}};
|
||||
|
||||
} // namespace OpcodeInfo
|
||||
|
||||
@@ -17,8 +17,10 @@ namespace IR {
|
||||
*/
|
||||
enum class Opcode {
|
||||
#define OPCODE(name, type, ...) name,
|
||||
#define A32OPC(name, type, ...) A32##name,
|
||||
#include "opcodes.inc"
|
||||
#undef OPCODE
|
||||
#undef A32OPC
|
||||
NUM_OPCODE
|
||||
};
|
||||
|
||||
|
||||
@@ -4,35 +4,35 @@ OPCODE(Void, T::Void,
|
||||
OPCODE(Identity, T::Opaque, T::Opaque )
|
||||
OPCODE(Breakpoint, T::Void, )
|
||||
|
||||
// ARM Context getters/setters
|
||||
OPCODE(GetRegister, T::U32, T::RegRef )
|
||||
OPCODE(GetExtendedRegister32, T::F32, T::ExtRegRef )
|
||||
OPCODE(GetExtendedRegister64, T::F64, T::ExtRegRef )
|
||||
OPCODE(SetRegister, T::Void, T::RegRef, T::U32 )
|
||||
OPCODE(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32 )
|
||||
OPCODE(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 )
|
||||
OPCODE(GetCpsr, T::U32, )
|
||||
OPCODE(SetCpsr, T::Void, T::U32 )
|
||||
OPCODE(SetCpsrNZCV, T::Void, T::U32 )
|
||||
OPCODE(SetCpsrNZCVQ, T::Void, T::U32 )
|
||||
OPCODE(GetNFlag, T::U1, )
|
||||
OPCODE(SetNFlag, T::Void, T::U1 )
|
||||
OPCODE(GetZFlag, T::U1, )
|
||||
OPCODE(SetZFlag, T::Void, T::U1 )
|
||||
OPCODE(GetCFlag, T::U1, )
|
||||
OPCODE(SetCFlag, T::Void, T::U1 )
|
||||
OPCODE(GetVFlag, T::U1, )
|
||||
OPCODE(SetVFlag, T::Void, T::U1 )
|
||||
OPCODE(OrQFlag, T::Void, T::U1 )
|
||||
OPCODE(GetGEFlags, T::U32, )
|
||||
OPCODE(SetGEFlags, T::Void, T::U32 )
|
||||
OPCODE(SetGEFlagsCompressed, T::Void, T::U32 )
|
||||
OPCODE(BXWritePC, T::Void, T::U32 )
|
||||
OPCODE(CallSupervisor, T::Void, T::U32 )
|
||||
OPCODE(GetFpscr, T::U32, )
|
||||
OPCODE(SetFpscr, T::Void, T::U32, )
|
||||
OPCODE(GetFpscrNZCV, T::U32, )
|
||||
OPCODE(SetFpscrNZCV, T::Void, T::U32, )
|
||||
// A32 Context getters/setters
|
||||
A32OPC(GetRegister, T::U32, T::RegRef )
|
||||
A32OPC(GetExtendedRegister32, T::F32, T::ExtRegRef )
|
||||
A32OPC(GetExtendedRegister64, T::F64, T::ExtRegRef )
|
||||
A32OPC(SetRegister, T::Void, T::RegRef, T::U32 )
|
||||
A32OPC(SetExtendedRegister32, T::Void, T::ExtRegRef, T::F32 )
|
||||
A32OPC(SetExtendedRegister64, T::Void, T::ExtRegRef, T::F64 )
|
||||
A32OPC(GetCpsr, T::U32, )
|
||||
A32OPC(SetCpsr, T::Void, T::U32 )
|
||||
A32OPC(SetCpsrNZCV, T::Void, T::U32 )
|
||||
A32OPC(SetCpsrNZCVQ, T::Void, T::U32 )
|
||||
A32OPC(GetNFlag, T::U1, )
|
||||
A32OPC(SetNFlag, T::Void, T::U1 )
|
||||
A32OPC(GetZFlag, T::U1, )
|
||||
A32OPC(SetZFlag, T::Void, T::U1 )
|
||||
A32OPC(GetCFlag, T::U1, )
|
||||
A32OPC(SetCFlag, T::Void, T::U1 )
|
||||
A32OPC(GetVFlag, T::U1, )
|
||||
A32OPC(SetVFlag, T::Void, T::U1 )
|
||||
A32OPC(OrQFlag, T::Void, T::U1 )
|
||||
A32OPC(GetGEFlags, T::U32, )
|
||||
A32OPC(SetGEFlags, T::Void, T::U32 )
|
||||
A32OPC(SetGEFlagsCompressed, T::Void, T::U32 )
|
||||
A32OPC(BXWritePC, T::Void, T::U32 )
|
||||
A32OPC(CallSupervisor, T::Void, T::U32 )
|
||||
A32OPC(GetFpscr, T::U32, )
|
||||
A32OPC(SetFpscr, T::Void, T::U32, )
|
||||
A32OPC(GetFpscrNZCV, T::U32, )
|
||||
A32OPC(SetFpscrNZCV, T::Void, T::U32, )
|
||||
|
||||
// Hints
|
||||
OPCODE(PushRSB, T::Void, T::U64 )
|
||||
@@ -155,26 +155,26 @@ OPCODE(FPU32ToDouble, T::F64, T::F32, T::U1
|
||||
OPCODE(FPS32ToDouble, T::F64, T::F32, T::U1 )
|
||||
|
||||
// Memory access
|
||||
OPCODE(ClearExclusive, T::Void, )
|
||||
OPCODE(SetExclusive, T::Void, T::U32, T::U8 )
|
||||
OPCODE(ReadMemory8, T::U8, T::U32 )
|
||||
OPCODE(ReadMemory16, T::U16, T::U32 )
|
||||
OPCODE(ReadMemory32, T::U32, T::U32 )
|
||||
OPCODE(ReadMemory64, T::U64, T::U32 )
|
||||
OPCODE(WriteMemory8, T::Void, T::U32, T::U8 )
|
||||
OPCODE(WriteMemory16, T::Void, T::U32, T::U16 )
|
||||
OPCODE(WriteMemory32, T::Void, T::U32, T::U32 )
|
||||
OPCODE(WriteMemory64, T::Void, T::U32, T::U64 )
|
||||
OPCODE(ExclusiveWriteMemory8, T::U32, T::U32, T::U8 )
|
||||
OPCODE(ExclusiveWriteMemory16, T::U32, T::U32, T::U16 )
|
||||
OPCODE(ExclusiveWriteMemory32, T::U32, T::U32, T::U32 )
|
||||
OPCODE(ExclusiveWriteMemory64, T::U32, T::U32, T::U32, T::U32 )
|
||||
A32OPC(ClearExclusive, T::Void, )
|
||||
A32OPC(SetExclusive, T::Void, T::U32, T::U8 )
|
||||
A32OPC(ReadMemory8, T::U8, T::U32 )
|
||||
A32OPC(ReadMemory16, T::U16, T::U32 )
|
||||
A32OPC(ReadMemory32, T::U32, T::U32 )
|
||||
A32OPC(ReadMemory64, T::U64, T::U32 )
|
||||
A32OPC(WriteMemory8, T::Void, T::U32, T::U8 )
|
||||
A32OPC(WriteMemory16, T::Void, T::U32, T::U16 )
|
||||
A32OPC(WriteMemory32, T::Void, T::U32, T::U32 )
|
||||
A32OPC(WriteMemory64, T::Void, T::U32, T::U64 )
|
||||
A32OPC(ExclusiveWriteMemory8, T::U32, T::U32, T::U8 )
|
||||
A32OPC(ExclusiveWriteMemory16, T::U32, T::U32, T::U16 )
|
||||
A32OPC(ExclusiveWriteMemory32, T::U32, T::U32, T::U32 )
|
||||
A32OPC(ExclusiveWriteMemory64, T::U32, T::U32, T::U32, T::U32 )
|
||||
|
||||
// Coprocessor
|
||||
OPCODE(CoprocInternalOperation, T::Void, T::CoprocInfo )
|
||||
OPCODE(CoprocSendOneWord, T::Void, T::CoprocInfo, T::U32 )
|
||||
OPCODE(CoprocSendTwoWords, T::Void, T::CoprocInfo, T::U32, T::U32 )
|
||||
OPCODE(CoprocGetOneWord, T::U32, T::CoprocInfo )
|
||||
OPCODE(CoprocGetTwoWords, T::U64, T::CoprocInfo )
|
||||
OPCODE(CoprocLoadWords, T::Void, T::CoprocInfo, T::U32 )
|
||||
OPCODE(CoprocStoreWords, T::Void, T::CoprocInfo, T::U32 )
|
||||
A32OPC(CoprocInternalOperation, T::Void, T::CoprocInfo )
|
||||
A32OPC(CoprocSendOneWord, T::Void, T::CoprocInfo, T::U32 )
|
||||
A32OPC(CoprocSendTwoWords, T::Void, T::CoprocInfo, T::U32, T::U32 )
|
||||
A32OPC(CoprocGetOneWord, T::U32, T::CoprocInfo )
|
||||
A32OPC(CoprocGetTwoWords, T::U64, T::CoprocInfo )
|
||||
A32OPC(CoprocLoadWords, T::Void, T::CoprocInfo, T::U32 )
|
||||
A32OPC(CoprocStoreWords, T::Void, T::CoprocInfo, T::U32 )
|
||||
|
||||
Reference in New Issue
Block a user