From f7f3d3f1981821b8532fc88ef46cf571b14f9142 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Tue, 25 Aug 2026 19:30:38 +0100 Subject: [PATCH] asm: reenable riscv64 --- .../riscv/tablegen/cpp-compiler/cpp-gen.odin | 33 +++++++++++++++++++ .../x86/tablegen/cpp-compiler/cpp-gen.odin | 4 +++ src/asm_tables_amd64.cpp | 4 +++ src/asm_tables_riscv.cpp | 33 +++++++++++++++++++ src/check_asm.cpp | 4 +-- 5 files changed, 76 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 c19194c3c..1eec54f16 100644 --- a/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin +++ b/core/rexcode/isa/riscv/tablegen/cpp-compiler/cpp-gen.odin @@ -128,6 +128,17 @@ main :: proc() { ClobberFlag_NX = 1<<4, // inexact }; + char const *clobber_flag_bit_name(u16 bit) { + switch (bit) { + case ClobberFlag_NV: return "nv"; + case ClobberFlag_DZ: return "dz"; + case ClobberFlag_OF: return "of"; + case ClobberFlag_UF: return "uf"; + case ClobberFlag_NX: return "nx"; + } + return "?"; + } + enum ClobberRegs : u8 { ClobberReg_RA = 1<<0, // x1, implicit link on C.JAL / C.JALR ClobberReg_SP = 1<<1, // x2, implicit base on the *SP compressed forms @@ -174,6 +185,24 @@ main :: proc() { return \"\"; } + + u16 flag_from_name(String const &name) { + static const struct {String name; ClobberFlags flag; } table[] = { + {str_lit("nv"), ClobberFlag_NV}, + {str_lit("dz"), ClobberFlag_DZ}, + {str_lit("of"), ClobberFlag_OF}, + {str_lit("uf"), ClobberFlag_UF}, + {str_lit("nx"), ClobberFlag_NX}, + }; + + for (auto const &t : table) { + if (name == t.name) { + return cast(u16)t.flag; + } + } + return 0; + } + u16 flags_from_name(String const &name) { static const struct { String name; ClobberFlags flag; } table[] = { // flags: accrued FP exception flags (fcsr[4:0]) @@ -232,6 +261,10 @@ main :: proc() { bool reads_mem; SideEffectFlags side_effects; + ClobberFlags flags_rd_call() const { + return {}; + } + bool implies_clobber_flags() const { return (flags_wr != 0); } 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 558c8cd7e..0ee411f3d 100644 --- a/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin +++ b/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin @@ -306,6 +306,10 @@ main :: proc() { bool reads_mem; SideEffectFlags side_effects; + ClobberFlags flags_rd_call() const { + return flags_rd; + } + bool implies_clobber_flags() const { u16 const FLAGS_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; diff --git a/src/asm_tables_amd64.cpp b/src/asm_tables_amd64.cpp index 657204e90..fe7fa0a0f 100644 --- a/src/asm_tables_amd64.cpp +++ b/src/asm_tables_amd64.cpp @@ -309,6 +309,10 @@ struct Asm_amd64 { bool reads_mem; SideEffectFlags side_effects; + ClobberFlags flags_rd_call() const { + return flags_rd; + } + bool implies_clobber_flags() const { u16 const FLAGS_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; diff --git a/src/asm_tables_riscv.cpp b/src/asm_tables_riscv.cpp index a118314a1..76f540513 100644 --- a/src/asm_tables_riscv.cpp +++ b/src/asm_tables_riscv.cpp @@ -76,6 +76,17 @@ struct Asm_riscv { ClobberFlag_NX = 1<<4, // inexact }; + char const *clobber_flag_bit_name(u16 bit) { + switch (bit) { + case ClobberFlag_NV: return "nv"; + case ClobberFlag_DZ: return "dz"; + case ClobberFlag_OF: return "of"; + case ClobberFlag_UF: return "uf"; + case ClobberFlag_NX: return "nx"; + } + return "?"; + } + enum ClobberRegs : u8 { ClobberReg_RA = 1<<0, // x1, implicit link on C.JAL / C.JALR ClobberReg_SP = 1<<1, // x2, implicit base on the *SP compressed forms @@ -122,6 +133,24 @@ struct Asm_riscv { return ""; } + + u16 flag_from_name(String const &name) { + static const struct {String name; ClobberFlags flag; } table[] = { + {str_lit("nv"), ClobberFlag_NV}, + {str_lit("dz"), ClobberFlag_DZ}, + {str_lit("of"), ClobberFlag_OF}, + {str_lit("uf"), ClobberFlag_UF}, + {str_lit("nx"), ClobberFlag_NX}, + }; + + for (auto const &t : table) { + if (name == t.name) { + return cast(u16)t.flag; + } + } + return 0; + } + u16 flags_from_name(String const &name) { static const struct { String name; ClobberFlags flag; } table[] = { // flags: accrued FP exception flags (fcsr[4:0]) @@ -180,6 +209,10 @@ struct Asm_riscv { bool reads_mem; SideEffectFlags side_effects; + ClobberFlags flags_rd_call() const { + return {}; + } + bool implies_clobber_flags() const { return (flags_wr != 0); } diff --git a/src/check_asm.cpp b/src/check_asm.cpp index 6256f314d..3a570692d 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -1632,7 +1632,7 @@ gb_internal bool check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm facts->gen_regs = produced | pinned_param_writes; facts->gen_flags = cast(u16)clobber.flags_wr; - facts->read_flags = cast(u16)clobber.flags_rd; + facts->read_flags = cast(u16)clobber.flags_rd_call(); // NOTE(bill): mnemonics such as `xor r, r` / `sub r, r` act as zeroing the destination // independent of its prior value: the read is architecturally dead, so it must not count as a use. @@ -2813,7 +2813,7 @@ gb_internal void check_asm_template_from_entity(CheckerContext *c, Entity *e, De if (build_context.metrics.arch == TargetArch_amd64) { check_asm_template(&g_asm_amd64, c, e, d); } else if (build_context.metrics.arch == TargetArch_riscv64) { - // check_asm_template(&g_asm_riscv, c, e, d); + check_asm_template(&g_asm_riscv, c, e, d); } else { error(e->token, "asm templates are not currently supported for this target"); }