about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-12-14 13:48:41 +0000
committerbors <bors@rust-lang.org>2015-12-14 13:48:41 +0000
commit50a02b43ba17bf1547b7124dff909604e967a7f6 (patch)
tree04c161e2e0556bca5bc5e4508847f2bbbae5b480 /src/libsyntax
parent6b3a3f270219819f8f98c2b6807ff70b92a941ac (diff)
parent65707dfc001b4dea745a040c2ecc61847ccba608 (diff)
downloadrust-50a02b43ba17bf1547b7124dff909604e967a7f6.tar.gz
rust-50a02b43ba17bf1547b7124dff909604e967a7f6.zip
Auto merge of #29735 - Amanieu:asm_indirect_constraint, r=pnkfelix
This PR reverts #29543 and instead implements proper support for "=*m" and "+*m" indirect output operands. This provides a framework on top of which support for plain memory operands ("m", "=m" and "+m") can be implemented.

This also fixes the liveness analysis pass not handling read/write operands correctly.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs10
-rw-r--r--src/libsyntax/ext/asm.rs12
-rw-r--r--src/libsyntax/fold.rs9
-rw-r--r--src/libsyntax/print/pprust.rs10
-rw-r--r--src/libsyntax/visit.rs4
5 files changed, 32 insertions, 13 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f11291fc0f7..46110a3bee9 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -1459,10 +1459,18 @@ pub enum AsmDialect {
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub struct InlineAsmOutput {
+    pub constraint: InternedString,
+    pub expr: P<Expr>,
+    pub is_rw: bool,
+    pub is_indirect: bool,
+}
+
+#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct InlineAsm {
     pub asm: InternedString,
     pub asm_str_style: StrStyle,
-    pub outputs: Vec<(InternedString, P<Expr>, bool)>,
+    pub outputs: Vec<InlineAsmOutput>,
     pub inputs: Vec<(InternedString, P<Expr>)>,
     pub clobbers: Vec<InternedString>,
     pub volatile: bool,
diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs
index d968858f634..b4f29f83726 100644
--- a/src/libsyntax/ext/asm.rs
+++ b/src/libsyntax/ext/asm.rs
@@ -125,7 +125,13 @@ 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(ast::InlineAsmOutput {
+                        constraint: output.unwrap_or(constraint),
+                        expr: out,
+                        is_rw: is_rw,
+                        is_indirect: is_indirect,
+                    });
                 }
             }
             Inputs => {
@@ -139,9 +145,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 '+'");
                     }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 73f2c51b246..c637813f07e 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1303,8 +1303,13 @@ 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(|out| {
+                    InlineAsmOutput {
+                        constraint: out.constraint,
+                        expr: folder.fold_expr(out.expr),
+                        is_rw: out.is_rw,
+                        is_indirect: out.is_indirect,
+                    }
                 }),
                 asm: asm,
                 asm_str_style: asm_str_style,
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index f7105951296..475bacbc886 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -2219,16 +2219,16 @@ impl<'a> State<'a> {
                 try!(self.word_space(":"));
 
                 try!(self.commasep(Inconsistent, &a.outputs,
-                                   |s, &(ref co, ref o, is_rw)| {
-                    match co.slice_shift_char() {
-                        Some(('=', operand)) if is_rw => {
+                                   |s, out| {
+                    match out.constraint.slice_shift_char() {
+                        Some(('=', operand)) if out.is_rw => {
                             try!(s.print_string(&format!("+{}", operand),
                                                 ast::CookedStr))
                         }
-                        _ => try!(s.print_string(&co, ast::CookedStr))
+                        _ => try!(s.print_string(&out.constraint, ast::CookedStr))
                     }
                     try!(s.popen());
-                    try!(s.print_expr(&**o));
+                    try!(s.print_expr(&*out.expr));
                     try!(s.pclose());
                     Ok(())
                 }));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index cdc11fb2c1c..22bf135f4f9 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -786,8 +786,8 @@ 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 {
-                visitor.visit_expr(&output)
+            for output in &ia.outputs {
+                visitor.visit_expr(&output.expr)
             }
         }
     }