汇编生成

mirror 1 week ago
parent 6ab99eb7bd
commit 46dad22baa

@ -0,0 +1,194 @@
#pragma once
#include <initializer_list>
#include <iosfwd>
#include <memory>
#include <string>
#include <vector>
namespace ir {
class Module;
}
namespace mir {
class MIRContext {
public:
MIRContext() = default;
};
MIRContext& DefaultContext();
enum class PhysReg {
W0, W1, W2, W3, W4, W5, W6, W7,
W8, W9, W10, W11,
X0, X1, X2, X3, X4, X5, X6, X7,
X8, X9, X10, X11, X29, X30, SP,
S0, S1, S2, S3, S4, S5, S6, S7, // 单精度浮点寄存器
S8, S9, S10
};
const char* PhysRegName(PhysReg reg);
enum class Opcode {
Prologue,
Epilogue,
MovImm,
MovReg,
FMovImm, // 浮点立即数加载
FMovReg, // 浮点寄存器移动
LoadStack,
StoreStack,
LoadStackOffset, // 加载数组元素ldr w8, [x29, base_offset + element_offset]
StoreStackOffset, // 存储数组元素str w8, [x29, base_offset + element_offset]
LoadStackAddr, // 加载栈地址add x9, x29, #offset用于数组基址
LoadIndirect, // 间接加载ldr w8, [x9]
StoreIndirect, // 间接存储str w8, [x9]
LoadGlobal,
StoreGlobal,
LoadGlobalAddr, // 加载全局变量地址(用于数组)
AddRI,
SubRI,
AddRR,
SubRR,
MulRR,
DivRR,
ModRR,
LsrRI,
LslRI,
LslRR, // 逻辑左移(用于 index * 4
FAddRR, // 浮点加法
FSubRR, // 浮点减法
FMulRR, // 浮点乘法
FDivRR, // 浮点除法
FSqrtRR, // 浮点平方根
SIToFP, // 有符号整型转浮点
FPToSI, // 浮点转有符号整型
CmpOnlyRR,
FCmpOnlyRR,
CmpRR,
FCmpRR, // 浮点比较
Bl,
B, // 无条件跳转
Bcond, // 条件跳转(基于之前的 cmp
FBcond, // 浮点条件跳转(基于之前的 fcmp使用 IEEE 754 兼容的条件码)
Cbnz, // 非零跳转
Cbz, // 零跳转
Ret,
};
class Operand {
public:
enum class Kind { Reg, Imm, FrameIndex, Symbol };
static Operand Reg(PhysReg reg);
static Operand Imm(int value);
static Operand FrameIndex(int index);
static Operand Symbol(std::string name);
Kind GetKind() const { return kind_; }
PhysReg GetReg() const { return reg_; }
int GetImm() const { return imm_; }
int GetFrameIndex() const { return imm_; }
const std::string& GetSymbol() const { return symbol_; }
private:
Operand(Kind kind, PhysReg reg, int imm, std::string symbol = "");
Kind kind_;
PhysReg reg_;
int imm_;
std::string symbol_;
};
class MachineInstr {
public:
MachineInstr(Opcode opcode, std::vector<Operand> operands = {});
Opcode GetOpcode() const { return opcode_; }
const std::vector<Operand>& GetOperands() const { return operands_; }
private:
Opcode opcode_;
std::vector<Operand> operands_;
};
struct FrameSlot {
int index = 0;
int size = 4;
int offset = 0;
};
class MachineBasicBlock {
public:
explicit MachineBasicBlock(std::string name);
const std::string& GetName() const { return name_; }
std::vector<MachineInstr>& GetInstructions() { return instructions_; }
const std::vector<MachineInstr>& GetInstructions() const { return instructions_; }
MachineInstr& Append(Opcode opcode,
std::initializer_list<Operand> operands = {});
private:
std::string name_;
std::vector<MachineInstr> instructions_;
};
class MachineFunction {
public:
explicit MachineFunction(std::string name);
const std::string& GetName() const { return name_; }
MachineBasicBlock& GetEntry() { return *blocks_.front(); }
const MachineBasicBlock& GetEntry() const { return *blocks_.front(); }
MachineBasicBlock* CreateBlock(std::string name);
MachineBasicBlock* FindBlock(const std::string& name);
const std::vector<std::unique_ptr<MachineBasicBlock>>& GetBlocks() const {
return blocks_;
}
int CreateFrameIndex(int size = 4);
FrameSlot& GetFrameSlot(int index);
const FrameSlot& GetFrameSlot(int index) const;
const std::vector<FrameSlot>& GetFrameSlots() const { return frame_slots_; }
int GetFrameSize() const { return frame_size_; }
void SetFrameSize(int size) { frame_size_ = size; }
private:
std::string name_;
std::vector<std::unique_ptr<MachineBasicBlock>> blocks_;
std::vector<FrameSlot> frame_slots_;
int frame_size_ = 0;
};
class MachineModule {
public:
MachineModule() = default;
MachineFunction* CreateFunction(std::string name);
const std::vector<std::unique_ptr<MachineFunction>>& GetFunctions() const {
return functions_;
}
void AddGlobalVar(std::string name, int init_val, int count, bool is_float,
std::vector<int> init_elems = {});
const std::vector<std::tuple<std::string, int, int, bool, std::vector<int>>>&
GetGlobalVars() const {
return global_vars_;
}
private:
std::vector<std::unique_ptr<MachineFunction>> functions_;
std::vector<std::tuple<std::string, int, int, bool, std::vector<int>>>
global_vars_; // (name, init, count, is_float, init_elements)
};
std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module);
void RunPeephole(MachineFunction& function);
void RunRegAlloc(MachineFunction& function);
void RunFrameLowering(MachineFunction& function);
void PrintAsm(const MachineModule& module, std::ostream& os);
} // namespace mir

File diff suppressed because it is too large Load Diff

@ -0,0 +1,68 @@
#include "mir/MIR.h"
#include <stdexcept>
#include "utils/Log.h"
namespace mir {
namespace {
bool IsAllowedReg(PhysReg reg) {
switch (reg) {
case PhysReg::W0:
case PhysReg::W1:
case PhysReg::W2:
case PhysReg::W3:
case PhysReg::W4:
case PhysReg::W5:
case PhysReg::W6:
case PhysReg::W7:
case PhysReg::W8:
case PhysReg::W9:
case PhysReg::W10:
case PhysReg::X0:
case PhysReg::X1:
case PhysReg::X2:
case PhysReg::X3:
case PhysReg::X4:
case PhysReg::X5:
case PhysReg::X6:
case PhysReg::X7:
case PhysReg::X8:
case PhysReg::X9:
case PhysReg::X10:
case PhysReg::X29:
case PhysReg::X30:
case PhysReg::SP:
case PhysReg::S0:
case PhysReg::S1:
case PhysReg::S2:
case PhysReg::S3:
case PhysReg::S4:
case PhysReg::S5:
case PhysReg::S6:
case PhysReg::S7:
case PhysReg::S8:
case PhysReg::S9:
case PhysReg::S10:
return true;
}
return false;
}
} // namespace
void RunRegAlloc(MachineFunction& function) {
for (const auto& bb_ptr : function.GetBlocks()) {
for (const auto& inst : bb_ptr->GetInstructions()) {
for (const auto& operand : inst.GetOperands()) {
if (operand.GetKind() == Operand::Kind::Reg &&
!IsAllowedReg(operand.GetReg())) {
throw std::runtime_error(FormatError("mir", "寄存器分配失败"));
}
}
}
}
}
} // namespace mir
Loading…
Cancel
Save