diff --git a/spec/compiler/codegen/asm_spec.cr b/spec/compiler/codegen/asm_spec.cr index 2c6b0707699e..289c1455741e 100644 --- a/spec/compiler/codegen/asm_spec.cr +++ b/spec/compiler/codegen/asm_spec.cr @@ -44,5 +44,13 @@ describe "Code gen: asm" do c )).to_i.should eq(42) end + + it "codegens with intel dialect" do + run(<<-CRYSTAL).to_i.should eq(1234) + dst = uninitialized Int32 + asm("mov dword ptr [$0], 1234" :: "r"(pointerof(dst)) :: "intel") + dst + CRYSTAL + end {% end %} end diff --git a/src/compiler/crystal/codegen/asm.cr b/src/compiler/crystal/codegen/asm.cr index f0b3e2f088ab..107d63f19ecf 100644 --- a/src/compiler/crystal/codegen/asm.cr +++ b/src/compiler/crystal/codegen/asm.cr @@ -53,7 +53,7 @@ class Crystal::CodeGenVisitor fun_type = LLVM::Type.function(input_types, output_type) constraints = constraints.to_s - value = fun_type.inline_asm(node.text, constraints, node.volatile?, node.alignstack?, node.can_throw?) + value = fun_type.inline_asm(node.text, constraints, node.volatile?, node.alignstack?, node.can_throw?, node.dialect) value = LLVM::Function.from_value(value) asm_value = call LLVMTypedFunction.new(fun_type, value), input_values diff --git a/src/compiler/crystal/codegen/ast.cr b/src/compiler/crystal/codegen/ast.cr index 816958844dd9..ab4fa76d4e16 100644 --- a/src/compiler/crystal/codegen/ast.cr +++ b/src/compiler/crystal/codegen/ast.cr @@ -138,4 +138,10 @@ module Crystal found_extern end end + + class Asm + def dialect : LLVM::InlineAsmDialect + intel? ? LLVM::InlineAsmDialect::Intel : LLVM::InlineAsmDialect::ATT + end + end end diff --git a/src/llvm/enums.cr b/src/llvm/enums.cr index b8e06fb46f89..ac23fa711560 100644 --- a/src/llvm/enums.cr +++ b/src/llvm/enums.cr @@ -440,6 +440,11 @@ module LLVM LittleEndian = 1 << 28 end + enum InlineAsmDialect + ATT + Intel + end + struct Value enum Kind Argument diff --git a/src/llvm/lib_llvm/core.cr b/src/llvm/lib_llvm/core.cr index 20f10c7e6e62..c865baaa55a5 100644 --- a/src/llvm/lib_llvm/core.cr +++ b/src/llvm/lib_llvm/core.cr @@ -4,11 +4,6 @@ lib LibLLVM # NOTE: the following C enums usually have different values from their C++ # counterparts (e.g. `LLVMModuleFlagBehavior` v.s. `LLVM::Module::ModFlagBehavior`) - enum InlineAsmDialect - ATT - Intel - end - enum ModuleFlagBehavior Warning = 1 end @@ -39,9 +34,9 @@ lib LibLLVM fun print_module_to_file = LLVMPrintModuleToFile(m : ModuleRef, filename : Char*, error_message : Char**) : Bool fun print_module_to_string = LLVMPrintModuleToString(m : ModuleRef) : Char* {% if !LibLLVM::IS_LT_130 %} - fun get_inline_asm = LLVMGetInlineAsm(ty : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : InlineAsmDialect, can_throw : Bool) : ValueRef + fun get_inline_asm = LLVMGetInlineAsm(ty : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : LLVM::InlineAsmDialect, can_throw : Bool) : ValueRef {% else %} - fun get_inline_asm = LLVMGetInlineAsm(t : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : InlineAsmDialect) : ValueRef + fun get_inline_asm = LLVMGetInlineAsm(t : TypeRef, asm_string : Char*, asm_string_size : SizeT, constraints : Char*, constraints_size : SizeT, has_side_effects : Bool, is_align_stack : Bool, dialect : LLVM::InlineAsmDialect) : ValueRef {% end %} fun get_module_context = LLVMGetModuleContext(m : ModuleRef) : ContextRef diff --git a/src/llvm/type.cr b/src/llvm/type.cr index 06c36ff5796d..c391019aef83 100644 --- a/src/llvm/type.cr +++ b/src/llvm/type.cr @@ -173,7 +173,7 @@ struct LLVM::Type Value.new LibLLVM.const_array(self, (values.to_unsafe.as(LibLLVM::ValueRef*)), values.size) end - def inline_asm(asm_string, constraints, has_side_effects = false, is_align_stack = false, can_throw = false) + def inline_asm(asm_string, constraints, has_side_effects = false, is_align_stack = false, can_throw = false, dialect : InlineAsmDialect = InlineAsmDialect::ATT) value = {% if LibLLVM::IS_LT_130 %} LibLLVM.get_inline_asm( @@ -184,7 +184,7 @@ struct LLVM::Type constraints.size, (has_side_effects ? 1 : 0), (is_align_stack ? 1 : 0), - LibLLVM::InlineAsmDialect::ATT + dialect, ) {% else %} LibLLVM.get_inline_asm( @@ -195,7 +195,7 @@ struct LLVM::Type constraints.size, (has_side_effects ? 1 : 0), (is_align_stack ? 1 : 0), - LibLLVM::InlineAsmDialect::ATT, + dialect, (can_throw ? 1 : 0) ) {% end %}