diff options
| author | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-05-13 22:17:43 +0000 |
| commit | 17f30e5451f581d753899d2f628e5be354df33cd (patch) | |
| tree | 58252137260855f9c5791b84bda1dcdb4d90407b /compiler/rustc_codegen_llvm/src/asm.rs | |
| parent | 6d395a1c2946c79966490f5b1e6e619d3a713e6b (diff) | |
| parent | a7ed6a5196996f00dd78a391a44af51ee8088058 (diff) | |
| download | rust-17f30e5451f581d753899d2f628e5be354df33cd.tar.gz rust-17f30e5451f581d753899d2f628e5be354df33cd.zip | |
Auto merge of #84107 - Amanieu:global_asm2, r=nagisa
Add support for const operands and options to global_asm! On x86, the default syntax is also switched to Intel to match asm!. Currently `global_asm!` only supports `const` operands and the `att_syntax` option. In the future, `sym` operands will also be supported. However there is no plan to support any of the other operand types or options since they don't make sense in the context of `global_asm!`. r? `@nagisa`
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/asm.rs')
| -rw-r--r-- | compiler/rustc_codegen_llvm/src/asm.rs | 45 |
1 files changed, 42 insertions, 3 deletions
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs index ea08052a9d0..a571418c1f5 100644 --- a/compiler/rustc_codegen_llvm/src/asm.rs +++ b/compiler/rustc_codegen_llvm/src/asm.rs @@ -356,10 +356,49 @@ impl AsmBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> { } impl AsmMethods for CodegenCx<'ll, 'tcx> { - fn codegen_global_asm(&self, ga: &hir::GlobalAsm) { - let asm = ga.asm.as_str(); + fn codegen_global_asm( + &self, + template: &[InlineAsmTemplatePiece], + operands: &[GlobalAsmOperandRef], + options: InlineAsmOptions, + _line_spans: &[Span], + ) { + let asm_arch = self.tcx.sess.asm_arch.unwrap(); + + // Default to Intel syntax on x86 + let intel_syntax = matches!(asm_arch, InlineAsmArch::X86 | InlineAsmArch::X86_64) + && !options.contains(InlineAsmOptions::ATT_SYNTAX); + + // Build the template string + let mut template_str = String::new(); + if intel_syntax { + template_str.push_str(".intel_syntax\n"); + } + for piece in template { + match *piece { + InlineAsmTemplatePiece::String(ref s) => template_str.push_str(s), + InlineAsmTemplatePiece::Placeholder { operand_idx, modifier: _, span: _ } => { + match operands[operand_idx] { + GlobalAsmOperandRef::Const { ref string } => { + // Const operands get injected directly into the + // template. Note that we don't need to escape $ + // here unlike normal inline assembly. + template_str.push_str(string); + } + } + } + } + } + if intel_syntax { + template_str.push_str("\n.att_syntax\n"); + } + unsafe { - llvm::LLVMRustAppendModuleInlineAsm(self.llmod, asm.as_ptr().cast(), asm.len()); + llvm::LLVMRustAppendModuleInlineAsm( + self.llmod, + template_str.as_ptr().cast(), + template_str.len(), + ); } } } |
