TranslateArm: Implement CLREX, LDREX, LDREXB, LDREXD, LDREXH, STREX, STREXB, STREXD, STREXH, SWP, SWPB

This commit is contained in:
MerryMage 2016-08-09 22:48:20 +01:00
parent d921390928
commit df39308e03
12 changed files with 446 additions and 98 deletions

View file

@ -362,6 +362,15 @@ IR::Value IREmitter::FPSub64(const IR::Value& a, const IR::Value& b, bool fpscr_
return Inst(IR::Opcode::FPSub64, {a, b});
}
void IREmitter::ClearExlcusive() {
Inst(IR::Opcode::ClearExclusive, {});
}
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(IR::Opcode::SetExclusive, {vaddr, Imm8(u8(byte_size))});
}
IR::Value IREmitter::ReadMemory8(const IR::Value& vaddr) {
return Inst(IR::Opcode::ReadMemory8, {vaddr});
}
@ -412,6 +421,38 @@ void IREmitter::WriteMemory64(const IR::Value& vaddr, const IR::Value& value) {
}
}
IR::Value IREmitter::ExclusiveWriteMemory8(const IR::Value& vaddr, const IR::Value& value) {
return Inst(IR::Opcode::ExclusiveWriteMemory8, {vaddr, value});
}
IR::Value IREmitter::ExclusiveWriteMemory16(const IR::Value& vaddr, const IR::Value& value) {
if (current_location.EFlag()) {
auto v = ByteReverseHalf(value);
return Inst(IR::Opcode::ExclusiveWriteMemory16, {vaddr, v});
} else {
return Inst(IR::Opcode::ExclusiveWriteMemory16, {vaddr, value});
}
}
IR::Value IREmitter::ExclusiveWriteMemory32(const IR::Value& vaddr, const IR::Value& value) {
if (current_location.EFlag()) {
auto v = ByteReverseWord(value);
return Inst(IR::Opcode::ExclusiveWriteMemory32, {vaddr, v});
} else {
return Inst(IR::Opcode::ExclusiveWriteMemory32, {vaddr, value});
}
}
IR::Value IREmitter::ExclusiveWriteMemory64(const IR::Value& vaddr, const IR::Value& value_lo, const IR::Value& value_hi) {
if (current_location.EFlag()) {
auto vlo = ByteReverseWord(value_lo);
auto vhi = ByteReverseWord(value_hi);
return Inst(IR::Opcode::ExclusiveWriteMemory64, {vaddr, vlo, vhi});
} else {
return Inst(IR::Opcode::ExclusiveWriteMemory64, {vaddr, value_lo, value_hi});
}
}
void IREmitter::Breakpoint() {
Inst(IR::Opcode::Breakpoint, {});
}