Add proper support for indirect output constraints in inline asm

This commit is contained in:
Amanieu d'Antras
2015-11-06 13:31:02 +00:00
parent 3e2ebaa918
commit 9d7b113b44
17 changed files with 78 additions and 39 deletions

View File

@@ -1462,7 +1462,7 @@ pub enum AsmDialect {
pub struct InlineAsm {
pub asm: InternedString,
pub asm_str_style: StrStyle,
pub outputs: Vec<(InternedString, P<Expr>, bool)>,
pub outputs: Vec<(InternedString, P<Expr>, bool, bool)>,
pub inputs: Vec<(InternedString, P<Expr>)>,
pub clobbers: Vec<InternedString>,
pub volatile: bool,

View File

@@ -125,7 +125,8 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
};
let is_rw = output.is_some();
outputs.push((output.unwrap_or(constraint), out, is_rw));
let is_indirect = constraint.contains("*");
outputs.push((output.unwrap_or(constraint), out, is_rw, is_indirect));
}
}
Inputs => {
@@ -139,9 +140,9 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
let (constraint, _str_style) = panictry!(p.parse_str());
if constraint.starts_with("=") && !constraint.contains("*") {
if constraint.starts_with("=") {
cx.span_err(p.last_span, "input operand constraint contains '='");
} else if constraint.starts_with("+") && !constraint.contains("*") {
} else if constraint.starts_with("+") {
cx.span_err(p.last_span, "input operand constraint contains '+'");
}

View File

@@ -1303,8 +1303,8 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu
inputs: inputs.move_map(|(c, input)| {
(c, folder.fold_expr(input))
}),
outputs: outputs.move_map(|(c, out, is_rw)| {
(c, folder.fold_expr(out), is_rw)
outputs: outputs.move_map(|(c, out, is_rw, is_indirect)| {
(c, folder.fold_expr(out), is_rw, is_indirect)
}),
asm: asm,
asm_str_style: asm_str_style,

View File

@@ -2221,7 +2221,7 @@ impl<'a> State<'a> {
try!(self.word_space(":"));
try!(self.commasep(Inconsistent, &a.outputs,
|s, &(ref co, ref o, is_rw)| {
|s, &(ref co, ref o, is_rw, _)| {
match co.slice_shift_char() {
Some(('=', operand)) if is_rw => {
try!(s.print_string(&format!("+{}", operand),

View File

@@ -786,7 +786,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
for &(_, ref input) in &ia.inputs {
visitor.visit_expr(&input)
}
for &(_, ref output, _) in &ia.outputs {
for &(_, ref output, _, _) in &ia.outputs {
visitor.visit_expr(&output)
}
}