From 4629754f7ced5df477eb017872ef65539db64a27 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sat, 24 Oct 2020 16:32:37 +0100 Subject: Inline asm expression (-llvm-api) See https://llvm.org/docs/LangRef.html#inline-assembler-expressions Example: ``` x := asm(i32) -> i32 { "bswap $0", "=r,r", }(123); ``` Allowed directives `#side_effect`, `#align_stack`, `#att`, `#intel` e.g. `asm() #side_effect #intel {...}` --- src/llvm_backend.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/llvm_backend.cpp') diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 65586d3a6..4abc65ab4 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -9563,6 +9563,43 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) { case_ast_node(ie, IndexExpr, expr); return lb_addr_load(p, lb_build_addr(p, expr)); case_end; + + case_ast_node(ia, InlineAsmExpr, expr); + Type *t = type_of_expr(expr); + GB_ASSERT(is_type_asm_proc(t)); + + String asm_string = {}; + String constraints_string = {}; + + TypeAndValue tav; + tav = type_and_value_of_expr(ia->asm_string); + GB_ASSERT(is_type_string(tav.type)); + GB_ASSERT(tav.value.kind == ExactValue_String); + asm_string = tav.value.value_string; + + tav = type_and_value_of_expr(ia->constraints_string); + GB_ASSERT(is_type_string(tav.type)); + GB_ASSERT(tav.value.kind == ExactValue_String); + constraints_string = tav.value.value_string; + + + LLVMInlineAsmDialect dialect = LLVMInlineAsmDialectATT; + switch (ia->dialect) { + case InlineAsmDialect_Default: dialect = LLVMInlineAsmDialectATT; break; + case InlineAsmDialect_ATT: dialect = LLVMInlineAsmDialectATT; break; + case InlineAsmDialect_Intel: dialect = LLVMInlineAsmDialectIntel; break; + default: GB_PANIC("Unhandled inline asm dialect"); break; + } + + LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, t)); + LLVMValueRef the_asm = LLVMGetInlineAsm(func_type, + cast(char *)asm_string.text, cast(size_t)asm_string.len, + cast(char *)constraints_string.text, cast(size_t)constraints_string.len, + ia->has_side_effects, ia->is_align_stack, dialect + ); + GB_ASSERT(the_asm != nullptr); + return {the_asm, t}; + case_end; } GB_PANIC("lb_build_expr: %.*s", LIT(ast_strings[expr->kind])); -- cgit v1.2.3