Aarch64 jit compiler wip: fix loading/storing floating-point values

This commit is contained in:
Nikita Lisitsa 2026-01-06 12:45:12 +03:00
parent 00d8f0fe52
commit 668851f6bf
6 changed files with 28 additions and 9 deletions

View file

@ -170,7 +170,7 @@ int main(int argc, char ** argv)
{ {
// TODO: remove, testing-only code; should execute entry point instead // TODO: remove, testing-only code; should execute entry point instead
auto offset = module.code.symbol_table.at("test"); auto offset = module.code.symbol_table.at("test");
auto fptr = (int(*)())(module.code.memory.data.get() + offset); auto fptr = (float(*)())(module.code.memory.data.get() + offset);
auto x = fptr(); auto x = fptr();
std::cout << "Result: " << std::boolalpha << x << std::endl; std::cout << "Result: " << std::boolalpha << x << std::endl;
} }

View file

@ -1,2 +1,3 @@
func test() -> i32: func test() -> f32:
return 3.141592h as i32 let pi : f16 = 3.141592h
return (pi * pi) as f32

View file

@ -334,7 +334,7 @@ namespace pslang::jit::aarch64
if (auto jt = it->variables.find(node.name); jt != it->variables.end()) if (auto jt = it->variables.find(node.name); jt != it->variables.end())
{ {
if (types::is_floating_point_type(*node.inferred_type)) if (types::is_floating_point_type(*node.inferred_type))
builder.ldr_fp(0, fp_mode_for(*node.inferred_type), 31, (stack_offset - jt->second.frame_offset) / 4); builder.ldr_fp(0, fp_mode_for(*node.inferred_type), 31, (stack_offset - jt->second.frame_offset) / builtin_type_size(*node.inferred_type));
else else
builder.ldr(0, 31, (stack_offset - jt->second.frame_offset) / 8); builder.ldr(0, 31, (stack_offset - jt->second.frame_offset) / 8);
break; break;
@ -601,7 +601,7 @@ namespace pslang::jit::aarch64
{ {
auto type = ast::get_type(*node.rhs); auto type = ast::get_type(*node.rhs);
if (types::is_floating_point_type(*type)) if (types::is_floating_point_type(*type))
builder.str_fp(0, fp_mode_for(*type), 31, (stack_offset - jt->second.frame_offset) / 4); builder.str_fp(0, fp_mode_for(*type), 31, (stack_offset - jt->second.frame_offset) / builtin_type_size(*type));
else else
builder.str(0, 31, (stack_offset - jt->second.frame_offset) / 8); builder.str(0, 31, (stack_offset - jt->second.frame_offset) / 8);
break; break;
@ -753,8 +753,6 @@ namespace pslang::jit::aarch64
scopes.back().stack_offset -= 16; scopes.back().stack_offset -= 16;
} }
// @mode = 0: 32-bit
// @mode = 1: 64-bit
void push_fp(std::uint8_t reg, std::uint8_t mode) void push_fp(std::uint8_t reg, std::uint8_t mode)
{ {
builder.sub_imm(31, 31, 16); builder.sub_imm(31, 31, 16);

View file

@ -166,12 +166,12 @@ namespace pslang::jit::aarch64
void instruction_builder::ldr_fp(std::uint8_t reg_dst, std::uint8_t mode, std::uint8_t reg_addr, std::uint16_t offset) void instruction_builder::ldr_fp(std::uint8_t reg_dst, std::uint8_t mode, std::uint8_t reg_addr, std::uint16_t offset)
{ {
do_push(0xbd400000u | (reg_dst & REG_MASK) | ((reg_addr & REG_MASK) << 5) | ((offset & 0xfffu) << 10) | ((mode & 0x3u) << 30)); do_push(0x3d400000u | (reg_dst & REG_MASK) | ((reg_addr & REG_MASK) << 5) | ((offset & 0xfffu) << 10) | ((mode & 0x3u) << 30));
} }
void instruction_builder::str_fp(std::uint8_t reg_src, std::uint8_t mode, std::uint8_t reg_addr, std::uint16_t offset) void instruction_builder::str_fp(std::uint8_t reg_src, std::uint8_t mode, std::uint8_t reg_addr, std::uint16_t offset)
{ {
do_push(0xbd000000u | (reg_src & REG_MASK) | ((reg_addr & REG_MASK) << 5) | ((offset & 0xfffu) << 10) | ((mode & 0x3u) << 30)); do_push(0x3d000000u | (reg_src & REG_MASK) | ((reg_addr & REG_MASK) << 5) | ((offset & 0xfffu) << 10) | ((mode & 0x3u) << 30));
} }
void instruction_builder::fcvt(std::uint8_t reg_src, std::uint8_t mode_src, std::uint8_t reg_dst, std::uint8_t mode_dst) void instruction_builder::fcvt(std::uint8_t reg_src, std::uint8_t mode_src, std::uint8_t reg_dst, std::uint8_t mode_dst)

View file

@ -23,4 +23,6 @@ namespace pslang::types
bool is_numeric_type(type const & type); bool is_numeric_type(type const & type);
bool is_builtin_type(type const & type); bool is_builtin_type(type const & type);
std::size_t builtin_type_size(type const & type);
} }

View file

@ -123,4 +123,22 @@ namespace pslang::types
return false; return false;
} }
std::size_t builtin_type_size(type const & type)
{
if (std::get_if<unit_type>(&type))
return 1;
if (auto ptype = std::get_if<primitive_type>(&type))
{
return std::visit([]<typename T>(primitive_type_base<T> const &) -> std::size_t
{
if constexpr (std::is_same_v<T, half_float>)
return 2;
return sizeof(T);
}, *ptype);
}
return 0;
}
} }