diff --git a/include/naivebackend/codegen.hpp b/include/naivebackend/codegen.hpp index 0ee32fd..0e63a57 100644 --- a/include/naivebackend/codegen.hpp +++ b/include/naivebackend/codegen.hpp @@ -21,7 +21,12 @@ inline void GenerateASM(std::shared_ptr act, std::vector(act)) { size_t sz = CalcSize(binary_act->type); @@ -94,7 +99,12 @@ inline void GenerateASM(std::shared_ptr act, std::vectorptr_full, 4, "t0", layout, code_lines); - code_lines.push_back("addi t2, t0, " + std::to_string(offset)); + if (offset < 2048) { + code_lines.push_back("addi t2, t0, " + std::to_string(offset)); + } else { + code_lines.push_back("li t1, " + std::to_string(offset)); + code_lines.push_back("add t2, t0, t1"); + } GenerateWriteAccess(get_element_act->result_full, 4, "t2", layout, code_lines); } else { throw std::runtime_error("Unknown getelementptr indices size"); @@ -134,7 +144,12 @@ inline void GenerateASM(std::shared_ptr act, std::vector= 8) { size_t ps_delta = (num_of_args * 4 + 15) / 16 * 16; - code_lines.push_back("addi sp, sp, -" + std::to_string(ps_delta)); + if (ps_delta < 2048) { + code_lines.push_back("addi sp, sp, -" + std::to_string(ps_delta)); + } else { + code_lines.push_back("li t0, -" + std::to_string(ps_delta)); + code_lines.push_back("add sp, sp, t0"); + } for (size_t i = 8; i < num_of_args; i++) { IRVar2RISCVReg(call_act->args_val_full[i], CalcSize(call_act->args_ty[i]), "t0", layout, code_lines); code_lines.push_back("sw t0, " + std::to_string((i - 8) * 4) + "(sp)"); diff --git a/include/naivebackend/naivebackend.h b/include/naivebackend/naivebackend.h index 95c2bae..d1a0f94 100644 --- a/include/naivebackend/naivebackend.h +++ b/include/naivebackend/naivebackend.h @@ -153,14 +153,31 @@ inline void GenerateReadAccess(std::string val, size_t bytes, std::string output } else if (val.size() > 12 && val.substr(0, 12) == "%.var.local.") { // local variable address keeper size_t offset = layout.QueryOffeset(val); - code_lines.push_back("addi " + output_reg + ", s0, -" + std::to_string(offset)); + if (offset < 2048) { + code_lines.push_back("addi " + output_reg + ", s0, -" + std::to_string(offset)); + } else { + code_lines.push_back("li " + output_reg + ", -" + std::to_string(offset)); + code_lines.push_back("add " + output_reg + ", s0, " + output_reg); + } } else if (val.size() > 10 && val.substr(0, 10) == "%.var.tmp.") { // tmp variable, not address keeper size_t offset = layout.QueryOffeset(val); if (bytes == 1) { - code_lines.push_back("lb " + output_reg + ", -" + std::to_string(offset) + "(s0)"); + if (offset < 2048) { + code_lines.push_back("lb " + output_reg + ", -" + std::to_string(offset) + "(s0)"); + } else { + code_lines.push_back("li " + output_reg + ", -" + std::to_string(offset)); + code_lines.push_back("add " + output_reg + ", s0, " + output_reg); + code_lines.push_back("lb " + output_reg + ", 0(" + output_reg + ")"); + } } else if (bytes == 4) { - code_lines.push_back("lw " + output_reg + ", -" + std::to_string(offset) + "(s0)"); + if (offset < 2048) { + code_lines.push_back("lw " + output_reg + ", -" + std::to_string(offset) + "(s0)"); + } else { + code_lines.push_back("li " + output_reg + ", -" + std::to_string(offset)); + code_lines.push_back("add " + output_reg + ", s0, " + output_reg); + code_lines.push_back("lw " + output_reg + ", 0(" + output_reg + ")"); + } } else { throw std::runtime_error("Unknown bytes"); } @@ -211,9 +228,21 @@ inline void GenerateWriteAccess(std::string val, size_t bytes, std::string data_ // tmp variable, not address keeper size_t offset = layout.QueryOffeset(val); if (bytes == 1) { - code_lines.push_back("sb " + data_reg + ", -" + std::to_string(offset) + "(s0)"); + if (offset < 2048) { + code_lines.push_back("sb " + data_reg + ", -" + std::to_string(offset) + "(s0)"); + } else { + code_lines.push_back("li t0, -" + std::to_string(offset)); + code_lines.push_back("add t0, s0, t0"); + code_lines.push_back("sb " + data_reg + ", 0(t0)"); + } } else if (bytes == 4) { - code_lines.push_back("sw " + data_reg + ", -" + std::to_string(offset) + "(s0)"); + if (offset < 2048) { + code_lines.push_back("sw " + data_reg + ", -" + std::to_string(offset) + "(s0)"); + } else { + code_lines.push_back("li t0, -" + std::to_string(offset)); + code_lines.push_back("add t0, s0, t0"); + code_lines.push_back("sw " + data_reg + ", 0(t0)"); + } } else { throw std::runtime_error("Unknown bytes"); } diff --git a/src/IR/IRBuilder.cpp b/src/IR/IRBuilder.cpp index b656864..b42c582 100644 --- a/src/IR/IRBuilder.cpp +++ b/src/IR/IRBuilder.cpp @@ -430,7 +430,7 @@ void IRBuilder::ActuralVisit(NewArrayExpr_ASTNode *node) { } auto dim_info = std::make_shared(); - std::string dim_info_var = "%.var.tmp." + std::to_string(tmp_var_counter++); + std::string dim_info_var = "%.var.local.tmp." + std::to_string(tmp_var_counter++); cur_alloca_block->actions.push_back(dim_info); dim_info->num = dims_with_size; dim_info->name_full = dim_info_var; diff --git a/src/naivebackend/naivebackend.cpp b/src/naivebackend/naivebackend.cpp index 6baeeec..2a2cb4e 100644 --- a/src/naivebackend/naivebackend.cpp +++ b/src/naivebackend/naivebackend.cpp @@ -52,10 +52,19 @@ void GenerateNaiveASM(std::ostream &os, std::shared_ptr prog) { riscv->funcs.push_back(func_asm); func_asm->full_label = func_def->func_name_raw; FuncLayout &layout = func_layouts[func_def->func_name_raw]; - func_asm->code_lines.push_back("addi sp, sp, -" + std::to_string(layout.total_frame_size)); - func_asm->code_lines.push_back("sw ra, " + std::to_string(layout.total_frame_size - 4) + "(sp)"); - func_asm->code_lines.push_back("sw s0, " + std::to_string(layout.total_frame_size - 8) + "(sp)"); - func_asm->code_lines.push_back("addi s0, sp, " + std::to_string(layout.total_frame_size)); + if (layout.total_frame_size < 2048) { + func_asm->code_lines.push_back("addi sp, sp, -" + std::to_string(layout.total_frame_size)); + func_asm->code_lines.push_back("sw ra, " + std::to_string(layout.total_frame_size - 4) + "(sp)"); + func_asm->code_lines.push_back("sw s0, " + std::to_string(layout.total_frame_size - 8) + "(sp)"); + func_asm->code_lines.push_back("addi s0, sp, " + std::to_string(layout.total_frame_size)); + } else { + func_asm->code_lines.push_back("li t0, " + std::to_string(layout.total_frame_size)); + func_asm->code_lines.push_back("sub sp, sp, t0"); + func_asm->code_lines.push_back("add t0, t0, sp"); + func_asm->code_lines.push_back("sw ra, -4(t0)"); + func_asm->code_lines.push_back("sw s0, -8(t0)"); + func_asm->code_lines.push_back("mv s0, t0"); + } if (func_def->init_block) { func_asm->code_lines.push_back(".entrylabel." + func_def->init_block->label_full + ":"); for (auto act : func_def->init_block->actions) {