From db41921a16766ccf10048329eda0d4426875bb1e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Wed, 12 Aug 2026 10:20:11 +0100 Subject: [PATCH] Mock out `p0: u64 = %rax, p0b: u8 = p0` --- src/check_asm.cpp | 66 ++++++++++++++++++++++++++++++++++++----------- src/parser.cpp | 10 ++++++- 2 files changed, 60 insertions(+), 16 deletions(-) diff --git a/src/check_asm.cpp b/src/check_asm.cpp index 089afb05a..c4aee9b38 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -411,24 +411,37 @@ gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice GB_ASSERT(spec->name->kind == Ast_Ident); Entity *input = scope_lookup(scope, spec->name->Ident.interned, spec->name->Ident.hash); + Entity *other_scratch = nullptr; String pin = {}; if (spec->value != nullptr) { - if (spec->value->kind != Ast_AsmRegister) { - gbString s = expr_to_string(spec->value); - error(spec->value, "Expected an asm register, got %s", s); - gb_string_free(s); - continue; - } + if (spec->value->kind == Ast_Ident) { + other_scratch = scope_lookup(scope, spec->value->Ident.interned, spec->value->Ident.hash); + if (other_scratch) { + auto group = check_asm_find_group(other_scratch, *asm_template_entity_decls, nullptr); + if (!group) { + error(spec->value, "This must be another parameter, got %.*s", LIT(other_scratch->token.string)); + } + } else { + error(spec->value, "Undefined parameter declaration '%.*s'", LIT(spec->value->Ident.token.string)); + } + } else { + if (spec->value->kind != Ast_AsmRegister) { + gbString s = expr_to_string(spec->value); + error(spec->value, "Expected an asm register or scratch parameter, got %s", s); + gb_string_free(s); + continue; + } - ast_node(reg, AsmRegister, spec->value); - pin = reg->name.string; - if (pin == "any") { - pin = {}; - } - if (pin.len != 0) { - if (string_set_update(&pin_set, pin)) { - error(spec->value, "Pinned register %%%.*s has already been assigned", LIT(pin)); + ast_node(reg, AsmRegister, spec->value); + pin = reg->name.string; + if (pin == "any") { + pin = {}; + } + if (pin.len != 0) { + if (string_set_update(&pin_set, pin)) { + error(spec->value, "Pinned register %%%.*s has already been assigned", LIT(pin)); + } } } } @@ -454,6 +467,20 @@ gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice ed.param_group = AsmTemplateEntityDeclParamGroup_Scratch; ed.total_index = cast(i32)asm_template_entity_decls->count; ed.pin = pin; + + if (other_scratch != nullptr) { + // TODO(bill): subsetting parameters + // p0: u64 = %rax, + // p0b: u8 = p0, + // + // or + // + // p0: u64, // implied = %any + // p0b: u8 = p0, // the 8-bit subsection of the same register, if possible + GB_ASSERT(spec->value != nullptr); + error(spec->value, "Another parameter must be assigned/paired with a scratch parameter declaration"); + } + array_add(asm_template_entity_decls, ed); } else { TokenPos pos = found->token.pos; @@ -478,8 +505,12 @@ gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice } else { error(spec_, "Asm register has already been pinned"); } - } + if (other_scratch != nullptr) { + GB_ASSERT(spec->value != nullptr); + error(spec->value, "Another parameter must be assigned/paired with a scratch parameter declaration"); + } + } } else { GB_ASSERT(spec->tied_name->kind == Ast_Ident); @@ -522,6 +553,11 @@ gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice i->pin = pin; o->pin = pin; + + if (other_scratch != nullptr) { + GB_ASSERT(spec->value != nullptr); + error(spec->value, "Another parameter must be assigned/paired with a scratch parameter declaration, not a tie"); + } } } } diff --git a/src/parser.cpp b/src/parser.cpp index c06c99845..c8b1b0ace 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -2642,7 +2642,15 @@ gb_internal Ast *parse_asm_template(AstFile *f) { type = parse_type(f); } if (allow_token(f, Token_Eq)) { - value = parse_asm_register(f); + if (f->curr_token.kind == Token_Ident) { + value = parse_ident(f); + } else if (f->curr_token.kind == Token_Mod) { + value = parse_asm_register(f); + } else { + error(f->curr_token, "Expected a register or scratch parameter"); + Ast *dummy = parse_expr(f, true); + gb_unused(dummy); + } } if (tied_name != nullptr) {