Add proper support for indirect output constraints in inline asm
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 '+'");
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user