From 344e8afa362719cf8c954db8886c8c3ee3a81ca4 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 17 Aug 2026 12:10:08 +0100 Subject: [PATCH] `#clobber cc` -> `#clobber flags` --- .../x86/tablegen/cpp-compiler/cpp-gen.odin | 8 ++--- src/asm_tables_amd64.cpp | 8 ++--- src/check_asm.cpp | 32 ++++++++++++------- src/entity.cpp | 4 +-- src/llvm_backend_asm.cpp | 4 +-- src/parser.cpp | 6 ++++ src/parser.hpp | 1 + 7 files changed, 40 insertions(+), 23 deletions(-) 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 2d5386edc..4d5228d92 100644 --- a/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin +++ b/core/rexcode/isa/x86/tablegen/cpp-compiler/cpp-gen.odin @@ -231,10 +231,10 @@ main :: proc() { bool reads_mem; SideEffectFlags side_effects; - bool implies_clobber_cc() { - u16 const CC_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| - ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; - return ((flags_wr | flags_undef) & CC_MASK) != 0; + bool implies_clobber_flags() { + u16 const FLAGS_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| + ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; + return ((flags_wr | flags_undef) & FLAGS_MASK) != 0; } bool implies_clobber_memory() { return writes_mem || reads_mem || diff --git a/src/asm_tables_amd64.cpp b/src/asm_tables_amd64.cpp index be0425c77..fd218e0e9 100644 --- a/src/asm_tables_amd64.cpp +++ b/src/asm_tables_amd64.cpp @@ -231,10 +231,10 @@ struct Asm_amd64 { bool reads_mem; SideEffectFlags side_effects; - bool implies_clobber_cc() { - u16 const CC_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| - ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; - return ((flags_wr | flags_undef) & CC_MASK) != 0; + bool implies_clobber_flags() { + u16 const FLAGS_MASK = ClobberFlag_CF|ClobberFlag_PF|ClobberFlag_AF| + ClobberFlag_ZF|ClobberFlag_SF|ClobberFlag_OF; + return ((flags_wr | flags_undef) & FLAGS_MASK) != 0; } bool implies_clobber_memory() { return writes_mem || reads_mem || diff --git a/src/check_asm.cpp b/src/check_asm.cpp index a794fa506..6e4914961 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -643,6 +643,13 @@ gb_internal void check_asm_specs(AsmCtx *asm_ctx, CheckerContext *ctx, Scope *sc template gb_internal bool check_register(AsmCtx *asm_ctx, Operand *operand, AstAsmRegister *asm_reg) { String name = asm_reg->name.string; + if (asm_reg->flag.kind == Token_Ident) { + // TODO(bill): has flags + if (name != "cc") { + + } + } + auto r = asm_ctx->register_lookup(name); if (r) { operand->mode = Addressing_Value; @@ -880,9 +887,9 @@ gb_internal void check_mnemonic(AsmCtx *asm_ctx, CheckerContext *ctx, Entity *tm // Handle clobbering from mnemonic auto clobber = asm_ctx->clobber(mnemonic); - tmpl_entity->AsmTemplate.clobber_cc |= clobber.implies_clobber_cc(); - tmpl_entity->AsmTemplate.clobber_memory |= clobber.implies_clobber_memory(); - tmpl_entity->AsmTemplate.is_volatile |= clobber.implies_side_effects(); + tmpl_entity->AsmTemplate.clobber_flags |= clobber.implies_clobber_flags(); + tmpl_entity->AsmTemplate.clobber_memory |= clobber.implies_clobber_memory(); + tmpl_entity->AsmTemplate.is_volatile |= clobber.implies_side_effects(); return; } @@ -1290,7 +1297,7 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity check_asm_specs(asm_ctx, ctx, ate->param_scope, at->specs, &ate->decls); { // check clobbers - bool clobber_cc = false; + bool clobber_flags = false; bool clobber_memory = false; for (Ast *clobber_ : at->clobbers) { @@ -1316,6 +1323,9 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity switch (clobber->value->kind) { case_ast_node(asm_reg, AsmRegister, clobber->value) String reg = asm_reg->name.string; + if (asm_reg->flag.string != "") { + error(asm_reg->flag, "#clobber on specific flags is not allowed"); + } Operand operand = {}; if (check_register(asm_ctx, &operand, asm_reg)) { if (string_set_update(clobber_registers_set, reg)) { @@ -1325,27 +1335,27 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity case_end; case_ast_node(ident, Ident, clobber->value); String str = ident->token.string; - if (str == "cc") { - if (clobber_cc) { - error(clobber->value, "#clobber cc has already been defined"); + if (str == "flags") { + if (clobber_flags) { + error(clobber->value, "#clobber flags has already been defined"); } - clobber_cc = true; + clobber_flags = true; } else if (str == "memory") { if (clobber_memory) { error(clobber->value, "#clobber memory has already been defined"); } clobber_memory = true; } else { - error(clobber->value, "Expected either a register, 'cc', or 'memory' for a '#clobber' specification, got '%.*s'", LIT(str)); + error(clobber->value, "Expected either a register, 'flags', or 'memory' for a '#clobber' specification, got '%.*s'", LIT(str)); } case_end; default: - error(clobber->value, "Expected either a register, 'cc', or 'memory' for a '#clobber' specification"); + error(clobber->value, "Expected either a register, 'flags', or 'memory' for a '#clobber' specification"); break; } } - entity->AsmTemplate.clobber_cc = clobber_cc; + entity->AsmTemplate.clobber_flags = clobber_flags; entity->AsmTemplate.clobber_memory = clobber_memory; entity->AsmTemplate.is_volatile = is_volatile; entity->AsmTemplate.is_align_stack = is_align_stack; diff --git a/src/entity.cpp b/src/entity.cpp index bfe4c42c9..3ec3860e2 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -344,8 +344,8 @@ struct Entity { bool is_volatile; bool is_align_stack; - bool clobber_cc; - bool clobber_memory; + bool clobber_flags; + bool clobber_memory; StringSet clobber_registers_set; Scope *param_scope; diff --git a/src/llvm_backend_asm.cpp b/src/llvm_backend_asm.cpp index 0fb03f13a..1e36459c8 100644 --- a/src/llvm_backend_asm.cpp +++ b/src/llvm_backend_asm.cpp @@ -451,8 +451,8 @@ struct lbAsmGenerate_amd64 : lbAsmGenerate { string_set_update(&emitted_reg_clobbers, reg); } - // Template-level clobbers derived from #clobber cc / #clobber memory. - if (tmpl_entity->AsmTemplate.clobber_cc) { + // Template-level clobbers derived from #clobber flags / #clobber memory. + if (tmpl_entity->AsmTemplate.clobber_flags) { sep(); if (build_context.metrics.arch == TargetArch_amd64) { raw("~{flags}"); // x86 EFLAGS condition codes diff --git a/src/parser.cpp b/src/parser.cpp index 6742f44f0..518beb2f0 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2437,6 +2437,12 @@ gb_internal Ast *parse_asm_register(AstFile *f) { Ast *reg = alloc_ast_node(f, Ast_AsmRegister); reg->AsmRegister.token = token; reg->AsmRegister.name = name; + if (allow_token(f, Token_Period)) { + Token flag = expect_token_after(f, Token_Ident, "register name and period for the flag"); + if (flag.kind == Token_Ident) { + reg->AsmRegister.flag = flag; + } + } return reg; } gb_internal Ast *parse_asm_operand(AstFile *f, bool allow_memory_operand) { diff --git a/src/parser.hpp b/src/parser.hpp index a8b69593e..cbbf84867 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -479,6 +479,7 @@ struct AstSplitArgs { AST_KIND(AsmRegister, "asm register", struct { \ Token token; \ Token name; \ + Token flag; \ }) \ AST_KIND(AsmSpec, "asm specification", struct { \ Ast *name; \