backend/arm64/abi: Implement ToRegList

This commit is contained in:
Merry 2022-12-10 23:12:04 +00:00
parent c01d27bb7c
commit 8f243089e0
2 changed files with 19 additions and 1 deletions

View file

@ -6,6 +6,8 @@
#pragma once #pragma once
#include <initializer_list> #include <initializer_list>
#include <stdexcept>
#include <type_traits>
#include <mcl/stdint.hpp> #include <mcl/stdint.hpp>
#include <oaknut/oaknut.hpp> #include <oaknut/oaknut.hpp>
@ -48,6 +50,22 @@ constexpr std::initializer_list<int> FPR_ORDER{8, 9, 10, 11, 12, 13, 14, 15, 16,
using RegisterList = u64; using RegisterList = u64;
constexpr RegisterList ToRegList(oaknut::Reg reg) {
if (reg.is_vector()) {
return RegisterList{1} << (reg.index() + 32);
}
if (reg.index() == 31) {
throw std::out_of_range("ZR not allowed in reg list");
}
if (reg.index() == -1) {
return RegisterList{1} << 31;
}
return RegisterList{1} << reg.index();
}
constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'3ff80000; constexpr RegisterList ABI_CALLEE_SAVE = 0x0000ff00'3ff80000;
constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff; constexpr RegisterList ABI_CALLER_SAVE = 0xffffffff'4000ffff;

View file

@ -336,7 +336,7 @@ void InlinePageTableEmitReadMemory(oaknut::CodeGenerator& code, EmitContext& ctx
EmitMemoryLdr<bitsize>(code, Rvalue->index(), Xbase, Xoffset, ordered); EmitMemoryLdr<bitsize>(code, Rvalue->index(), Xbase, Xoffset, ordered);
ctx.deferred_emits.emplace_back([&code, &ctx, inst, Xaddr = *Xaddr, Rvalue = *Rvalue, ordered, fallback, end] { ctx.deferred_emits.emplace_back([&code, &ctx, inst, Xaddr = *Xaddr, Rvalue = *Rvalue, ordered, fallback, end] {
const u64 save_regs = ABI_CALLER_SAVE & ~((bitsize == 128 ? (1ull << 32) : 1ull) << Rvalue.index()); const u64 save_regs = ABI_CALLER_SAVE & ~ToRegList(Rvalue);
code.l(*fallback); code.l(*fallback);
ABI_PushRegisters(code, save_regs, 0); ABI_PushRegisters(code, save_regs, 0);
code.MOV(X1, Xaddr); code.MOV(X1, Xaddr);