(
bx: &mut Builder<'a, 'll, 'tcx>,
asm: &str,
cons: &str,
inputs: &[&'ll Value],
output: &'ll llvm::Type,
volatile: bool,
alignstack: bool,
dia: LlvmAsmDialect,
lin
| 360 | |
| 361 | #[allow(clippy::too_many_arguments)] |
| 362 | pub(crate) fn inline_asm_call<'a, 'll, 'tcx>( |
| 363 | bx: &mut Builder<'a, 'll, 'tcx>, |
| 364 | asm: &str, |
| 365 | cons: &str, |
| 366 | inputs: &[&'ll Value], |
| 367 | output: &'ll llvm::Type, |
| 368 | volatile: bool, |
| 369 | alignstack: bool, |
| 370 | dia: LlvmAsmDialect, |
| 371 | line_spans: &[Span], |
| 372 | ) -> Option<&'ll Value> { |
| 373 | let volatile = if volatile { llvm::True } else { llvm::False }; |
| 374 | let alignstack = if alignstack { llvm::True } else { llvm::False }; |
| 375 | |
| 376 | let argtys = inputs.iter().map(|v| bx.cx.val_ty(*v)).collect::<Vec<_>>(); |
| 377 | |
| 378 | let fty = bx.cx.type_func(&argtys[..], output); |
| 379 | unsafe { |
| 380 | // Ask LLVM to verify that the constraints are well-formed. |
| 381 | let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons.as_ptr().cast(), cons.len()); |
| 382 | if constraints_ok { |
| 383 | let v = llvm::LLVMRustInlineAsm( |
| 384 | fty, |
| 385 | asm.as_ptr().cast(), |
| 386 | asm.len(), |
| 387 | cons.as_ptr().cast(), |
| 388 | cons.len(), |
| 389 | volatile, |
| 390 | alignstack, |
| 391 | llvm::AsmDialect::from_generic(dia), |
| 392 | ); |
| 393 | let call = bx.call(fty, v, inputs, None); |
| 394 | |
| 395 | // Store mark in a metadata node so we can map LLVM errors |
| 396 | // back to source locations. See #17552. |
| 397 | let key = "srcloc"; |
| 398 | let kind = llvm::LLVMGetMDKindIDInContext( |
| 399 | bx.llcx, |
| 400 | key.as_ptr() as *const c_char, |
| 401 | key.len() as c_uint, |
| 402 | ); |
| 403 | |
| 404 | let mut srcloc = vec![]; |
| 405 | srcloc.extend( |
| 406 | line_spans |
| 407 | .iter() |
| 408 | .map(|span| bx.const_i32(span.lo().to_u32() as i32)), |
| 409 | ); |
| 410 | let md = llvm::LLVMMDNodeInContext(bx.llcx, srcloc.as_ptr(), srcloc.len() as u32); |
| 411 | llvm::LLVMSetMetadata(call, kind, md); |
| 412 | |
| 413 | Some(call) |
| 414 | } else { |
| 415 | // LLVM has detected an issue with our constraints, bail out |
| 416 | None |
| 417 | } |
| 418 | } |
| 419 | } |
no test coverage detected