#pragma once #include #include #include #include #include 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 operands = {}); Opcode GetOpcode() const { return opcode_; } const std::vector& GetOperands() const { return operands_; } private: Opcode opcode_; std::vector 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& GetInstructions() { return instructions_; } const std::vector& GetInstructions() const { return instructions_; } MachineInstr& Append(Opcode opcode, std::initializer_list operands = {}); private: std::string name_; std::vector 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>& GetBlocks() const { return blocks_; } int CreateFrameIndex(int size = 4); FrameSlot& GetFrameSlot(int index); const FrameSlot& GetFrameSlot(int index) const; const std::vector& GetFrameSlots() const { return frame_slots_; } int GetFrameSize() const { return frame_size_; } void SetFrameSize(int size) { frame_size_ = size; } private: std::string name_; std::vector> blocks_; std::vector frame_slots_; int frame_size_ = 0; }; class MachineModule { public: MachineModule() = default; MachineFunction* CreateFunction(std::string name); const std::vector>& GetFunctions() const { return functions_; } void AddGlobalVar(std::string name, int init_val, int count, bool is_float, std::vector init_elems = {}); const std::vector>>& GetGlobalVars() const { return global_vars_; } private: std::vector> functions_; std::vector>> global_vars_; // (name, init, count, is_float, init_elements) }; std::unique_ptr 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