From 471d2b17657bdaea357faeaa3e857f8a758bfbe3 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Tue, 12 Mar 2013 16:40:59 -0700 Subject: [PATCH 1/9] Inline asm exprs should be RvalueStmtExpr. --- src/librustc/middle/ty.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 69e06117785..f455e983690 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -3102,7 +3102,6 @@ pub fn expr_kind(tcx: ctxt, ast::expr_block(*) | ast::expr_copy(*) | ast::expr_repeat(*) | - ast::expr_inline_asm(*) | ast::expr_lit(@codemap::spanned {node: lit_str(_), _}) | ast::expr_vstore(_, ast::expr_vstore_slice) | ast::expr_vstore(_, ast::expr_vstore_mut_slice) | @@ -3145,6 +3144,7 @@ pub fn expr_kind(tcx: ctxt, ast::expr_loop(*) | ast::expr_assign(*) | ast::expr_swap(*) | + ast::expr_inline_asm(*) | ast::expr_assign_op(*) => { RvalueStmtExpr } From 6d078db952cf76b35bbd8577fe6a9f5d9e12c566 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Tue, 12 Mar 2013 17:53:25 -0700 Subject: [PATCH 2/9] Actually pass inline asm operands around. --- src/librustc/middle/liveness.rs | 26 +++++++++++++++++++++++-- src/librustc/middle/moves.rs | 12 ++++++++++-- src/librustc/middle/trans/expr.rs | 23 +++++++++++----------- src/librustc/middle/trans/type_use.rs | 7 ++++++- src/librustc/middle/typeck/check/mod.rs | 9 ++++++++- src/libsyntax/ast.rs | 6 ++++-- src/libsyntax/ext/asm.rs | 3 ++- src/libsyntax/fold.rs | 9 ++++++++- src/libsyntax/print/pprust.rs | 20 +++++++++++++++++-- src/libsyntax/visit.rs | 9 ++++++++- 10 files changed, 100 insertions(+), 24 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 1201346ab68..2afe9564b20 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1347,7 +1347,15 @@ pub impl Liveness { self.propagate_through_expr(e, succ) } - expr_inline_asm(*) | + expr_inline_asm(_, ins, outs, _, _, _) =>{ + let succ = do ins.foldr(succ) |&(_, expr), succ| { + self.propagate_through_expr(expr, succ) + }; + do outs.foldr(succ) |&(_, expr), succ| { + self.propagate_through_expr(expr, succ) + } + } + expr_lit(*) => { succ } @@ -1613,6 +1621,20 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { visit::visit_expr(expr, self, vt); } + expr_inline_asm(_, ins, outs, _, _, _) => { + for ins.each |&(_, in)| { + (vt.visit_expr)(in, self, vt); + } + + // Output operands must be lvalues + for outs.each |&(_, out)| { + self.check_lvalue(out, vt); + (vt.visit_expr)(out, self, vt); + } + + visit::visit_expr(expr, self, vt); + } + // no correctness conditions related to liveness expr_call(*) | expr_method_call(*) | expr_if(*) | expr_match(*) | expr_while(*) | expr_loop(*) | expr_index(*) | expr_field(*) | @@ -1621,7 +1643,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) | expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) | expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) | - expr_paren(*) | expr_inline_asm(*) => { + expr_paren(*) => { visit::visit_expr(expr, self, vt); } } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index a7562d190a2..372c54f2b09 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -558,10 +558,18 @@ pub impl VisitContext { self.use_expr(base, Read, visitor); } + expr_inline_asm(_, ref ins, ref outs, _, _, _) => { + for ins.each |&(c, in)| { + // XXX: Do something? + } + for outs.each |&(c, out)| { + // XXX: Do something? + } + } + expr_break(*) | expr_again(*) | - expr_lit(*) | - expr_inline_asm(*) => {} + expr_lit(*) => {} expr_loop(ref blk, _) => { self.consume_block(blk, visitor); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index e986d0bdae3..e634dfcbe65 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -557,6 +557,18 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { ast::expr_paren(a) => { return trans_rvalue_stmt_unadjusted(bcx, a); } + ast::expr_inline_asm(asm, ref ins, ref outs, + cons, volatile, alignstack) => { + // XXX: cons doesn't actual contain ALL the stuff we should + // be passing since the constraints for in/outputs aren't included + do str::as_c_str(*asm) |a| { + do str::as_c_str(*cons) |c| { + InlineAsmCall(bcx, a, c, volatile, alignstack, + lib::llvm::AD_ATT); + } + } + return bcx; + } _ => { bcx.tcx().sess.span_bug( expr.span, @@ -691,17 +703,6 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, ast::expr_assign_op(op, dst, src) => { return trans_assign_op(bcx, expr, op, dst, src); } - ast::expr_inline_asm(asm, cons, volatile, alignstack) => { - // XXX: cons doesn't actual contain ALL the stuff we should - // be passing since the constraints for in/outputs aren't included - do str::as_c_str(*asm) |a| { - do str::as_c_str(*cons) |c| { - InlineAsmCall(bcx, a, c, volatile, alignstack, - lib::llvm::AD_ATT); - } - } - return bcx; - } _ => { bcx.tcx().sess.span_bug( expr.span, diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 5279c10d967..8439d941c90 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -348,12 +348,17 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } mark_for_method_call(cx, e.id, e.callee_id); } + + expr_inline_asm(_, ref ins, ref outs, _, _, _) => { + // XXX Do something, maybe? + } + expr_paren(e) => mark_for_expr(cx, e), expr_match(*) | expr_block(_) | expr_if(*) | expr_while(*) | expr_break(_) | expr_again(_) | expr_unary(_, _) | expr_lit(_) | expr_mac(_) | expr_addr_of(_, _) | expr_ret(_) | expr_loop(_, _) | - expr_loop_body(_) | expr_do_body(_) | expr_inline_asm(*) => () + expr_loop_body(_) | expr_do_body(_) => () } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 240f79ce262..f3fff416c55 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2317,8 +2317,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let region_lb = ty::re_scope(expr.id); instantiate_path(fcx, pth, tpt, expr.span, expr.id, region_lb); } - ast::expr_inline_asm(*) => { + ast::expr_inline_asm(_, ins, outs, _, _, _) => { fcx.require_unsafe(expr.span, ~"use of inline assembly"); + + for ins.each |&(_, in)| { + check_expr(fcx, in); + } + for outs.each |&(_, out)| { + check_expr(fcx, out); + } fcx.write_nil(id); } ast::expr_mac(_) => tcx.sess.bug(~"unexpanded macro"), diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 298cb241bed..e5fb2ad153c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -601,8 +601,10 @@ pub enum expr_ { expr_ret(Option<@expr>), expr_log(log_level, @expr, @expr), - /* asm, clobbers + constraints, volatile, align stack */ - expr_inline_asm(@~str, @~str, bool, bool), + expr_inline_asm(@~str, // asm + ~[(@~str, @expr)], // inputs + ~[(@~str, @expr)], // outputs + @~str, bool, bool), // clobbers, volatile, align stack expr_mac(mac), diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 4f2fd68ff95..0110c186cfa 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -156,7 +156,8 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) MRExpr(@ast::expr { id: cx.next_id(), callee_id: cx.next_id(), - node: ast::expr_inline_asm(@asm, @cons, volatile, alignstack), + node: ast::expr_inline_asm(@asm, inputs, outputs, + @cons, volatile, alignstack), span: sp }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1626c55e721..a8952f313a5 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -560,7 +560,14 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.fold_expr(e) ) } - expr_inline_asm(*) => copy *e, + expr_inline_asm(asm, ins, outs, c, v, a) => { + expr_inline_asm( + asm, + ins.map(|&(c, in)| (c, fld.fold_expr(in))), + outs.map(|&(c, out)| (c, fld.fold_expr(out))), + c, v, a + ) + } expr_mac(ref mac) => expr_mac(fold_mac((*mac))), expr_struct(path, ref fields, maybe_expr) => { expr_struct( diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 724e61daea7..370434010b2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1403,7 +1403,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { } } } - ast::expr_inline_asm(a, c, v, _) => { + ast::expr_inline_asm(a, in, out, c, v, _) => { if v { word(s.s, ~"__volatile__ asm!"); } else { @@ -1411,7 +1411,23 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { } popen(s); print_string(s, *a); - word_space(s, ~","); + word_space(s, ~":"); + for out.each |&(co, o)| { + print_string(s, *co); + popen(s); + print_expr(s, o); + pclose(s); + word_space(s, ~","); + } + word_space(s, ~":"); + for in.each |&(co, o)| { + print_string(s, *co); + popen(s); + print_expr(s, o); + pclose(s); + word_space(s, ~","); + } + word_space(s, ~":"); print_string(s, *c); pclose(s); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 95ab603f584..1fb81b5c702 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -562,7 +562,14 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { } expr_mac(ref mac) => visit_mac((*mac), e, v), expr_paren(x) => (v.visit_expr)(x, e, v), - expr_inline_asm(*) => (), + expr_inline_asm(_, ins, outs, _, _, _) => { + for ins.each |&(c, in)| { + (v.visit_expr)(in, e, v); + } + for outs.each |&(c, out)| { + (v.visit_expr)(out, e, v); + } + } } (v.visit_expr_post)(ex, e, v); } From d8ab47e7f9ed4c30c9ff3d4e2351b19992a380dd Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 00:32:23 -0700 Subject: [PATCH 3/9] Properly handle input operands for inline asm. --- src/librustc/middle/trans/build.rs | 9 ++++-- src/librustc/middle/trans/expr.rs | 49 +++++++++++++++++++++++++++--- 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 850ea908e74..9712bab2ceb 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -873,6 +873,7 @@ pub fn add_comment(bcx: block, text: &str) { } pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, + inputs: &[ValueRef], volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { unsafe { @@ -883,11 +884,15 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, let alignstack = if alignstack { lib::llvm::True } else { lib::llvm::False }; - let llfty = T_fn(~[], T_void()); + let argtys = do inputs.map |v| { + io::println(fmt!("ARG TYPE: %?", val_str(cx.ccx().tn, *v))); + val_ty(*v) + }; + let llfty = T_fn(argtys, T_void()); let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, alignstack, dia as c_uint); - Call(cx, v, ~[]) + Call(cx, v, inputs) } } diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index e634dfcbe65..6c403e4f8bb 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -558,12 +558,51 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { return trans_rvalue_stmt_unadjusted(bcx, a); } ast::expr_inline_asm(asm, ref ins, ref outs, - cons, volatile, alignstack) => { - // XXX: cons doesn't actual contain ALL the stuff we should - // be passing since the constraints for in/outputs aren't included + clobs, volatile, alignstack) => { + let mut constraints = ~[]; + let mut cleanups = ~[]; + + // TODO: Handle outputs + + 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, + None, callee::DontAutorefArg) + }) + + }; + + for cleanups.each |c| { + revoke_clean(bcx, *c); + } + + let mut constraints = str::connect(constraints, ","); + + // Add the clobbers + if *clobs != ~"" { + if constraints == ~"" { + constraints += *clobs; + } else { + constraints += ~"," + *clobs; + } + } else { + constraints += *clobs; + } + + io::println(fmt!("Inputs: %?\nConstraints: %?\n", ins, constraints)); + do str::as_c_str(*asm) |a| { - do str::as_c_str(*cons) |c| { - InlineAsmCall(bcx, a, c, volatile, alignstack, + do str::as_c_str(constraints) |c| { + InlineAsmCall(bcx, a, c, inputs, volatile, alignstack, lib::llvm::AD_ATT); } } From 59dcbd9f1c04a670cb12e1127a2f1fd0898050a6 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 01:21:52 -0700 Subject: [PATCH 4/9] Initial support for output operands in asm. --- src/librustc/middle/trans/build.rs | 8 +++--- src/librustc/middle/trans/expr.rs | 40 ++++++++++++++++++++++++------ 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 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; } _ => { From 9ead7dad934cc361f8e5e489238031c987ecfc82 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 10:11:36 -0700 Subject: [PATCH 5/9] Implicitly use addr_of for output operands in asm. --- src/librustc/middle/trans/expr.rs | 21 ++++++++++++++++++--- src/libsyntax/ext/asm.rs | 7 +++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 10462a65d06..75097e151aa 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -561,17 +561,32 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { clobs, volatile, alignstack) => { let mut constraints = ~[]; let mut cleanups = ~[]; + let mut aoutputs = ~[]; let outputs = do outs.map |&(c, out)| { constraints.push(copy *c); - let outty = ty::arg { + let aoutty = ty::arg { mode: ast::expl(ast::by_val), ty: expr_ty(bcx, out) }; + aoutputs.push(unpack_result!(bcx, { + callee::trans_arg_expr(bcx, aoutty, out, &mut cleanups, + None, callee::DontAutorefArg) + })); + + let e = match out.node { + ast::expr_addr_of(_, e) => e, + _ => fail!(~"Expression must be addr of") + }; + + let outty = ty::arg { + mode: ast::expl(ast::by_val), + ty: expr_ty(bcx, e) + }; unpack_result!(bcx, { - callee::trans_arg_expr(bcx, outty, out, &mut cleanups, + callee::trans_arg_expr(bcx, outty, e, &mut cleanups, None, callee::DontAutorefArg) }) @@ -627,7 +642,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { }; // TODO: Handle >1 outputs - let op = PointerCast(bcx, output, T_ptr(val_ty(output))); + let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(output))); Store(bcx, r, op); return bcx; diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 0110c186cfa..34cb743a727 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -75,6 +75,13 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) let out = p.parse_expr(); p.expect(&token::RPAREN); + let out = @ast::expr { + id: cx.next_id(), + callee_id: cx.next_id(), + span: out.span, + node: ast::expr_addr_of(ast::m_mutbl, out) + }; + outputs.push((constraint, out)); } } From e182ac4bbde92a4a29fcdd3ff7c3906b394b8c16 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 13:21:54 -0700 Subject: [PATCH 6/9] Actually use no or multiple operands properly. --- src/librustc/middle/trans/build.rs | 8 ++++---- src/librustc/middle/trans/expr.rs | 24 ++++++++++++++++++------ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 3eab94b8bc4..1d31dc4fb8a 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], output: ValueRef, + inputs: &[ValueRef], output: TypeRef, volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { unsafe { @@ -885,12 +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!("INPUT TYPE: %?", val_str(cx.ccx().tn, *v))); + debug!("Asm Input Type: %?", val_str(cx.ccx().tn, *v)); val_ty(*v) }; - io::println(fmt!("OUTPUT TYPE: %?", val_str(cx.ccx().tn, output))); - let llfty = T_fn(argtys, val_ty(output)); + debug!("Asm Output Type: %?", ty_str(cx.ccx().tn, output)); + let llfty = T_fn(argtys, 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 75097e151aa..73cff97de95 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -629,10 +629,15 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { constraints += *clobs; } - io::println(fmt!("Constraints: %?\n", constraints)); + debug!("Asm Constraints: %?", constraints); - // TODO: Handle >1 outputs - let output = outputs[0]; + let output = if outputs.len() == 0 { + T_void() + } else if outputs.len() == 1 { + val_ty(outputs[0]) + } else { + T_struct(outputs.map(|o| val_ty(*o))) + }; let r = do str::as_c_str(*asm) |a| { do str::as_c_str(constraints) |c| { @@ -641,9 +646,16 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { } }; - // TODO: Handle >1 outputs - let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(output))); - Store(bcx, r, op); + if outputs.len() == 1 { + let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); + Store(bcx, r, op); + } else { + for aoutputs.eachi |i, o| { + let v = ExtractValue(bcx, r, i); + let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i]))); + Store(bcx, v, op); + } + } return bcx; } From 3d56936be3c010829edf188475140dcb322da803 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 13:47:15 -0700 Subject: [PATCH 7/9] Tidy. --- src/librustc/middle/trans/expr.rs | 5 +++-- src/libsyntax/ext/asm.rs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 73cff97de95..8453b49f5c0 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -604,7 +604,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { mode: ast::expl(ast::by_val), ty: expr_ty(bcx, in) }; - + unpack_result!(bcx, { callee::trans_arg_expr(bcx, inty, in, &mut cleanups, None, callee::DontAutorefArg) @@ -647,7 +647,8 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { }; if outputs.len() == 1 { - let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); + let op = PointerCast(bcx, aoutputs[0], + T_ptr(val_ty(outputs[0]))); Store(bcx, r, op); } else { for aoutputs.eachi |i, o| { diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index 34cb743a727..a014d8ccb8b 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -163,7 +163,7 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) MRExpr(@ast::expr { id: cx.next_id(), callee_id: cx.next_id(), - node: ast::expr_inline_asm(@asm, inputs, outputs, + node: ast::expr_inline_asm(@asm, inputs, outputs, @cons, volatile, alignstack), span: sp }) From d68b98a5bfebffb28d49e14e6568a69c547c74ae Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 13 Mar 2013 15:32:48 -0700 Subject: [PATCH 8/9] Don't use by_val for passing asm operands. --- src/librustc/middle/trans/expr.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 8453b49f5c0..fb63f5384fb 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -567,7 +567,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { constraints.push(copy *c); let aoutty = ty::arg { - mode: ast::expl(ast::by_val), + mode: ast::expl(ast::by_copy), ty: expr_ty(bcx, out) }; aoutputs.push(unpack_result!(bcx, { @@ -581,7 +581,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { }; let outty = ty::arg { - mode: ast::expl(ast::by_val), + mode: ast::expl(ast::by_copy), ty: expr_ty(bcx, e) }; @@ -601,7 +601,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { constraints.push(copy *c); let inty = ty::arg { - mode: ast::expl(ast::by_val), + mode: ast::expl(ast::by_copy), ty: expr_ty(bcx, in) }; From 83f2d4ab3dbd3b52ea60212a6698c73201b67a34 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Fri, 15 Mar 2013 18:54:39 -0700 Subject: [PATCH 9/9] Fix type_use for inline asm. --- src/librustc/middle/moves.rs | 10 +--------- src/librustc/middle/trans/type_use.rs | 7 ++++++- src/libsyntax/visit.rs | 4 ++-- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 372c54f2b09..9848c65ac43 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -558,15 +558,7 @@ pub impl VisitContext { self.use_expr(base, Read, visitor); } - expr_inline_asm(_, ref ins, ref outs, _, _, _) => { - for ins.each |&(c, in)| { - // XXX: Do something? - } - for outs.each |&(c, out)| { - // XXX: Do something? - } - } - + expr_inline_asm(*) | expr_break(*) | expr_again(*) | expr_lit(*) => {} diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 8439d941c90..692dc392173 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -350,7 +350,12 @@ pub fn mark_for_expr(cx: Context, e: @expr) { } expr_inline_asm(_, ref ins, ref outs, _, _, _) => { - // XXX Do something, maybe? + for ins.each |&(_, in)| { + node_type_needs(cx, use_repr, in.id); + } + for outs.each |&(_, out)| { + node_type_needs(cx, use_repr, out.id); + } } expr_paren(e) => mark_for_expr(cx, e), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 1fb81b5c702..6a0f1a2ec46 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -563,10 +563,10 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { expr_mac(ref mac) => visit_mac((*mac), e, v), expr_paren(x) => (v.visit_expr)(x, e, v), expr_inline_asm(_, ins, outs, _, _, _) => { - for ins.each |&(c, in)| { + for ins.each |&(_, in)| { (v.visit_expr)(in, e, v); } - for outs.each |&(c, out)| { + for outs.each |&(_, out)| { (v.visit_expr)(out, e, v); } }