diff options
| author | Commeownist <commeownist@yandex.ru> | 2021-09-26 16:30:45 +0300 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-26 09:30:45 -0400 |
| commit | 4e7e822f39fca4ccf146a71dbb1098b76ecea1af (patch) | |
| tree | d6a43082547ff9d929199b2715a606dda28dcaf3 /src | |
| parent | 0f4b616a08eda85247e6123120b8cba01dc4383b (diff) | |
| download | rust-4e7e822f39fca4ccf146a71dbb1098b76ecea1af.tar.gz rust-4e7e822f39fca4ccf146a71dbb1098b76ecea1af.zip | |
Impove handling of registers in inline asm (#82)
* Correctly handle st(0) register in the clobbers list * Gate the clobbers based on enabled target features
Diffstat (limited to 'src')
| -rw-r--r-- | src/asm.rs | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/asm.rs b/src/asm.rs index a684c34b644..3b77097e9ad 100644 --- a/src/asm.rs +++ b/src/asm.rs @@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods, use rustc_hir::LlvmInlineAsmInner; use rustc_middle::{bug, ty::Instance}; -use rustc_span::Span; +use rustc_span::{Span, Symbol}; use rustc_target::asm::*; use std::borrow::Cow; @@ -173,7 +173,20 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> { continue }, (Register(reg_name), None) => { - clobbers.push(reg_name); + // `clobber_abi` can add lots of clobbers that are not supported by the target, + // such as AVX-512 registers, so we just ignore unsupported registers + let is_target_supported = reg.reg_class().supported_types(asm_arch).iter() + .any(|&(_, feature)| { + if let Some(feature) = feature { + self.tcx.sess.target_features.contains(&Symbol::intern(feature)) + } else { + true // Register class is unconditionally supported + } + }); + + if is_target_supported && !clobbers.contains(®_name) { + clobbers.push(reg_name); + } continue } }; @@ -526,16 +539,20 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister { let constraint = match reg { // For vector registers LLVM wants the register name to match the type size. InlineAsmRegOrRegClass::Reg(reg) => { - // TODO(antoyo): add support for vector register. - match reg.name() { - "ax" => "a", - "bx" => "b", - "cx" => "c", - "dx" => "d", - "si" => "S", - "di" => "D", - // For registers like r11, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 - name => return ConstraintOrRegister::Register(name), + match reg { + InlineAsmReg::X86(_) => { + // TODO(antoyo): add support for vector register. + // + // // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119 + return ConstraintOrRegister::Register(match reg.name() { + // Some of registers' names does not map 1-1 from rust to gcc + "st(0)" => "st", + + name => name, + }); + } + + _ => unimplemented!(), } }, InlineAsmRegOrRegClass::RegClass(reg) => match reg { |
