Fix a bug in inline assembly codegen where host clobbers were always used regardless of target
This commit is contained in:
parent
883551b1d7
commit
a7f00cbc0c
1 changed files with 25 additions and 46 deletions
|
@ -76,43 +76,34 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||||
// no failure occurred preparing operands, no need to cleanup
|
// no failure occurred preparing operands, no need to cleanup
|
||||||
fcx.pop_custom_cleanup_scope(temp_scope);
|
fcx.pop_custom_cleanup_scope(temp_scope);
|
||||||
|
|
||||||
let mut constraints = constraints.iter()
|
let clobbers = ia.clobbers.iter()
|
||||||
.map(|s| s.to_string())
|
.map(|s| format!("~{{{}}}", &s))
|
||||||
.chain(ext_constraints.into_iter())
|
.collect::<Vec<String>>();
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.connect(",");
|
|
||||||
|
|
||||||
let mut clobbers = ia.clobbers.iter()
|
// Default per-arch clobbers
|
||||||
.map(|s| format!("~{{{}}}", &s))
|
// Basically what clang does
|
||||||
.collect::<Vec<String>>()
|
let arch_clobbers = match bcx.sess().target.target.arch.as_slice() {
|
||||||
.connect(",");
|
"x86" | "x86_64" => vec!("~{dirflag}", "~{fpsr}", "~{flags}"),
|
||||||
let more_clobbers = get_clobbers();
|
_ => Vec::new()
|
||||||
if !more_clobbers.is_empty() {
|
};
|
||||||
if !clobbers.is_empty() {
|
|
||||||
clobbers.push(',');
|
|
||||||
}
|
|
||||||
clobbers.push_str(&more_clobbers[..]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the clobbers to our constraints list
|
let all_constraints= constraints.iter()
|
||||||
if clobbers.len() != 0 && constraints.len() != 0 {
|
.map(|s| s.to_string())
|
||||||
constraints.push(',');
|
.chain(ext_constraints.into_iter())
|
||||||
constraints.push_str(&clobbers[..]);
|
.chain(clobbers.into_iter())
|
||||||
} else {
|
.chain(arch_clobbers.into_iter()
|
||||||
constraints.push_str(&clobbers[..]);
|
.map(|s| s.to_string()))
|
||||||
}
|
.collect::<Vec<String>>()
|
||||||
|
.connect(",");
|
||||||
|
|
||||||
debug!("Asm Constraints: {}", &constraints[..]);
|
debug!("Asm Constraints: {}", &all_constraints[..]);
|
||||||
|
|
||||||
let num_outputs = outputs.len();
|
|
||||||
|
|
||||||
// Depending on how many outputs we have, the return type is different
|
// Depending on how many outputs we have, the return type is different
|
||||||
let output_type = if num_outputs == 0 {
|
let num_outputs = outputs.len();
|
||||||
Type::void(bcx.ccx())
|
let output_type = match num_outputs {
|
||||||
} else if num_outputs == 1 {
|
0 => Type::void(bcx.ccx()),
|
||||||
output_types[0]
|
1 => output_types[0],
|
||||||
} else {
|
_ => Type::struct_(bcx.ccx(), &output_types[..], false)
|
||||||
Type::struct_(bcx.ccx(), &output_types[..], false)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let dialect = match ia.dialect {
|
let dialect = match ia.dialect {
|
||||||
|
@ -121,10 +112,10 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||||
};
|
};
|
||||||
|
|
||||||
let asm = CString::new(ia.asm.as_bytes()).unwrap();
|
let asm = CString::new(ia.asm.as_bytes()).unwrap();
|
||||||
let constraints = CString::new(constraints).unwrap();
|
let constraint_cstr = CString::new(all_constraints).unwrap();
|
||||||
let r = InlineAsmCall(bcx,
|
let r = InlineAsmCall(bcx,
|
||||||
asm.as_ptr(),
|
asm.as_ptr(),
|
||||||
constraints.as_ptr(),
|
constraint_cstr.as_ptr(),
|
||||||
&inputs,
|
&inputs,
|
||||||
output_type,
|
output_type,
|
||||||
ia.volatile,
|
ia.volatile,
|
||||||
|
@ -158,15 +149,3 @@ pub fn trans_inline_asm<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, ia: &ast::InlineAsm)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default per-arch clobbers
|
|
||||||
// Basically what clang does
|
|
||||||
|
|
||||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
|
||||||
fn get_clobbers() -> String {
|
|
||||||
"".to_string()
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
|
||||||
fn get_clobbers() -> String {
|
|
||||||
"~{dirflag},~{fpsr},~{flags}".to_string()
|
|
||||||
}
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue