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.

120 lines
2.6 KiB

#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 };
const char* PhysRegName(PhysReg reg);
enum class Opcode {
Prologue,
Epilogue,
MovImm,
LoadStack,
StoreStack,
AddRR,
Ret,
};
class Operand {
public:
enum class Kind { Reg, Imm, FrameIndex };
static Operand Reg(PhysReg reg);
static Operand Imm(int value);
static Operand FrameIndex(int index);
Kind kind() const { return kind_; }
PhysReg reg() const { return reg_; }
int imm() const { return imm_; }
int frame_index() const { return imm_; }
private:
Operand(Kind kind, PhysReg reg, int imm);
Kind kind_;
PhysReg reg_;
int imm_;
};
class MachineInstr {
public:
MachineInstr(Opcode opcode, std::vector<Operand> operands = {});
Opcode opcode() const { return opcode_; }
const std::vector<Operand>& operands() 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& name() const { return name_; }
std::vector<MachineInstr>& instructions() { return instructions_; }
const std::vector<MachineInstr>& instructions() 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& name() const { return name_; }
MachineBasicBlock& entry() { return entry_; }
const MachineBasicBlock& entry() const { return entry_; }
int CreateFrameIndex(int size = 4);
FrameSlot& frame_slot(int index);
const FrameSlot& frame_slot(int index) const;
const std::vector<FrameSlot>& frame_slots() const { return frame_slots_; }
int frame_size() const { return frame_size_; }
void set_frame_size(int size) { frame_size_ = size; }
private:
std::string name_;
MachineBasicBlock entry_;
std::vector<FrameSlot> frame_slots_;
int frame_size_ = 0;
};
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);
} // namespace mir