about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLuqman Aden <me@luqman.ca>2013-03-13 01:21:52 -0700
committerLuqman Aden <laden@mozilla.com>2013-03-15 18:55:44 -0700
commit59dcbd9f1c04a670cb12e1127a2f1fd0898050a6 (patch)
treea43acd4f85e6fb6abfdfb12c357bb8e5f0c10c37
parentd8ab47e7f9ed4c30c9ff3d4e2351b19992a380dd (diff)
downloadrust-59dcbd9f1c04a670cb12e1127a2f1fd0898050a6.tar.gz
rust-59dcbd9f1c04a670cb12e1127a2f1fd0898050a6.zip
Initial support for output operands in asm.
-rw-r--r--src/librustc/middle/trans/build.rs8
-rw-r--r--src/librustc/middle/trans/expr.rs40
2 files changed, 37 insertions, 11 deletions
diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs
index 9712bab2ceb..3eab94b8bc4 100644
--- a/src/librustc/middle/trans/build.rs
+++ b/src/librustc/middle/trans/build.rs
@@ -873,7 +873,7 @@ pub fn add_comment(bcx: block, text: &str) {
 }
 
 pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
-                     inputs: &[ValueRef],
+                     inputs: &[ValueRef], output: ValueRef,
                      volatile: bool, alignstack: bool,
                      dia: AsmDialect) -> ValueRef {
     unsafe {
@@ -885,10 +885,12 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
                          else          { lib::llvm::False };
 
         let argtys = do inputs.map |v| {
-            io::println(fmt!("ARG TYPE: %?", val_str(cx.ccx().tn, *v)));
+            io::println(fmt!("INPUT TYPE: %?", val_str(cx.ccx().tn, *v)));
             val_ty(*v)
         };
-        let llfty = T_fn(argtys, T_void());
+
+        io::println(fmt!("OUTPUT TYPE: %?", val_str(cx.ccx().tn, output)));
+        let llfty = T_fn(argtys, val_ty(output));
         let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile,
                                     alignstack, dia as c_uint);
 
diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs
index 6c403e4f8bb..10462a65d06 100644
--- a/src/librustc/middle/trans/expr.rs
+++ b/src/librustc/middle/trans/expr.rs
@@ -562,17 +562,33 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
             let mut constraints = ~[];
             let mut cleanups = ~[];
 
-            // TODO: Handle outputs
+            let outputs = do outs.map |&(c, out)| {
+                constraints.push(copy *c);
 
-            let inputs = do ins.map |&(c, in)| {
+                let outty = ty::arg {
+                    mode: ast::expl(ast::by_val),
+                    ty: expr_ty(bcx, out)
+                };
 
+                unpack_result!(bcx, {
+                    callee::trans_arg_expr(bcx, outty, out, &mut cleanups,
+                                           None, callee::DontAutorefArg)
+                })
+
+            };
+
+            for cleanups.each |c| {
+                revoke_clean(bcx, *c);
+            }
+            cleanups = ~[];
+
+            let inputs = do ins.map |&(c, in)| {
                 constraints.push(copy *c);
 
                 let inty = ty::arg {
                     mode: ast::expl(ast::by_val),
                     ty: expr_ty(bcx, in)
                 };
-
                 
                 unpack_result!(bcx, {
                     callee::trans_arg_expr(bcx, inty, in, &mut cleanups,
@@ -598,14 +614,22 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
                 constraints += *clobs;
             }
 
-            io::println(fmt!("Inputs: %?\nConstraints: %?\n", ins, constraints));
+            io::println(fmt!("Constraints: %?\n", constraints));
 
-            do str::as_c_str(*asm) |a| {
+            // TODO: Handle >1 outputs
+            let output = outputs[0];
+
+            let r = do str::as_c_str(*asm) |a| {
                 do str::as_c_str(constraints) |c| {
-                    InlineAsmCall(bcx, a, c, inputs, volatile, alignstack,
-                                  lib::llvm::AD_ATT);
+                    InlineAsmCall(bcx, a, c, inputs, output, volatile,
+                                  alignstack, lib::llvm::AD_ATT)
                 }
-            }
+            };
+
+            // TODO: Handle >1 outputs
+            let op = PointerCast(bcx, output, T_ptr(val_ty(output)));
+            Store(bcx, r, op);
+
             return bcx;
         }
         _ => {