Support frame pointers

This commit is contained in:
Nikita Lisitsa 2026-03-25 19:23:12 +03:00
parent 64514d9bf4
commit d31758eb4a

View file

@ -15,6 +15,8 @@ namespace pslang::jit::aarch64
struct local_context struct local_context
{ {
bool use_frame_pointer = true;
std::unordered_map<std::string, std::int32_t> extern_symbols; std::unordered_map<std::string, std::int32_t> extern_symbols;
std::unordered_map<ir::node_ref, std::int32_t> nodes; std::unordered_map<ir::node_ref, std::int32_t> nodes;
@ -632,12 +634,18 @@ namespace pslang::jit::aarch64
else else
throw std::runtime_error("Unsupported function argument type"); throw std::runtime_error("Unsupported function argument type");
} }
if (!lcontext.use_frame_pointer)
{
builder.sub_imm(31, 31, 16); builder.sub_imm(31, 31, 16);
builder.str(30, 31, 0); builder.str(30, 31, 0);
}
lcontext.branch_resolve.emplace_back(pcontext.code.size(), node.target); lcontext.branch_resolve.emplace_back(pcontext.code.size(), node.target);
builder.bl(0); builder.bl(0);
if (!lcontext.use_frame_pointer)
{
builder.ldr(30, 31, 0); builder.ldr(30, 31, 0);
builder.add_imm(31, 31, 16); builder.add_imm(31, 31, 16);
}
// TODO: struct/array return value? // TODO: struct/array return value?
if (types::is_unit_type(*type)) if (types::is_unit_type(*type))
@ -695,6 +703,11 @@ namespace pslang::jit::aarch64
else else
throw std::runtime_error("Unsupported return value type"); throw std::runtime_error("Unsupported return value type");
} }
if (lcontext.use_frame_pointer)
{
builder.ldr(29, 31, (stack_size - 16) / 8);
builder.ldr(30, 31, (stack_size - 8) / 8);
}
if (stack_size > 0) if (stack_size > 0)
builder.add_imm(31, 31, stack_size); builder.add_imm(31, 31, stack_size);
builder.ret(); builder.ret();
@ -703,6 +716,10 @@ namespace pslang::jit::aarch64
void compile(ir::node_ref begin, ir::node_ref end) void compile(ir::node_ref begin, ir::node_ref end)
{ {
stack_size = 0; stack_size = 0;
if (lcontext.use_frame_pointer)
stack_size += 16;
for (auto it = begin; it != end; ++it) for (auto it = begin; it != end; ++it)
{ {
if (ir::is_value_instruction(it->instruction)) if (ir::is_value_instruction(it->instruction))
@ -711,6 +728,7 @@ namespace pslang::jit::aarch64
stack_position[it] = stack_size; stack_position[it] = stack_size;
} }
} }
stack_size = ((stack_size + 15) / 16) * 16; stack_size = ((stack_size + 15) / 16) * 16;
if (!std::holds_alternative<ir::label>(begin->instruction)) if (!std::holds_alternative<ir::label>(begin->instruction))
@ -721,6 +739,12 @@ namespace pslang::jit::aarch64
lcontext.nodes[it] = pcontext.code.size(); lcontext.nodes[it] = pcontext.code.size();
if (stack_size > 0) if (stack_size > 0)
builder.sub_imm(31, 31, stack_size); builder.sub_imm(31, 31, stack_size);
if (lcontext.use_frame_pointer)
{
builder.str(29, 31, (stack_size - 16) / 8);
builder.str(30, 31, (stack_size - 8) / 8);
builder.add_imm(31, 29, stack_size - 16);
}
++it; ++it;
for (; it != end; ++it) for (; it != end; ++it)