Aarch64 compiler wip: simplify stack, always 16-byte-align pushed values

This commit is contained in:
Nikita Lisitsa 2026-01-04 12:15:52 +03:00
parent 4df89de879
commit 716d51221f

View file

@ -75,14 +75,9 @@ namespace pslang::jit::aarch64
context & context; context & context;
instruction_builder builder{context.code}; instruction_builder builder{context.code};
// Bytes starting at stack pointer that are free for use // Difference between initial stack pointer at function enter
// (pushing registers / allocating variables) // and current virtual stack pointer value. The actual stack pointer
// Must be a multiple of 8 // value is rounded down to a multiple of 16
std::uint32_t stack_free_bytes = 0;
// Different between initial stack pointer at function enter
// and current stack pointer value
// Must be a multiple of 16
std::uint32_t stack_offset = 0; std::uint32_t stack_offset = 0;
struct variable_data struct variable_data
@ -97,9 +92,8 @@ namespace pslang::jit::aarch64
{ {
std::unordered_map<std::string, variable_data> variables = {}; std::unordered_map<std::string, variable_data> variables = {};
// Different between initial stack pointer at scope enter // Difference between initial virtual stack pointer at scope enter
// and current stack pointer value // and current virtual stack pointer value
// Must be a multiple of 16
std::uint32_t stack_offset = 0; std::uint32_t stack_offset = 0;
}; };
@ -332,7 +326,7 @@ namespace pslang::jit::aarch64
{ {
apply(*node.initializer); apply(*node.initializer);
push(0); push(0);
scopes.back().variables[node.name] = {.frame_offset = stack_offset - stack_free_bytes}; scopes.back().variables[node.name] = {.frame_offset = stack_offset};
} }
void apply(ast::return_statement const & node) void apply(ast::return_statement const & node)
@ -358,28 +352,18 @@ namespace pslang::jit::aarch64
private: private:
void push(std::uint8_t reg) void push(std::uint8_t reg)
{ {
if (stack_free_bytes < 8) builder.sub_imm(31, 31, 16);
{ builder.str(reg, 31, 0);
builder.sub_imm(31, 31, 16); stack_offset += 16;
stack_free_bytes += 16; scopes.back().stack_offset += 16;
stack_offset += 16;
scopes.back().stack_offset += 16;
}
builder.str(reg, 31, (stack_free_bytes - 8) / 8);
stack_free_bytes -= 8;
} }
void pop(std::uint8_t reg) void pop(std::uint8_t reg)
{ {
builder.ldr(reg, 31, stack_free_bytes / 8); builder.ldr(reg, 31, 0);
stack_free_bytes += 8; builder.add_imm(31, 31, 16);
if (stack_free_bytes >= 16) stack_offset -= 16;
{ scopes.back().stack_offset -= 16;
builder.add_imm(31, 31, 16);
stack_free_bytes -= 16;
stack_offset -= 16;
scopes.back().stack_offset -= 16;
}
} }
// Set register @reg to -1 (all bits = 1) // Set register @reg to -1 (all bits = 1)