计算出函数栈需要开辟的空间大小;形式参数入栈

main
wqz 3 years ago
parent d33a9852c5
commit 2c4c343555

@ -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<ConstantValue>(stInst->getValue());
auto pointer = dynamic_cast<AllocaInst *>(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<Instruction *>(pointer)) != localVarStOffset.end())
offset = localVarStOffset[dynamic_cast<Instruction *>(pointer)];
else if (paramsStOffset.find(dynamic_cast<Argument *>(pointer)) != paramsStOffset.end())
offset = paramsStOffset[dynamic_cast<Argument *>(pointer)];
if (isa<ConstantValue>(value))
{
int constant_value = value->getInt();
ss1 << constant_value;
code += space + "mov\tr3, #" + ss1.str() + endl;
int constant_value = dynamic_cast<ConstantValue *>(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<RegId, string>
@ -270,28 +307,36 @@ namespace backend
int pos;
bool found = false;
// find var in localvar
// if (localVarStOffset.find(dynamic_cast<Instruction *>(var)) != localVarStOffset.end())
// pos = localVarStOffset[dynamic_cast<Instruction *>(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<Argument *>(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<LoadInst *>(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<StoreInst *>(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<AllocaInst *>(instr);
tmp = allocaInst_gen(aInst, RegManager::RANY);
code += M_emitComment("alloca inst");
// code += M_emitComment("alloca inst");
code += tmp.second;
dstRegId = tmp.first;
break;

@ -183,6 +183,10 @@ namespace backend
map<BasicBlock *, string> 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<Argument *> backpatch;
public:
CodeGen(Module *module) : module(module) {}

Loading…
Cancel
Save