]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc_codegen_llvm/asm.rs
Auto merge of #61300 - indygreg:upgrade-cross-make, r=sanxiyn
[rust.git] / src / librustc_codegen_llvm / asm.rs
index 4427308f4155d303753c13fcd7dd3207b2d6b300..100a896ea0c7d703a6312dbc6636cdad98707fcb 100644 (file)
@@ -10,7 +10,7 @@
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::mir::operand::OperandValue;
 
-use std::ffi::CString;
+use std::ffi::{CStr, CString};
 use libc::{c_uint, c_char};
 
 
@@ -73,7 +73,8 @@ fn codegen_inline_asm(
 
         let asm = CString::new(ia.asm.as_str().as_bytes()).unwrap();
         let constraint_cstr = CString::new(all_constraints).unwrap();
-        let r = self.inline_asm_call(
+        let r = inline_asm_call(
+            self,
             &asm,
             &constraint_cstr,
             &inputs,
@@ -119,3 +120,46 @@ fn codegen_global_asm(&self, ga: &hir::GlobalAsm) {
         }
     }
 }
+
+fn inline_asm_call(
+    bx: &mut Builder<'a, 'll, 'tcx>,
+    asm: &CStr,
+    cons: &CStr,
+    inputs: &[&'ll Value],
+    output: &'ll llvm::Type,
+    volatile: bool,
+    alignstack: bool,
+    dia: ::syntax::ast::AsmDialect,
+) -> Option<&'ll Value> {
+    let volatile = if volatile { llvm::True }
+                    else        { llvm::False };
+    let alignstack = if alignstack { llvm::True }
+                        else          { llvm::False };
+
+    let argtys = inputs.iter().map(|v| {
+        debug!("Asm Input Type: {:?}", *v);
+        bx.cx.val_ty(*v)
+    }).collect::<Vec<_>>();
+
+    debug!("Asm Output Type: {:?}", output);
+    let fty = bx.cx.type_func(&argtys[..], output);
+    unsafe {
+        // Ask LLVM to verify that the constraints are well-formed.
+        let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr());
+        debug!("Constraint verification result: {:?}", constraints_ok);
+        if constraints_ok {
+            let v = llvm::LLVMRustInlineAsm(
+                fty,
+                asm.as_ptr(),
+                cons.as_ptr(),
+                volatile,
+                alignstack,
+                llvm::AsmDialect::from_generic(dia),
+            );
+            Some(bx.call(v, inputs, None))
+        } else {
+            // LLVM has detected an issue with our constraints, bail out
+            None
+        }
+    }
+}