From 2c4c3435554d4fc7e3a5cb704168f1d25306b32e Mon Sep 17 00:00:00 2001 From: wqz <1197460504@qq.com> Date: Sat, 17 Jun 2023 00:20:35 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=A1=E7=AE=97=E5=87=BA=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E6=A0=88=E9=9C=80=E8=A6=81=E5=BC=80=E8=BE=9F=E7=9A=84=E7=A9=BA?= =?UTF-8?q?=E9=97=B4=E5=A4=A7=E5=B0=8F;=E5=BD=A2=E5=BC=8F=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E5=85=A5=E6=A0=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/backend/codegen.cpp | 119 ++++++++++++++++++++++++++++------------ src/backend/codegen.hpp | 4 ++ 2 files changed, 87 insertions(+), 36 deletions(-) diff --git a/src/backend/codegen.cpp b/src/backend/codegen.cpp index 05d0105..3fd20a1 100644 --- a/src/backend/codegen.cpp +++ b/src/backend/codegen.cpp @@ -99,21 +99,43 @@ namespace backend } } } + // put arguments in the stack + auto entry_block = func->getEntryBlock(); + auto args = entry_block->getArguments(); + int arg_num = 0; + for (auto arg = args.begin(); arg != args.end(); ++arg) + { + // r0-r3 + if (arg_num < 4) + { + paramsStOffset.emplace(arg->get(), top_offset); + code += space + "str\tr" + to_string(arg_num) + ", [fp, #" + to_string(top_offset) + "]" + endl; + top_offset -= 4; + } + // other + else + { + paramsStOffset.emplace(arg->get(), above_offset); + above_offset += 4; + } + arg_num++; + } + if (max_param > 4) + top_offset -= (max_param - 4) * 4; + code = space + "sub\tsp, sp, #" + to_string(-top_offset - 4) + endl + code; if (haveCall) { - // push fp,lr - code += space + "push\t{fp,lr}" + endl; // set fp - code += space + "add\tfp, sp, #4" + endl; - // top_offset = -8; + code = space + "add\tfp, sp, #4" + endl + code; + // push fp,lr + code = space + "push\t{fp,lr}" + endl + code; } else { - // push fp - code += space + "push\t{fp}" + endl; // set fp - code += space + "add\tfp, sp, #0" + endl; - // top_offset = -4; + code = space + "add\tfp, sp, #0" + endl + code; + // push fp + code = space + "push\t{fp}" + endl + code; } return code; } @@ -147,7 +169,7 @@ namespace backend code += space + "pop\t{fp,lr}" + endl; else code += space + "pop\t{fp}" + endl; - code += space + "bx\t" + endl; + code += space + "bx\tlr" + endl; return code; } @@ -158,6 +180,9 @@ namespace backend string bbCode; auto bbs = func->getBasicBlocks(); top_offset = -8; + above_offset = 4; + max_param = 0; + backpatch.clear(); for (auto iter = bbs.begin(); iter != bbs.end(); ++iter) { auto bb = iter->get(); @@ -168,9 +193,18 @@ namespace backend string prologueCode = prologueCode_gen(func); string epilogueCode = epilogueCode_gen(func); string literalPoolsCode = literalPoolsCode_gen(func); - // - code = funcHead + prologueCode + bbCode + - epilogueCode + literalPoolsCode; + // backpatch parasoffset + int start_pos = 0; + int index = 0; + while ((start_pos = bbCode.find("unk", start_pos)) != std::string::npos) + { + int arg_offset = paramsStOffset[backpatch[index++]]; + bbCode.replace(start_pos, 3, to_string(arg_offset)); + start_pos += to_string(arg_offset).length(); + } + code += funcHead + prologueCode + bbCode + + epilogueCode + literalPoolsCode; + return code; } @@ -242,20 +276,23 @@ namespace backend string CodeGen::storeInst_gen(StoreInst *stInst) { string code; - auto value = dyncast(stInst->getValue()); - auto pointer = dynamic_cast(stInst->getPointer()); - int offset = localVarStOffset[pointer]; - std::stringstream ss1; - std::stringstream ss2; - if (value) + auto value = stInst->getValue(); + auto pointer = stInst->getPointer(); + int offset; + if (localVarStOffset.find(dynamic_cast(pointer)) != localVarStOffset.end()) + offset = localVarStOffset[dynamic_cast(pointer)]; + else if (paramsStOffset.find(dynamic_cast(pointer)) != paramsStOffset.end()) + offset = paramsStOffset[dynamic_cast(pointer)]; + if (isa(value)) { - int constant_value = value->getInt(); - ss1 << constant_value; - code += space + "mov\tr3, #" + ss1.str() + endl; + int constant_value = dynamic_cast(value)->getInt(); + code += space + "mov\tr3, #" + to_string(constant_value) + endl; + code += space + "str\tr3, [fp, #" + to_string(offset) + "]" + endl; + } + else + { + code += space + "str\tr" + value->getName() + ", [fp, #" + to_string(offset) + "]" + endl; } - ss2 << offset; - code += space + "str\tr3, [fp, #" + ss2.str() + "]" + endl; - return code; } pair @@ -270,28 +307,36 @@ namespace backend int pos; bool found = false; // find var in localvar + // if (localVarStOffset.find(dynamic_cast(var)) != localVarStOffset.end()) + // pos = localVarStOffset[dynamic_cast(var)]; for (auto local_var : localVarStOffset) { + // code += "load var in localvar\n"; if (local_var.first == var) { pos = local_var.second; found = true; + code += space + "ldr\tr" + to_string(reg_num) + ", [fp, #" + to_string(pos) + "]" + endl; break; } } // if var is not localvar but an argument if (not found) { - for (auto arg : paramsStOffset) - { - if (arg.first == var) - { - pos = arg.second; - break; - } - } + code += space + "ldr\tr" + to_string(reg_num) + ", [fp, #unk]" + endl; + backpatch.push_back(dynamic_cast(var)); } - code += space + "ldr\tr" + to_string(reg_num) + ", [fp, #" + to_string(pos) + "]" + endl; + // { + // code += "load var in paramvar\n"; + // for (auto arg : paramsStOffset) + // { + // if (arg.first == var) + // { + // // pos = arg.second; + // break; + // } + // } + // } return {dstRegId, code}; } string CodeGen::returnInst_gen(ReturnInst *retInst) @@ -327,6 +372,8 @@ namespace backend RegId dst_reg = RegManager::R0; int arg_num = 0; int para_offset = 0; + // the max number of all subfunctions' arguments + max_param = args.size() > max_param ? args.size() : max_param; for (auto arg : args) { arg_num++; @@ -374,7 +421,7 @@ namespace backend { LoadInst *ldInst = dynamic_cast(instr); tmp = loadInst_gen(ldInst, RegManager::RANY); - code += M_emitComment("load inst"); + // code += M_emitComment("load inst"); code += tmp.second; dstRegId = tmp.first; break; @@ -382,7 +429,7 @@ namespace backend case Instruction::kStore: { StoreInst *stInst = dynamic_cast(instr); - code += M_emitComment("store inst"); + // code += M_emitComment("store inst"); code += storeInst_gen(stInst); return code; break; @@ -391,7 +438,7 @@ namespace backend { AllocaInst *aInst = dynamic_cast(instr); tmp = allocaInst_gen(aInst, RegManager::RANY); - code += M_emitComment("alloca inst"); + // code += M_emitComment("alloca inst"); code += tmp.second; dstRegId = tmp.first; break; diff --git a/src/backend/codegen.hpp b/src/backend/codegen.hpp index 837840c..d566273 100644 --- a/src/backend/codegen.hpp +++ b/src/backend/codegen.hpp @@ -183,6 +183,10 @@ namespace backend map bb_labels; uint64_t label_no = 0; int top_offset = 0; + int above_offset = 4; + int max_param = 0; + // record arguments need to be backpatched + vector backpatch; public: CodeGen(Module *module) : module(module) {}