Skip to content

Commit

Permalink
feat: arm frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
ganyao114 committed Jan 30, 2024
1 parent 583334c commit 400163a
Show file tree
Hide file tree
Showing 11 changed files with 272 additions and 27 deletions.
6 changes: 6 additions & 0 deletions source/base/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ using s16 = int16_t;
using s32 = int32_t;
using s64 = int64_t;

#if __LP64__
using VAddr = u64;
#else
using VAddr = u32;
#endif

constexpr inline u64 operator ""_KB(unsigned long long n) {
return static_cast<u64>(n) * UINT64_C(1024);
}
Expand Down
38 changes: 38 additions & 0 deletions source/runtime/backend/arm64/jit/translator.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include "translator.h"
#include "runtime/backend/context.h"

namespace swift::runtime::backend::arm64 {

Expand All @@ -23,6 +24,43 @@ void JitTranslator::Translate(ir::Inst* inst) {
#undef INST
}

void JitTranslator::EmitLoadUniform(ir::Inst* inst) {
auto uni = inst->GetArg<ir::Uniform>(0);
auto uni_offset = uni.GetOffset();
auto uni_type = uni.GetType();

auto uni_buffer_offset = offsetof(State, uniform_buffer_begin);

}

void JitTranslator::EmitStoreUniform(ir::Inst* inst) {

}

void JitTranslator::EmitLoadLocal(ir::Inst* inst) {

}

void JitTranslator::EmitStoreLocal(ir::Inst* inst) {

}

void JitTranslator::EmitLoadMemory(ir::Inst* inst) {

}

void JitTranslator::EmitStoreMemory(ir::Inst* inst) {

}

void JitTranslator::EmitLoadMemoryTSO(ir::Inst* inst) {

}

void JitTranslator::EmitStoreMemoryTSO(ir::Inst* inst) {

}

Operand JitTranslator::EmitOperand(ir::Operand& ir_op) {
context.V(ir_op.GetLeft().value).B();
return Operand();
Expand Down
3 changes: 1 addition & 2 deletions source/runtime/backend/reg_alloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
namespace swift::runtime::backend {

RegAlloc::RegAlloc(u32 instr_size, const GPRSMask& gprs, const FPRSMask& fprs)
: alloc_result{instr_size}, gprs(gprs), fprs(fprs) {}
: alloc_result(instr_size), gprs(gprs), fprs(fprs) {}

void RegAlloc::MapRegister(u32 id, ir::HostFPR fpr) {
auto &map = alloc_result[id];
Expand Down Expand Up @@ -44,7 +44,6 @@ const GPRSMask& RegAlloc::GetGprs() const { return gprs; }
const FPRSMask& RegAlloc::GetFprs() const { return fprs; }

ir::HostGPR RegAlloc::GetTmpGPR() {

return ir::HostGPR{1};
}

Expand Down
3 changes: 2 additions & 1 deletion source/runtime/frontend/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
add_subdirectory(slang)
add_subdirectory(x86)
add_subdirectory(x86)
add_subdirectory(arm64)
149 changes: 149 additions & 0 deletions source/runtime/frontend/arm64/arm64_frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,152 @@
//

#include "arm64_frontend.h"

namespace swift::arm64 {

#define __ assembler->

A64Decoder::A64Decoder(swift::VAddr start, runtime::MemoryInterface* memory, runtime::ir::Assembler* visitor) : assembler(visitor) {}

void A64Decoder::Decode() {

}

void A64Decoder::WriteXRegister(u8 code, ir::Value value, Reg31Mode r31mode) {
switch (value.Type()) {
case ir::ValueType::U64: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U32: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U16: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U8: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::V128: {

break;
}
case ir::ValueType::V64: {

break;
}
default:
VIXL_UNREACHABLE();
}
}

void A64Decoder::WriteWRegister(u8 code, ir::Value value, Reg31Mode r31mode) {
switch (value.Type()) {
case ir::ValueType::U64: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U32: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U16: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::U8: {
if (r31mode == Reg31IsZeroRegister) {

} else {

}
break;
}
case ir::ValueType::V128: {

break;
}
case ir::ValueType::V64: {

break;
}
default:
VIXL_UNREACHABLE();
}
}

void A64Decoder::VisitSystem(const Instruction* instr) { DecoderVisitor::VisitSystem(instr); }

void A64Decoder::VisitMoveWideImmediate(const Instruction* instr) {
auto mov_op = static_cast<MoveWideImmediateOp>(instr->Mask(MoveWideImmediateMask));
ir::Value new_xn_val{};

bool is_64_bits = instr->GetSixtyFourBits() == 1;
// Shift is limited for W operations.
VIXL_ASSERT(is_64_bits || (instr->GetShiftMoveWide() < 2));

// Get the shifted immediate.
s64 shift = instr->GetShiftMoveWide() * 16;
s64 shifted_imm16 = static_cast<s64>(instr->GetImmMoveWide()) << shift;

// Compute the new value.
switch (mov_op) {
case MOVN_w:
case MOVN_x: {
auto new_val = ~shifted_imm16;
if (!is_64_bits) new_val &= kWRegMask;
new_xn_val = __ LoadImm(ir::Imm(ForceCast<u64>(new_val)));
break;
}
case MOVK_w:
case MOVK_x: {
auto reg_code = instr->GetRd();
auto prev_xn_val = is_64_bits ? ReadXRegister(reg_code) : ReadWRegister(reg_code);
new_xn_val = __ BitInsert(prev_xn_val, __ LoadImm(ir::Imm((u16) instr->GetImmMoveWide())), ir::Imm{(u8) shift}, ir::Imm{16u});
break;
}
case MOVZ_w:
case MOVZ_x: {
new_xn_val = __ LoadImm(ir::Imm(ForceCast<u64>(shifted_imm16)));
break;
}
default:
VIXL_UNREACHABLE();
}

// Update the destination register.
WriteXRegister(instr->GetRd(), new_xn_val);
}

}
52 changes: 49 additions & 3 deletions source/runtime/frontend/arm64/arm64_frontend.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,53 @@
// Created by 甘尧 on 2024/1/4.
//

#ifndef SWIFTVM_ARM64_FRONTEND_H
#define SWIFTVM_ARM64_FRONTEND_H
#pragma once

#endif // SWIFTVM_ARM64_FRONTEND_H
#include "runtime/include/config.h"
#include "runtime/frontend/ir_assembler.h"
#include "cpu-features.h"
#include "aarch64/abi-aarch64.h"
#include "aarch64/cpu-features-auditor-aarch64.h"
#include "aarch64/disasm-aarch64.h"
#include "aarch64/instructions-aarch64.h"

namespace swift::arm64 {

using namespace vixl::aarch64;
using namespace runtime;

class A64Decoder : public DecoderVisitor {
public:

A64Decoder(VAddr start, runtime::MemoryInterface *memory, runtime::ir::Assembler* visitor);

void Decode();

void VisitMoveWideImmediate(const Instruction* instr) override;

void VisitSystem(const Instruction* instr) override;

private:

void WriteRegister(u8 code, ir::Value value, Reg31Mode r31mode = Reg31IsZeroRegister);

ir::Value ReadRegister(u8 code, ir::ValueType size, Reg31Mode r31mode = Reg31IsZeroRegister);

ir::Value ReadXRegister(u8 code, Reg31Mode r31mode = Reg31IsZeroRegister) {
return ReadRegister(code, ir::ValueType::U64, r31mode);
}

ir::Value ReadWRegister(u8 code, Reg31Mode r31mode = Reg31IsZeroRegister) {
return ReadRegister(code, ir::ValueType::U32, r31mode);
}

void WritePc(ir::Lambda new_pc);

void WriteXRegister(u8 code, ir::Value value, Reg31Mode r31mode = Reg31IsZeroRegister);

void WriteWRegister(u8 code, ir::Value value, Reg31Mode r31mode = Reg31IsZeroRegister);

ir::Assembler* assembler;
};

}
2 changes: 1 addition & 1 deletion source/runtime/frontend/ir_assembler.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class Assembler {
constexpr static auto MAX_ARG = 3;
auto arg_count = sizeof...(args);
ASSERT(arg_count <= MAX_ARG);
return CallLambda(FptrCast(l), std::forward<const Args&>(args)...);
return CallLambda(Lambda{Imm{reinterpret_cast<VAddr>(FptrCast(l))}}, std::forward<const Args&>(args)...);
}

HIRBuilder::ElseThen If(const terminal::If& if_);
Expand Down
39 changes: 23 additions & 16 deletions source/runtime/frontend/x86/decoder.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,9 @@ ir::Operand ToOperand(ir::Lambda address) {
}
}

ir::Operand ToOperand(ir::Value value) {
return ir::Operand{value};
}
ir::Operand ToOperand(ir::Value value) { return ir::Operand{value}; }

X64Decoder::X64Decoder(VAddr start, runtime::MemoryInterface *memory, ir::Assembler* visitor)
X64Decoder::X64Decoder(VAddr start, runtime::MemoryInterface* memory, ir::Assembler* visitor)
: start(start), assembler(visitor), memory(memory) {}

void X64Decoder::Decode() {
Expand Down Expand Up @@ -308,21 +306,16 @@ void X64Decoder::DecodeCondJump(_DInst& insn, Cond cond) {
}
} else {
auto check_result = CheckCond(cond);
auto label = __ NotGoto(check_result);
__ SetLocation(address);
__ BindLabel(label);
__ If(ir::terminal::If{check_result, ir::terminal::ReturnToDispatch{}, ir::terminal::LinkBlock{pc + insn.size}});
CondGoto(check_result, address, pc + insn.size);
}
}

void X64Decoder::DecodeZeroCheckJump(_DInst& insn, _RegisterType reg) {
auto& op0 = insn.ops[0];
auto value_check = R(reg);
auto address = AddrSrc(insn, op0);
auto label = __ Goto(value_check);
__ SetLocation(address);
__ BindLabel(label);
__ If(ir::terminal::If{value_check, ir::terminal::LinkBlock{pc + insn.size}, ir::terminal::ReturnToDispatch{}});

CondGoto(__ Not(value_check), address, pc + insn.size);
}

void X64Decoder::DecodeAddSubWithCarry(_DInst& insn, bool sub) {
Expand Down Expand Up @@ -383,8 +376,7 @@ void X64Decoder::DecodeCondMov(_DInst& insn, Cond cond) {
__ BindLabel(label);
}

void X64Decoder::DecodeAnd(_DInst& insn) {
}
void X64Decoder::DecodeAnd(_DInst& insn) {}

ir::Value X64Decoder::R(_RegisterType reg) {
assert(reg <= _RegisterType::R_XMM15);
Expand Down Expand Up @@ -487,6 +479,20 @@ ir::BOOL X64Decoder::CheckCond(Cond cond) {
}
}

void X64Decoder::CondGoto(ir::BOOL cond, ir::Lambda then_, ir::Location else_) {
if (then_.IsValue()) {
auto label = __ NotGoto(cond);
__ SetLocation(then_);
__ BindLabel(label);
__ If(ir::terminal::If{
cond, ir::terminal::ReturnToDispatch{}, ir::terminal::LinkBlock{else_}});
} else {
__ If(ir::terminal::If{cond,
ir::terminal::LinkBlock{then_.GetImm().GetValue()},
ir::terminal::LinkBlock{else_}});
}
}

ir::ValueType X64Decoder::GetSize(u32 bits) {
switch (bits) {
case 0:
Expand Down Expand Up @@ -610,7 +616,8 @@ ir::Lambda X64Decoder::GetAddress(_DInst& insn, _Operand& operand) {
value = insn.disp ? __ Add(value_base_index, offset) : value_base_index;
} else {
auto value_rn = R(static_cast<_RegisterType>(operand.index));
auto value_base_index = insn.scale ? __ LslImm(value_rn, ir::Imm(insn.scale)) : value_rn;
auto value_base_index =
insn.scale ? __ LslImm(value_rn, ir::Imm(insn.scale)) : value_rn;
value = insn.disp ? __ Add(value_base_index, offset) : value_base_index;
}
break;
Expand Down Expand Up @@ -642,7 +649,7 @@ ir::Value X64Decoder::Pop(_RegisterType reg, ir::ValueType size) {
} else {
R(reg, value);
}
R(sp, __ Add(R(sp), ir::Imm((u8) size_byte)));
R(sp, __ Add(R(sp), ir::Imm((u8)size_byte)));
return value;
}

Expand Down
Loading

0 comments on commit 400163a

Please sign in to comment.