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;
instruction_builder builder{context.code};
// Bytes starting at stack pointer that are free for use
// (pushing registers / allocating variables)
// Must be a multiple of 8
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
// Difference between initial stack pointer at function enter
// and current virtual stack pointer value. The actual stack pointer
// value is rounded down to a multiple of 16
std::uint32_t stack_offset = 0;
struct variable_data
@ -97,9 +92,8 @@ namespace pslang::jit::aarch64
{
std::unordered_map<std::string, variable_data> variables = {};
// Different between initial stack pointer at scope enter
// and current stack pointer value
// Must be a multiple of 16
// Difference between initial virtual stack pointer at scope enter
// and current virtual stack pointer value
std::uint32_t stack_offset = 0;
};
@ -332,7 +326,7 @@ namespace pslang::jit::aarch64
{
apply(*node.initializer);
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)
@ -357,30 +351,20 @@ namespace pslang::jit::aarch64
private:
void push(std::uint8_t reg)
{
if (stack_free_bytes < 8)
{
builder.sub_imm(31, 31, 16);
stack_free_bytes += 16;
builder.str(reg, 31, 0);
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)
{
builder.ldr(reg, 31, stack_free_bytes / 8);
stack_free_bytes += 8;
if (stack_free_bytes >= 16)
{
builder.ldr(reg, 31, 0);
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)
void set_m1(std::uint8_t reg)