Allow for inlineable asm calls

This commit is contained in:
gingerBill
2026-08-18 14:57:34 +01:00
parent 0bc9e60725
commit a86e523053
8 changed files with 30 additions and 12 deletions

View File

@@ -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"

View File

@@ -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");
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;

View File

@@ -481,6 +481,7 @@ struct AstSplitArgs {
Slice<Ast *> clobbers; \
Slice<Ast *> instructions; \
Token end; \
Entity * anonymous_entity; \
}) \
AST_KIND(AsmRegister, "asm register", struct { \
Token token; \