Skip to content

Commit 4e7e822

Browse files
author
Commeownist
authored
Impove handling of registers in inline asm (rust-lang#82)
* Correctly handle st(0) register in the clobbers list * Gate the clobbers based on enabled target features
1 parent 0f4b616 commit 4e7e822

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

Diff for: src/asm.rs

+29-12
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_codegen_ssa::traits::{AsmBuilderMethods, AsmMethods, BaseTypeMethods,
66

77
use rustc_hir::LlvmInlineAsmInner;
88
use rustc_middle::{bug, ty::Instance};
9-
use rustc_span::Span;
9+
use rustc_span::{Span, Symbol};
1010
use rustc_target::asm::*;
1111

1212
use std::borrow::Cow;
@@ -173,7 +173,20 @@ impl<'a, 'gcc, 'tcx> AsmBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
173173
continue
174174
},
175175
(Register(reg_name), None) => {
176-
clobbers.push(reg_name);
176+
// `clobber_abi` can add lots of clobbers that are not supported by the target,
177+
// such as AVX-512 registers, so we just ignore unsupported registers
178+
let is_target_supported = reg.reg_class().supported_types(asm_arch).iter()
179+
.any(|&(_, feature)| {
180+
if let Some(feature) = feature {
181+
self.tcx.sess.target_features.contains(&Symbol::intern(feature))
182+
} else {
183+
true // Register class is unconditionally supported
184+
}
185+
});
186+
187+
if is_target_supported && !clobbers.contains(&reg_name) {
188+
clobbers.push(reg_name);
189+
}
177190
continue
178191
}
179192
};
@@ -526,16 +539,20 @@ fn reg_to_gcc(reg: InlineAsmRegOrRegClass) -> ConstraintOrRegister {
526539
let constraint = match reg {
527540
// For vector registers LLVM wants the register name to match the type size.
528541
InlineAsmRegOrRegClass::Reg(reg) => {
529-
// TODO(antoyo): add support for vector register.
530-
match reg.name() {
531-
"ax" => "a",
532-
"bx" => "b",
533-
"cx" => "c",
534-
"dx" => "d",
535-
"si" => "S",
536-
"di" => "D",
537-
// For registers like r11, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
538-
name => return ConstraintOrRegister::Register(name),
542+
match reg {
543+
InlineAsmReg::X86(_) => {
544+
// TODO(antoyo): add support for vector register.
545+
//
546+
// // For explicit registers, we have to create a register variable: https://stackoverflow.com/a/31774784/389119
547+
return ConstraintOrRegister::Register(match reg.name() {
548+
// Some of registers' names does not map 1-1 from rust to gcc
549+
"st(0)" => "st",
550+
551+
name => name,
552+
});
553+
}
554+
555+
_ => unimplemented!(),
539556
}
540557
},
541558
InlineAsmRegOrRegClass::RegClass(reg) => match reg {

0 commit comments

Comments
 (0)