From 4a4a5045f8d620c4fd477a2c6a0b8d39455fc7dd Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 21 Aug 2026 12:19:02 +0100 Subject: [PATCH] Check for float register width exactly for risc-v frontend --- .../riscv/tablegen/cpp-compiler/cpp-gen.odin | 3 +++ .../isa/x86/tablegen/cpp-compiler/cpp-gen.odin | 3 +++ src/asm_tables_amd64.cpp | 3 +++ src/asm_tables_riscv.cpp | 3 +++ src/check_asm.cpp | 17 +++++++++++++++-- 5 files changed, 27 insertions(+), 2 deletions(-) diff --git a/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin b/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin index 73c8d6874..928455eba 100644 --- a/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin +++ b/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin @@ -551,6 +551,9 @@ main :: proc() { bool integer_reg_width_is_exact() const { return false; } + bool float_reg_width_is_exact() const { + return false; + } """) strings.write_string(&sb, "\n\n") diff --git a/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin b/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin index edc0ba60d..002c2d1b5 100644 --- a/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin +++ b/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin @@ -553,6 +553,9 @@ main :: proc() { bool integer_reg_width_is_exact() const { return true; } + bool float_reg_width_is_exact() const { + return true; + } """) strings.write_string(&sb, "\n\n") diff --git a/src/asm_tables_amd64.cpp b/src/asm_tables_amd64.cpp index 2485a7bfc..ce8ce4f6c 100644 --- a/src/asm_tables_amd64.cpp +++ b/src/asm_tables_amd64.cpp @@ -581,6 +581,9 @@ struct Asm_amd64 { bool integer_reg_width_is_exact() const { return true; } + bool float_reg_width_is_exact() const { + return true; + } AsmOperandKind kind_from_operand_type(OperandType type) const { switch (type) { diff --git a/src/asm_tables_riscv.cpp b/src/asm_tables_riscv.cpp index b861d1389..3a4305d29 100644 --- a/src/asm_tables_riscv.cpp +++ b/src/asm_tables_riscv.cpp @@ -521,6 +521,9 @@ struct Asm_riscv { bool integer_reg_width_is_exact() const { return false; } + bool float_reg_width_is_exact() const { + return false; + } AsmOperandKind kind_from_operand_type(OperandType type) const { switch (type) { diff --git a/src/check_asm.cpp b/src/check_asm.cpp index 6aed94084..a2263b6f6 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -312,11 +312,22 @@ gb_internal bool check_asm_operand_size_class(AsmCtx *asm_ctx, typename AsmCtx:: // Width check. if (want_w != 0 && got_w != 0) { if (want_class == AsmRegClass_Vector && !is_memory) { + // A scalar float uses only the low lane, so it may be narrower than the + // slot; a #simd vector must match the vector width exactly. bool width_ok = (got_class == AsmRegClass_Float) ? (got_w <= want_w) : (got_w == want_w); if (!width_ok) { if (mismatch_) *mismatch_ = AsmMismatch_Size; return false; } + } else if (want_class == AsmRegClass_Float && + got_class == AsmRegClass_Float && !is_memory && + !asm_ctx->float_reg_width_is_exact()) { + // NOTE(bill): architectures such as RISC-V have registers which are + // always the architecture width + if (got_w > want_w) { + if (mismatch_) *mismatch_ = AsmMismatch_Size; + return false; + } } else if (want_class == AsmRegClass_Integer && !is_memory && !asm_ctx->integer_reg_width_is_exact()) { // NOTE(bill): architectures such as RISC-V have registers which are @@ -1419,8 +1430,10 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm error(operands[i].expr, "'%.*s' operand-%td: a floating-point constant cannot be used as an immediate", LIT(name), i); } else if (m == AsmMismatch_Size && want_bits[i] && got_bits[i]) { - error(operands[i].expr, "'%.*s' operand-%td has the wrong size: expected a %u-bit operand, got %u-bit", - LIT(name), i, cast(unsigned)want_bits[i], cast(unsigned)got_bits[i]); + error(operands[i].expr, "'%.*s' operand-%td has the wrong size: expected a %u-bit %.*s operand, got %u-bit", + LIT(name), i, + cast(unsigned)want_bits[i], LIT(asm_reg_class_strings[dst_reg_class]), + cast(unsigned)got_bits[i]); } else if (m == AsmMismatch_Class) { error(operands[i].expr, "'%.*s' operand-%td is in the wrong register class, expected %d-bit %.*s %.*s, got %d-bit %.*s %.*s", LIT(name), i,