mirror of
https://github.com/odin-lang/Odin.git
synced 2026-08-23 13:31:35 +00:00
Allow for inlineable asm calls
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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; \
|
||||
|
||||
Reference in New Issue
Block a user