diff --git a/base/runtime/procs_windows_amd64.odin b/base/runtime/procs_windows_amd64.odin index 18322e38f..00b1ffc05 100644 --- a/base/runtime/procs_windows_amd64.odin +++ b/base/runtime/procs_windows_amd64.odin @@ -30,7 +30,7 @@ when ODIN_NO_CRT { @(export, link_name="__chkstk", private="file") __chkstk :: proc "naked" () { - internal :: asm() { + asm() { // Allocate 16 bytes to store values of r10 and r11 sub %rsp, 0x10 mov [%rsp], %r10 @@ -64,9 +64,7 @@ when ODIN_NO_CRT { mov %r11, [%rsp + 0x8] add %rsp, 0x10 ret - } - - internal() + }() } // @(require) // foreign import crt_lib "procs_windows_amd64.asm" diff --git a/src/check_asm.cpp b/src/check_asm.cpp index 1b1cc4bd9..4443fc8a7 100644 --- a/src/check_asm.cpp +++ b/src/check_asm.cpp @@ -1681,4 +1681,12 @@ gb_internal void check_asm_template(AsmCtx *asm_ctx, CheckerContext *ctx, Entity if (previous_prefix != 0) { error(previous_prefix_instr, "A prefix must be immediately followed by an instruction, but the template ended"); } +} + +gb_internal void check_asm_template_from_entity(CheckerContext *c, Entity *e, DeclInfo *d) { + if (build_context.metrics.arch == TargetArch_amd64) { + check_asm_template(&g_asm_amd64, c, e, d); + } else { + error(e->token, "asm templates are not currently supported for this target"); + } } \ No newline at end of file diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 72b4a5892..68553c25f 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -2202,11 +2202,7 @@ gb_internal void check_entity_decl(CheckerContext *ctx, Entity *e, DeclInfo *d, break; case Entity_AsmTemplate: - if (build_context.metrics.arch == TargetArch_amd64) { - check_asm_template(&g_asm_amd64, &c, e, d); - } else { - error(e->token, "asm templates are not currently supported for this target"); - } + check_asm_template_from_entity(&c, e, d); break; } diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 1bc79a10a..9c04ee362 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -12432,9 +12432,18 @@ gb_internal ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast return kind; case_end; - case_ast_node(asm_template, AsmTemplate, node); - error(node, "Illegal use of an asm template outside of a named constant value declaration"); - o->mode = Addressing_Invalid; + case_ast_node(at, AsmTemplate, node); + Token token = at->token; + DeclInfo *d = make_decl_info(c->scope, c->decl); + Entity *e = alloc_entity_asm_template(d->scope, token, nullptr, node); + d->init_expr = node; + at->anonymous_entity = e; + + check_asm_template_from_entity(c, e, d); + + o->mode = Addressing_Value; + o->type = e->type; + o->expr = node; case_end; case_ast_node(i, Implicit, node); diff --git a/src/checker.cpp b/src/checker.cpp index d6ca0b350..25bbc0f56 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -1837,6 +1837,9 @@ retry:; case_ast_node(label, AsmLabelDecl, expr); return entity_of_node(label->name); case_end; + case_ast_node(at, AsmTemplate, expr); + return at->anonymous_entity; + case_end; } return nullptr; } diff --git a/src/checker.hpp b/src/checker.hpp index 1a53018e3..bdfd2c9c3 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -928,3 +928,5 @@ gb_internal GenTypesData *ensure_polymorphic_record_entity_has_gen_types(Checker gb_internal void init_map_internal_types(Type *type); + +gb_internal void check_asm_template_from_entity(CheckerContext *c, Entity *e, DeclInfo *d); diff --git a/src/parser.cpp b/src/parser.cpp index 543e89d0e..24e16102a 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -528,6 +528,7 @@ gb_internal Ast *clone_ast(Ast *node, AstFile *f) { n->AsmTemplate.specs = clone_ast_array(n->AsmTemplate.specs, f); n->AsmTemplate.clobbers = clone_ast_array(n->AsmTemplate.clobbers, f); n->AsmTemplate.instructions = clone_ast_array(n->AsmTemplate.instructions, f); + n->AsmTemplate.anonymous_entity = nullptr; break; case Ast_AsmRegister: break; diff --git a/src/parser.hpp b/src/parser.hpp index 2dfb8be21..4779e09a8 100644 --- a/src/parser.hpp +++ b/src/parser.hpp @@ -481,6 +481,7 @@ struct AstSplitArgs { Slice clobbers; \ Slice instructions; \ Token end; \ + Entity * anonymous_entity; \ }) \ AST_KIND(AsmRegister, "asm register", struct { \ Token token; \