Skip to content

Commit

Permalink
Impove handling of registers in inline asm (rust-lang#82)
Browse files Browse the repository at this point in the history
* Correctly handle st(0) register in the clobbers list
* Gate the clobbers based on enabled target features
  • Loading branch information
Commeownist authored Sep 26, 2021
1 parent 0f4b616 commit 4e7e822
Showing 1 changed file with 29 additions and 12 deletions.
41 changes: 29 additions & 12 deletions src/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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(&reg_name) {
clobbers.push(reg_name);
}
continue
}
};
Expand Down Expand Up @@ -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 {
Expand Down

0 comments on commit 4e7e822

Please sign in to comment.