A64: Implement pcrel
This commit is contained in:
parent
c09e69bb97
commit
5a1d88c5dc
6 changed files with 43 additions and 6 deletions
|
@ -59,6 +59,7 @@ add_library(dynarmic
|
||||||
frontend/A64/location_descriptor.cpp
|
frontend/A64/location_descriptor.cpp
|
||||||
frontend/A64/location_descriptor.h
|
frontend/A64/location_descriptor.h
|
||||||
frontend/A64/translate/impl/data_processing_addsub.cpp
|
frontend/A64/translate/impl/data_processing_addsub.cpp
|
||||||
|
frontend/A64/translate/impl/data_processing_pcrel.cpp
|
||||||
frontend/A64/translate/impl/impl.cpp
|
frontend/A64/translate/impl/impl.cpp
|
||||||
frontend/A64/translate/impl/impl.h
|
frontend/A64/translate/impl/impl.h
|
||||||
frontend/A64/translate/translate.cpp
|
frontend/A64/translate/translate.cpp
|
||||||
|
|
|
@ -173,8 +173,8 @@ void A64EmitX64::EmitA64SetX(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
A64::Reg reg = inst->GetArg(0).GetA64RegRef();
|
A64::Reg reg = inst->GetArg(0).GetA64RegRef();
|
||||||
auto addr = qword[r15 + offsetof(A64JitState, reg) + sizeof(u64) * static_cast<size_t>(reg)];
|
auto addr = qword[r15 + offsetof(A64JitState, reg) + sizeof(u64) * static_cast<size_t>(reg)];
|
||||||
if (args[1].IsImmediate()) {
|
if (args[1].FitsInImmediateU32()) {
|
||||||
code->mov(addr, args[1].GetImmediateU64());
|
code->mov(addr, args[1].GetImmediateU32());
|
||||||
} else if (args[1].IsInXmm()) {
|
} else if (args[1].IsInXmm()) {
|
||||||
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
|
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[1]);
|
||||||
code->movq(addr, to_store);
|
code->movq(addr, to_store);
|
||||||
|
@ -187,8 +187,8 @@ void A64EmitX64::EmitA64SetX(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
void A64EmitX64::EmitA64SetSP(A64EmitContext& ctx, IR::Inst* inst) {
|
void A64EmitX64::EmitA64SetSP(A64EmitContext& ctx, IR::Inst* inst) {
|
||||||
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
auto addr = qword[r15 + offsetof(A64JitState, sp)];
|
auto addr = qword[r15 + offsetof(A64JitState, sp)];
|
||||||
if (args[0].IsImmediate()) {
|
if (args[0].FitsInImmediateU32()) {
|
||||||
code->mov(addr, args[0].GetImmediateU64());
|
code->mov(addr, args[0].GetImmediateU32());
|
||||||
} else if (args[0].IsInXmm()) {
|
} else if (args[0].IsInXmm()) {
|
||||||
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
|
Xbyak::Xmm to_store = ctx.reg_alloc.UseXmm(args[0]);
|
||||||
code->movq(addr, to_store);
|
code->movq(addr, to_store);
|
||||||
|
|
|
@ -100,6 +100,13 @@ bool Argument::IsImmediate() const {
|
||||||
return value.IsImmediate();
|
return value.IsImmediate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Argument::FitsInImmediateU32() const {
|
||||||
|
if (!IsImmediate())
|
||||||
|
return false;
|
||||||
|
u64 imm = ImmediateToU64(value);
|
||||||
|
return imm < 0x100000000;
|
||||||
|
}
|
||||||
|
|
||||||
bool Argument::GetImmediateU1() const {
|
bool Argument::GetImmediateU1() const {
|
||||||
return value.GetU1();
|
return value.GetU1();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,6 +56,8 @@ public:
|
||||||
IR::Type GetType() const;
|
IR::Type GetType() const;
|
||||||
bool IsImmediate() const;
|
bool IsImmediate() const;
|
||||||
|
|
||||||
|
bool FitsInImmediateU32() const;
|
||||||
|
|
||||||
bool GetImmediateU1() const;
|
bool GetImmediateU1() const;
|
||||||
u8 GetImmediateU8() const;
|
u8 GetImmediateU8() const;
|
||||||
u16 GetImmediateU16() const;
|
u16 GetImmediateU16() const;
|
||||||
|
|
|
@ -30,8 +30,8 @@ std::vector<Matcher<V>> GetDecodeTable() {
|
||||||
#define INST(fn, name, bitstring) Decoder::detail::detail<Matcher<V>>::GetMatcher(fn, name, bitstring)
|
#define INST(fn, name, bitstring) Decoder::detail::detail<Matcher<V>>::GetMatcher(fn, name, bitstring)
|
||||||
|
|
||||||
// Data processing - Immediate - PC relative addressing
|
// Data processing - Immediate - PC relative addressing
|
||||||
//INST(&V::ADR, "ADR", "0ii10000iiiiiiiiiiiiiiiiiiiddddd"),
|
INST(&V::ADR, "ADR", "0ii10000iiiiiiiiiiiiiiiiiiiddddd"),
|
||||||
//INST(&V::ADRP, "ADRP", "1ii10000iiiiiiiiiiiiiiiiiiiddddd"),
|
INST(&V::ADRP, "ADRP", "1ii10000iiiiiiiiiiiiiiiiiiiddddd"),
|
||||||
|
|
||||||
// Data processing - Immediate - Add/Sub
|
// Data processing - Immediate - Add/Sub
|
||||||
INST(&V::ADD_imm, "ADD (immediate)", "z0010001ssiiiiiiiiiiiinnnnnddddd"),
|
INST(&V::ADD_imm, "ADD (immediate)", "z0010001ssiiiiiiiiiiiinnnnnddddd"),
|
||||||
|
|
27
src/frontend/A64/translate/impl/data_processing_pcrel.cpp
Normal file
27
src/frontend/A64/translate/impl/data_processing_pcrel.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
/* This file is part of the dynarmic project.
|
||||||
|
* Copyright (c) 2018 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 "frontend/A64/translate/impl/impl.h"
|
||||||
|
|
||||||
|
namespace Dynarmic {
|
||||||
|
namespace A64 {
|
||||||
|
|
||||||
|
bool TranslatorVisitor::ADR(Imm<2> immlo, Imm<19> immhi, Reg Rd) {
|
||||||
|
u64 imm = concatenate(immhi, immlo).ZeroExtend<u64>();
|
||||||
|
u64 base = ir.PC();
|
||||||
|
X(64, Rd, ir.Imm64(base + imm));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::ADRP(Imm<2> immlo, Imm<19> immhi, Reg Rd) {
|
||||||
|
u64 imm = concatenate(immhi, immlo).ZeroExtend<u64>() << 12;
|
||||||
|
u64 base = ir.PC() & ~u64(0xFFF);
|
||||||
|
X(64, Rd, ir.Imm64(base + imm));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace A64
|
||||||
|
} // namespace Dynarmic
|
Loading…
Reference in a new issue