diff --git a/src/Backend.cpp b/src/Backend.cpp deleted file mode 100644 index e1435ab..0000000 --- a/src/Backend.cpp +++ /dev/null @@ -1,295 +0,0 @@ -#include "Backend.h" -using namespace sysy; - -namespace sysy { - -using RegId = RegManager::RegId; - -string CodeGen::code_gen() { - string code; - code += module_gen(module); - return code; -} - -string CodeGen::module_gen(Module *module) { - string code; - string dataCode; - string textCode; - // clear last module's label record - clearModuleRecord(module); - // generate asmcode for all global values - dataCode += globaldata_gen(); - - code += space + ".arch armv7ve " + eol; - code += space + ".text " + eol; - auto functions = module->getFunctions(); - - for (auto iter = functions->begin(); iter != functions->end(); ++iter) { - string name = iter->first; - Function *func = iter->second; - auto bblist = func->getBasicBlocks(); - if (bblist.empty()) - continue; - // generate asmcode for each function - textCode += function_gen(func) + eol; - } - code += (dataCode + textCode + eol); - return code; -} - -string CodeGen::functionHead_gen(Function *func) { - string code; - code += space + ".globl " + func->getName() + eol; - code += space + ".p2align " + std::to_string(int_p2align) + eol; - code += space + ".type " + func->getName() + ", %function" + eol; - code += func->getName() + ":" + eol; - return code; -} -/** - * stack structure: - * - * last function stack - * -------------------------- <-- fp point - * callee-saved regs (include fp, sp, lr) - * -------------------------- - * local variables and subfunc's return value (ir inst) - * -------------------------- - * arg0,arg1,arg2,arg3 (as tempory variable) - * -------------------------- - * caller-saved regs - * -------------------------- - * arg_x ~ arg_4 - * -------------------------- <-- sp point - * next function stack - * - */ -/** - * prologue : - * preserve callee-saved registers (lr, fp and other callee-saved regs) - * set new fp - * alloc stack space for local var/ args / return value. - * store args to stack - * */ -string CodeGen::prologueCode_gen(Function *func) { - string code; - /** - *code in here - */ - return code; -} - -/* epilogue : - * free stack space - * restore sp - * restore used callee-saved register(lr, fp and other callee-saved - * regs) bx lr - */ -string CodeGen::epilogueCode_gen(Function *func) { - string code; - /** - *code in here - */ - return code; -} - -string CodeGen::function_gen(Function *func) { - curFunc = func; - clearFunctionRecord(func); - string bbCode; - auto bbs = func->getBasicBlocks(); - for (auto iter = bbs.begin(); iter != bbs.end(); ++iter) { - auto bb = iter->get(); - bbCode += basicBlock_gen(bb); - } - string code; - string funcHead = functionHead_gen(func); - string prologueCode = prologueCode_gen(func); - string epilogueCode = epilogueCode_gen(func); - string literalPoolsCode = literalPoolsCode_gen(func); - // - code = funcHead + prologueCode + bbCode + epilogueCode + literalPoolsCode; - return code; -} - -string CodeGen::basicBlock_gen(BasicBlock *bb) { - curBB = bb; - string bbLabel = getBBLabel(bb); - string code; - code += bbLabel + ":" + eol; - for (auto &instr : bb->getInstructions()) { - auto instrType = instr->getKind(); - code += instruction_gen(instr.get()); - } - return code; -} -/** - * RegId : binaryInst_gen returns RegId as its destination operand - * code : asmcode generated by binaryInst_gen - */ -pair CodeGen::binaryInst_gen(BinaryInst *bInst, RegId dstRegId) { - string code; - /** - *code in here - */ - return {dstRegId, code}; -} - -pair CodeGen::unaryInst_gen(UnaryInst *uInst, RegId dstRegId) { - string code; - /** - *code in here - */ - return {dstRegId, code}; -} -pair CodeGen::allocaInst_gen(AllocaInst *aInst, - RegManager::RegId dstRegId) { - string code; - /** - *code in here - */ - return {dstRegId, code}; -} - -string CodeGen::storeInst_gen(StoreInst *stInst) { - string code; - /** - *code in here - */ - return code; -} -pair CodeGen::loadInst_gen(LoadInst *ldInst, RegId dstRegId) { - string code; - /** - *code in here - */ - return {dstRegId, code}; -} -string CodeGen::returnInst_gen(ReturnInst *retInst) { - string code; - /** - *code in here - */ - return code; -} -string CodeGen::uncondBrInst_gen(UncondBrInst *ubInst) { - string code; - /** - *code in here - */ - return code; -} -string CodeGen::condBrInst_gen(CondBrInst *cbInst) { - string code; - /** - *code in here - */ - return code; -} -pair CodeGen::callInst_gen(CallInst *callInst, RegId dstRegId) { - string code; - /** - *code in here - */ - return {dstRegId, code}; -} - -string CodeGen::instruction_gen(Instruction *instr) { - string code; - string unkName = instr->getName(); - RegManager::RegId dstRegId = RegManager::RNONE; - auto instrType = instr->getKind(); - pair tmp; - switch (instrType) { - // binary inst - case Instruction::kAdd: - case Instruction::kMul: - case Instruction::kSub: { - BinaryInst *bInst = dynamic_cast(instr); - // registers are used only for instruction operation, consider use which - // register (any one that is free for use) - tmp = binaryInst_gen(bInst, RegManager::RANY); - code += tmp.second; - dstRegId = tmp.first; - break; - } - case Instruction::kLoad: { - LoadInst *ldInst = dynamic_cast(instr); - tmp = loadInst_gen(ldInst, RegManager::RANY); - code += M_emitComment("load inst"); - code += tmp.second; - dstRegId = tmp.first; - break; - } - case Instruction::kStore: { - StoreInst *stInst = dynamic_cast(instr); - code += M_emitComment("store inst"); - code += storeInst_gen(stInst); - return code; - break; - } - case Instruction::kAlloca: { - AllocaInst *aInst = dynamic_cast(instr); - tmp = allocaInst_gen(aInst, RegManager::RANY); - code += M_emitComment("alloca inst"); - code += tmp.second; - dstRegId = tmp.first; - break; - } - case Instruction::kReturn: { - ReturnInst *retInst = dynamic_cast(instr); - code += M_emitComment("return inst"); - code += returnInst_gen(retInst); - return code; - break; - } - case Instruction::kCall: { - CallInst *cInst = dynamic_cast(instr); - auto tmp = callInst_gen(cInst, RegManager::RANY); - code += tmp.second; - dstRegId = tmp.first; - if (dstRegId == RegManager::R0) - return code; - break; - } - case Instruction::kBr: { - UncondBrInst *ubInst = dynamic_cast(instr); - code += uncondBrInst_gen(ubInst); - return code; - break; - } - case Instruction::kCondBr: { - CondBrInst *cbInst = dynamic_cast(instr); - code += condBrInst_gen(cbInst); - return code; - break; - } - default: { - code += - "ERROR CODE : instruction " + unkName + " is not implementation" + eol; - break; - } - } - if (!instr->getType()->isVoid()) { - code += storeRegToStack_gen(dstRegId, instr); - // regm.freeReg(dstRegId);//TODO : code in here. - } - return code; -} -// -string CodeGen::globaldata_gen() { - string asmCode; - /** - *code in here - */ - return asmCode; -} - -string CodeGen::literalPoolsCode_gen(Function *func) { - string code; - /** - *code in here - */ - return code; -} - -} // namespace sysy diff --git a/src/include/Backend.h b/src/include/Backend.h deleted file mode 100644 index 9acb6e6..0000000 --- a/src/include/Backend.h +++ /dev/null @@ -1,217 +0,0 @@ -#pragma once -/** - * 后端设计需要注意的点 - * - * label分配 : - * 全局变量的label,常量的label,basicblock的label,函数入口label,函数出口label - * 全局数据处理 - * 常量处理 - * 临时变量的处理(包括函数参数也是临时变量) - * 函数参数的处理 - * 块参数的处理 (如果SSA问题通过块传参解决则需要处理块参数) - * 函数栈空间结构的设计 - * 块的遍历问题 - * arm32的过程调用约定 - * - * 后端测试需要注意的点 - * - * 如何汇编与链接. - * qemu以及树莓派如何运行. - */ -#include -#include -#include -#include -#include "IR.h" - -using std::find; -using std::map; -using std::pair; -using std::set; -using std::string; -using std::to_string; -using std::vector; - -#define Macro_ERROR_MSG(...) \ - do { \ - fprintf(stderr, "ERROR in line-%d of %s: ", __LINE__, __FILE__); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - fflush(stderr); \ - exit(1); \ - } while (0); - -#define M_emitInst(STR) (space + STR + eol) -#define M_emitComment(STR) (space + "//" + STR + eol) -#define M_emitLabel(STR) (STR + ":" + eol) - -// #define REG_EXP - -static const string space = string(4, ' '); -static const string eol = "\n"; -// only for armv7 -static const int int_align = 4; -static const int int_size = 4; -static const int int_p2align = 2; -static const int reg_size = 4; - -// default arm32 max imm -// -static const uint32_t maxMovImm = 0xFFF; -static const string stackIndexReg = "fp"; - -static uint16_t getWordHigh(uint32_t cval) { return (cval >> 16) & 0xFFFF; } -static uint16_t getWordLow(uint32_t cval) { return cval & 0xFFFF; } -// -static string emitInst_1srcR_noDstR(string name, string srcReg) { - return space + name + " " + srcReg + eol; -} -static string emitInst_2srcR_1dstR(string name, string srcReg0, string srcReg1, - string dstReg) { - return space + name + " " + dstReg + ", " + srcReg0 + ", " + srcReg1 + eol; -} - -namespace sysy { -// -class RegManager { -public: - //{0,1,2,3,4,5,6,7,8,9,10}; - enum RegId : unsigned { - R0 = 0, - R1 = 1, - R2 = 2, - R3 = 3, - R4 = 4, - R5 = 5, - R6 = 6, - R7 = 7, - R8 = 8, - R9 = 9, - R10 = 10, - RNONE = 1024, - RANY = 2048, - }; - static string toString(RegId reg) { - if (reg == RNONE) - return "RNONE"; - if (reg == RANY) - return "RANY"; - return "r" + to_string(reg); - } -}; - -class Operand { -public: - using RegId = RegManager::RegId; - enum Kind { - kReg, - kImm, - }; - Kind kind; - union { - uint32_t imm; - RegId regId; - }; - Operand(){}; - Operand(uint32_t imm) : kind(kImm), imm(imm) {} - Operand(RegId regId) : kind(kReg), regId(regId) {} - bool isImm(void) { return kind == kImm; } - bool isReg(void) { return kind == kReg; } - uint32_t getImm(void) { - assert(kind == kImm); - return imm; - } - RegId getRegId(void) { - assert(kind == kReg); - return regId; - } - string toString(void) { - if (kind == kImm) - return "#" + to_string(imm); - else - return RegManager::toString(regId); - } -}; - -class CodeGen { -public: - using RegId = RegManager::RegId; - -private: - sysy::Module *module; - Function *curFunc; - BasicBlock *curBB; - // - RegManager regm; - // globalValue - bool loadGlobalValByMOVWT = true; - // basicBlock - vector linear_bb; - int bb_no = 0; - // function params, return value and localVar - map paramsStOffset; - map localVarStOffset; - int retValueStOffset = 0; - size_t stOffsetAcc = 0; - // label manager - map bb_labels; - uint64_t label_no = 0; - -public: - CodeGen(Module *module) : module(module) {} - // code_gen function list - string code_gen(); - string module_gen(Module *module); - string function_gen(Function *func); - string basicBlock_gen(BasicBlock *bb); - string instruction_gen(Instruction *instr); - string globaldata_gen(); - string prologueCode_gen(Function *func); - string epilogueCode_gen(Function *func); - string literalPoolsCode_gen(Function *func); - string functionHead_gen(Function *func); - // Module - void clearModuleRecord(Module *module) { label_no = 0; } - // instruction gen function list - // - pair loadInst_gen(LoadInst *ldInst, RegId dstRegId); - string storeInst_gen(StoreInst *stInst); - pair allocaInst_gen(AllocaInst *aInst, RegId dstRegId); - string returnInst_gen(ReturnInst *retInst); - pair callInst_gen(CallInst *retInst, RegId dstRegId); - pair binaryInst_gen(BinaryInst *bInst, RegId dstRegId); - pair unaryInst_gen(UnaryInst *bInst, RegId dstRegId); - string uncondBrInst_gen(UncondBrInst *ubInst); - string condBrInst_gen(CondBrInst *ubInst); - - // - string storeRegToStack_gen(RegId regId, Instruction *inst) { - string code; - /** - *code in here - */ - return code; - } - // function - void clearFunctionRecord(Function *func) { - localVarStOffset.clear(); - paramsStOffset.clear(); - retValueStOffset = 0; - bb_labels.clear(); - // - stOffsetAcc = 0; - } - string getBBLabel(BasicBlock *bb) { - auto t = bb_labels.find(bb); - string label; - if (t == bb_labels.end()) { - label = ".LBB_" + to_string(label_no++); - bb_labels.emplace(bb, label); - } else { - label = t->second; - } - return label; - } -}; - -} // namespace sysy \ No newline at end of file