A64: Implement branch (register)

This commit is contained in:
MerryMage 2018-01-07 13:56:32 +00:00
parent 86d1095df7
commit 23f3afe0b3
8 changed files with 54 additions and 8 deletions

View file

@ -198,6 +198,20 @@ void A64EmitX64::EmitA64SetSP(A64EmitContext& ctx, IR::Inst* inst) {
} }
} }
void A64EmitX64::EmitA64SetPC(A64EmitContext& ctx, IR::Inst* inst) {
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
auto addr = qword[r15 + offsetof(A64JitState, pc)];
if (args[0].FitsInImmediateU32()) {
code->mov(addr, args[0].GetImmediateU32());
} else if (args[0].IsInXmm()) {
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
code->movq(addr, to_store);
} else {
Xbyak::Reg64 to_store = ctx.reg_alloc.UseGpr(args[0]);
code->mov(addr, to_store);
}
}
void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) { void A64EmitX64::EmitTerminalImpl(IR::Term::Interpret terminal, IR::LocationDescriptor) {
code->mov(code->ABI_PARAM1, A64::LocationDescriptor{terminal.next}.PC()); code->mov(code->ABI_PARAM1, A64::LocationDescriptor{terminal.next}.PC());
code->mov(code->ABI_PARAM2.cvt32(), 1); code->mov(code->ABI_PARAM2.cvt32(), 1);

View file

@ -53,6 +53,7 @@ public:
SCOPE_EXIT({ this->is_executing = false; }); SCOPE_EXIT({ this->is_executing = false; });
jit_state.halt_requested = false; jit_state.halt_requested = false;
// TODO: Check code alignment
block_of_code.RunCode(&jit_state); block_of_code.RunCode(&jit_state);
PerformRequestedCacheInvalidation(); PerformRequestedCacheInvalidation();

View file

@ -102,15 +102,15 @@ std::vector<Matcher<V>> GetDecodeTable() {
//INST(&V::MRS, "MRS", "110101010011poooNNNNMMMMooottttt"), //INST(&V::MRS, "MRS", "110101010011poooNNNNMMMMooottttt"),
// Unconditonal branch (Register) // Unconditonal branch (Register)
//INST(&V::BR, "BR", "1101011000011111000000nnnnn00000"), INST(&V::BLR, "BLR", "1101011000111111000000nnnnn00000"),
//INST(&V::BRA, "BRAA, BRAAZ, BRAB, BRABZ", "1101011Z0001111100001Mnnnnnmmmmm"), INST(&V::BR, "BR", "1101011000011111000000nnnnn00000"),
//INST(&V::BLR, "BLR", "1101011000111111000000nnnnn00000"),
//INST(&V::BLRA, "BLRAA, BLRAAZ, BLRAB, BLRABZ", "1101011Z0011111100001Mnnnnnmmmmm"),
//INST(&V::RET, "RET", "1101011001011111000000nnnnn00000"),
//INST(&V::RETA, "RETAA, RETAB", "110101100101111100001M1111111111"),
//INST(&V::ERET, "ERET", "11010110100111110000001111100000"),
//INST(&V::ERETA, "ERETAA, ERETAB", "110101101001111100001M1111111111"),
//INST(&V::DRPS, "DRPS", "11010110101111110000001111100000"), //INST(&V::DRPS, "DRPS", "11010110101111110000001111100000"),
//INST(&V::ERET, "ERET", "11010110100111110000001111100000"),
INST(&V::RET, "RET", "1101011001011111000000nnnnn00000"),
//INST(&V::BLRA, "BLRAA, BLRAAZ, BLRAB, BLRABZ", "1101011Z0011111100001Mnnnnnmmmmm"), // ARMv8.3
//INST(&V::BRA, "BRAA, BRAAZ, BRAB, BRABZ", "1101011Z0001111100001Mnnnnnmmmmm"), // ARMv8.3
//INST(&V::ERETA, "ERETAA, ERETAB", "110101101001111100001M1111111111"), // ARMv8.3
//INST(&V::RETA, "RETAA, RETAB", "110101100101111100001M1111111111"), // ARMv8.3
// Unconditonal branch (immediate) // Unconditonal branch (immediate)
INST(&V::B_uncond, "B", "000101iiiiiiiiiiiiiiiiiiiiiiiiii"), INST(&V::B_uncond, "B", "000101iiiiiiiiiiiiiiiiiiiiiiiiii"),

View file

@ -62,5 +62,9 @@ void IREmitter::SetSP(const IR::U64& value) {
Inst(Opcode::A64SetSP, value); Inst(Opcode::A64SetSP, value);
} }
void IREmitter::SetPC(const IR::U64& value) {
Inst(Opcode::A64SetPC, value);
}
} // namespace IR } // namespace IR
} // namespace Dynarmic } // namespace Dynarmic

View file

@ -40,6 +40,7 @@ public:
void SetW(Reg dest_reg, const IR::U32& value); void SetW(Reg dest_reg, const IR::U32& value);
void SetX(Reg dest_reg, const IR::U64& value); void SetX(Reg dest_reg, const IR::U64& value);
void SetSP(const IR::U64& value); void SetSP(const IR::U64& value);
void SetPC(const IR::U64& value);
}; };
} // namespace IR } // namespace IR

View file

@ -38,5 +38,29 @@ bool TranslatorVisitor::BL(Imm<26> imm26) {
return false; return false;
} }
bool TranslatorVisitor::BLR(Reg Rn) {
X(64, Reg::R30, ir.Imm64(ir.PC() + 4));
ir.PushRSB(ir.current_location.AdvancePC(4));
auto target = X(64, Rn);
ir.SetPC(target);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
bool TranslatorVisitor::BR(Reg Rn) {
auto target = X(64, Rn);
ir.SetPC(target);
ir.SetTerm(IR::Term::ReturnToDispatch{});
return false;
}
bool TranslatorVisitor::RET(Reg Rn) {
auto target = X(64, Rn);
ir.SetPC(target);
ir.SetTerm(IR::Term::PopRSBHint{});
return false;
}
} // namespace A64 } // namespace A64
} // namespace Dynarmic } // namespace Dynarmic

View file

@ -155,6 +155,7 @@ bool Inst::WritesToCoreRegister() const {
case Opcode::A64SetW: case Opcode::A64SetW:
case Opcode::A64SetX: case Opcode::A64SetX:
case Opcode::A64SetSP: case Opcode::A64SetSP:
case Opcode::A64SetPC:
return true; return true;
default: default:

View file

@ -43,6 +43,7 @@ A64OPC(GetSP, T::U64,
A64OPC(SetW, T::Void, T::A64Reg, T::U32 ) A64OPC(SetW, T::Void, T::A64Reg, T::U32 )
A64OPC(SetX, T::Void, T::A64Reg, T::U64 ) A64OPC(SetX, T::Void, T::A64Reg, T::U64 )
A64OPC(SetSP, T::Void, T::U64 ) A64OPC(SetSP, T::Void, T::U64 )
A64OPC(SetPC, T::Void, T::U64 )
// Hints // Hints
OPCODE(PushRSB, T::Void, T::U64 ) OPCODE(PushRSB, T::Void, T::U64 )