You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nudt-compiler-cpp/include/mir/MIR.h

304 lines
9.2 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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, W8, W9, X29, X30, SP
// 32位通用寄存器
W0, W1, W2, W3, W4, W5, W6, W7, // 参数传递/临时
W8, W9, // 临时寄存器(当前主要使用)
W10, W11, W12, W13, W14, W15, // 临时寄存器(扩展)
W16, W17, // intra-procedure-call 临时
W18, // 平台预留
W19, W20, W21, W22, W23, W24, // 被调用者保存(扩展用)
W25, W26, W27, W28, // 被调用者保存
W29, // 帧指针 (FP)
W30, // 链接寄存器 (LR)
// 64位版本
X0, X1, X2, X3, X4, X5, X6, X7,
X8, X9, X10, X11, X12, X13, X14, X15,
X16, X17, X18,
X19, X20, X21, X22, X23, X24, X25, X26, X27, X28,
X29, // FP
X30, // LR
// 浮点寄存器 (32位)
S0, S1, S2, S3, S4, S5, S6, S7,
S8, S9, S10, S11, S12, S13, S14, S15,
S16, S17, S18, S19, S20, S21, S22, S23,
S24, S25, S26, S27, S28, S29, S30, S31,
// 特殊寄存器
SP, // 栈指针
ZR, // 零寄存器
};
const char* PhysRegName(PhysReg reg);
// ========== 条件码枚举(用于 BCond 指令)==========
enum class CondCode {
EQ, // 相等 (equal)
NE, // 不等 (not equal)
CS, // 进位设置 (carry set) / 无符号大于等于
CC, // 进位清除 (carry clear) / 无符号小于
MI, // 负数 (minus)
PL, // 非负数 (plus)
VS, // 溢出 (overflow set)
VC, // 无溢出 (overflow clear)
HI, // 无符号大于 (higher)
LS, // 无符号小于等于 (lower or same)
GE, // 有符号大于等于 (greater or equal)
LT, // 有符号小于 (less than)
GT, // 有符号大于 (greater than)
LE, // 有符号小于等于 (less or equal)
AL, // 总是 (always)
};
const char* CondCodeName(CondCode cc);
// ========== MIR 指令操作码枚举 ==========
enum class Opcode {
// ---------- 栈帧相关 ----------
Prologue, // 函数序言(伪指令)
Epilogue, // 函数尾声(伪指令)
// ---------- 数据传输 ----------
MovImm, // 立即数移动到寄存器: MOV w8, #imm
MovReg, // 寄存器之间移动: MOV w8, w9
LoadStack, // 从栈槽加载: LDR w8, [sp, #offset]
StoreStack, // 存储到栈槽: STR w8, [sp, #offset]
LoadStackPair,// 成对加载: LDP x29, x30, [sp], #16
StoreStackPair,// 成对存储: STP x29, x30, [sp, #-16]!
// ---------- 整数算术运算 ----------
AddRR, // 加法: ADD w8, w8, w9
AddRI, // 加法(立即数): ADD w8, w8, #imm
SubRR, // 减法: SUB w8, w8, w9
SubRI, // 减法(立即数): SUB w8, w8, #imm
MulRR, // 乘法: MUL w8, w8, w9
SDivRR, // 有符号除法: SDIV w8, w8, w9
UDivRR, // 无符号除法: UDIV w8, w8, w9
// ---------- 浮点算术运算 ----------
FAddRR, // 浮点加法: FADD s0, s0, s1
FSubRR, // 浮点减法: FSUB s0, s0, s1
FMulRR, // 浮点乘法: FMUL s0, s0, s1
FDivRR, // 浮点除法: FDIV s0, s0, s1
// ---------- 比较运算 ----------
CmpRR, // 比较(寄存器): CMP w8, w9
CmpRI, // 比较(立即数): CMP w8, #imm
FCmpRR, // 浮点比较: FCMP s0, s1
// ---------- 类型转换 ----------
SIToFP, // 有符号整数转浮点: SCVTF s0, w0
FPToSI, // 浮点转有符号整数: FCVTZS w0, s0
ZExt, // 零扩展i1 -> i32: AND w8, w8, #1
// ---------- 控制流 ----------
B, // 无条件跳转: B label
BCond, // 条件跳转: B.EQ label, B.NE label, B.GT label 等
Call, // 函数调用: BL target
Ret, // 函数返回: RET
// ---------- 逻辑运算 ----------
AndRR, // 按位与: AND w8, w8, w9
OrRR, // 按位或: ORR w8, w8, w9
EorRR, // 按位异或: EOR w8, w8, w9
LslRR, // 逻辑左移: LSL w8, w8, w9
LsrRR, // 逻辑右移: LSR w8, w8, w9
AsrRR, // 算术右移: ASR w8, w8, w9
// ---------- 特殊 ----------
Nop, // 空操作: NOP
Label, // 内联标签,不生成实际指令,仅输出标签名
// 添加
Movk, // movk Rd, #imm16, lsl #shift
};
// ========== 操作数类 ==========
class Operand {
public:
enum class Kind { Reg, Imm, FrameIndex, Cond, Label };
static Operand Reg(PhysReg reg);
static Operand Imm(int value);
static Operand FrameIndex(int index);
static Operand Cond(CondCode cc);
static Operand Label(const std::string& label);
Kind GetKind() const { return kind_; }
PhysReg GetReg() const { return reg_; }
int GetImm() const { return imm_; }
int GetFrameIndex() const { return imm_; }
CondCode GetCondCode() const { return cc_; }
const std::string& GetLabel() const { return label_; }
private:
Operand(Kind kind, PhysReg reg, int imm, CondCode cc, const std::string& label);
Kind kind_;
PhysReg reg_;
int imm_;
CondCode cc_;
std::string label_;
};
// ========== MIR 指令类 ==========
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;
};
// ========== MIR 基本块 ==========
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 = {});
MachineInstr& Append(Opcode opcode, std::vector<Operand> operands);
// 控制流信息
std::vector<MachineBasicBlock*>& GetSuccessors() { return successors_; }
const std::vector<MachineBasicBlock*>& GetSuccessors() const { return successors_; }
void AddSuccessor(MachineBasicBlock* succ) { successors_.push_back(succ); }
private:
std::string name_;
std::vector<MachineInstr> instructions_;
std::vector<MachineBasicBlock*> successors_;
};
// ========== MIR 函数 ==========
class MachineFunction {
public:
explicit MachineFunction(std::string name);
const std::string& GetName() const { return name_; }
// 基本块管理
MachineBasicBlock& GetEntry() { return entry_; }
const MachineBasicBlock& GetEntry() const { return entry_; }
std::vector<std::unique_ptr<MachineBasicBlock>>& GetBasicBlocks() {
return basic_blocks_;
}
const std::vector<std::unique_ptr<MachineBasicBlock>>& GetBasicBlocks() const {
return basic_blocks_;
}
void AddBasicBlock(std::unique_ptr<MachineBasicBlock> bb) {
basic_blocks_.push_back(std::move(bb));
}
// 栈槽管理
int CreateFrameIndex(int size = 4);
FrameSlot& GetFrameSlot(int index);
const FrameSlot& GetFrameSlot(int index) const;
std::vector<FrameSlot>& GetFrameSlots() { return frame_slots_; }
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_;
MachineBasicBlock entry_;
std::vector<std::unique_ptr<MachineBasicBlock>> basic_blocks_;
std::vector<FrameSlot> frame_slots_;
int frame_size_ = 0;
};
// ========== MIR 模块 ==========
class MachineModule {
public:
MachineModule() = default;
// 添加 MachineFunction
void AddFunction(std::unique_ptr<MachineFunction> func) {
functions_.push_back(std::move(func));
}
// 获取所有函数
const std::vector<std::unique_ptr<MachineFunction>>& GetFunctions() const {
return functions_;
}
std::vector<std::unique_ptr<MachineFunction>>& GetFunctions() {
return functions_;
}
// 根据名称查找函数
MachineFunction* GetFunction(const std::string& name) {
for (auto& func : functions_) {
if (func->GetName() == name) {
return func.get();
}
}
return nullptr;
}
const MachineFunction* GetFunction(const std::string& name) const {
for (const auto& func : functions_) {
if (func->GetName() == name) {
return func.get();
}
}
return nullptr;
}
private:
std::vector<std::unique_ptr<MachineFunction>> functions_;
};
// ========== 后端流程函数 ==========
/* std::unique_ptr<MachineFunction> LowerToMIR(const ir::Module& module);
void RunRegAlloc(MachineFunction& function);
void RunFrameLowering(MachineFunction& function);
void PrintAsm(const MachineFunction& function, std::ostream& os); */
std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module);
void RunRegAlloc(MachineModule& module);
void RunFrameLowering(MachineModule& module);
void PrintAsm(const MachineModule& module, std::ostream& os);
} // namespace mir