Skip to content

Commit 4f74376

Browse files
committed
rollup merge of #23466: woehr/master
This fixes a bug in LLVM IR generation for in-line assembly where Rust would always use the host clobbers instead of target clobbers. I also took this opportunity to clean/simplify the ```trans_inline_asm``` function. This is my first Rust pull request; please let me know if I'm missing anything.
2 parents d3fbc14 + b92fee9 commit 4f74376

File tree

1 file changed

+25
-47
lines changed
  • src/librustc_trans/trans

1 file changed

+25
-47
lines changed

src/librustc_trans/trans/asm.rs

Lines changed: 25 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -76,43 +76,33 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
7676
// no failure occurred preparing operands, no need to cleanup
7777
fcx.pop_custom_cleanup_scope(temp_scope);
7878

79-
let mut constraints = constraints.iter()
80-
.map(|s| s.to_string())
81-
.chain(ext_constraints.into_iter())
82-
.collect::<Vec<String>>()
83-
.connect(",");
84-
85-
let mut clobbers = ia.clobbers.iter()
86-
.map(|s| format!("~{{{}}}", &s))
87-
.collect::<Vec<String>>()
88-
.connect(",");
89-
let more_clobbers = get_clobbers();
90-
if !more_clobbers.is_empty() {
91-
if !clobbers.is_empty() {
92-
clobbers.push(',');
93-
}
94-
clobbers.push_str(&more_clobbers[..]);
95-
}
96-
97-
// Add the clobbers to our constraints list
98-
if clobbers.len() != 0 && constraints.len() != 0 {
99-
constraints.push(',');
100-
constraints.push_str(&clobbers[..]);
101-
} else {
102-
constraints.push_str(&clobbers[..]);
103-
}
79+
let clobbers = ia.clobbers.iter()
80+
.map(|s| format!("~{{{}}}", &s));
81+
82+
// Default per-arch clobbers
83+
// Basically what clang does
84+
let arch_clobbers = match bcx.sess().target.target.arch.as_slice() {
85+
"x86" | "x86_64" => vec!("~{dirflag}", "~{fpsr}", "~{flags}"),
86+
_ => Vec::new()
87+
};
10488

105-
debug!("Asm Constraints: {}", &constraints[..]);
89+
let all_constraints= constraints.iter()
90+
.map(|s| s.to_string())
91+
.chain(ext_constraints.into_iter())
92+
.chain(clobbers)
93+
.chain(arch_clobbers.iter()
94+
.map(|s| s.to_string()))
95+
.collect::<Vec<String>>()
96+
.connect(",");
10697

107-
let num_outputs = outputs.len();
98+
debug!("Asm Constraints: {}", &all_constraints[..]);
10899

109100
// Depending on how many outputs we have, the return type is different
110-
let output_type = if num_outputs == 0 {
111-
Type::void(bcx.ccx())
112-
} else if num_outputs == 1 {
113-
output_types[0]
114-
} else {
115-
Type::struct_(bcx.ccx(), &output_types[..], false)
101+
let num_outputs = outputs.len();
102+
let output_type = match num_outputs {
103+
0 => Type::void(bcx.ccx()),
104+
1 => output_types[0],
105+
_ => Type::struct_(bcx.ccx(), &output_types[..], false)
116106
};
117107

118108
let dialect = match ia.dialect {
@@ -121,10 +111,10 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
121111
};
122112

123113
let asm = CString::new(ia.asm.as_bytes()).unwrap();
124-
let constraints = CString::new(constraints).unwrap();
114+
let constraint_cstr = CString::new(all_constraints).unwrap();
125115
let r = InlineAsmCall(bcx,
126116
asm.as_ptr(),
127-
constraints.as_ptr(),
117+
constraint_cstr.as_ptr(),
128118
&inputs,
129119
output_type,
130120
ia.volatile,
@@ -158,15 +148,3 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
158148

159149
}
160150

161-
// Default per-arch clobbers
162-
// Basically what clang does
163-
164-
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
165-
fn get_clobbers() -> String {
166-
"".to_string()
167-
}
168-
169-
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
170-
fn get_clobbers() -> String {
171-
"~{dirflag},~{fpsr},~{flags}".to_string()
172-
}

0 commit comments

Comments
 (0)