From 727a565f1e65c415b018f26d878a0d3ebdc9e3ea Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 27 Mar 2013 12:50:57 -0700 Subject: [PATCH 1/6] librustc: Move inline asm stuff to different mod. --- src/librustc/middle/trans/asm.rs | 130 ++++++++++++++++++++++++++++++ src/librustc/middle/trans/expr.rs | 102 +---------------------- src/librustc/rustc.rc | 1 + 3 files changed, 133 insertions(+), 100 deletions(-) create mode 100644 src/librustc/middle/trans/asm.rs diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs new file mode 100644 index 0000000000000..ceb1b7ed1ecda --- /dev/null +++ b/src/librustc/middle/trans/asm.rs @@ -0,0 +1,130 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/*! +# Translation of inline assembly. +*/ + +use core::prelude::*; + +use lib; +use middle::trans::build::*; +use middle::trans::callee; +use middle::trans::common::*; +use middle::ty; + +use syntax::ast; +use syntax::ast::*; + +// Take an inline assembly expression and splat it out via LLVM +pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[(@~str, @expr)], + clobs: @~str, volatile: bool, alignstack: bool) -> block { + + let mut bcx = bcx; + let mut constraints = ~[]; + let mut cleanups = ~[]; + let mut aoutputs = ~[]; + + // Prepare the output operands + let outputs = do outs.map |&(c, out)| { + constraints.push(copy *c); + + let aoutty = ty::arg { + mode: ast::expl(ast::by_copy), + 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_copy), + ty: expr_ty(bcx, e) + }; + + unpack_result!(bcx, { + callee::trans_arg_expr(bcx, outty, e, &mut cleanups, None, callee::DontAutorefArg) + }) + + }; + + for cleanups.each |c| { + revoke_clean(bcx, *c); + } + cleanups.clear(); + + // Now the input operands + let inputs = do ins.map |&(c, in)| { + constraints.push(copy *c); + + let inty = ty::arg { + mode: ast::expl(ast::by_copy), + 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 to our constraints list + if *clobs != ~"" && constraints != ~"" { + constraints += ~"," + *clobs; + } else { + constraints += *clobs; + } + + debug!("Asm Constraints: %?", constraints); + + let numOutputs = outputs.len(); + + // Depending on how many outputs we have, the return type is different + let output = if numOutputs == 0 { + T_void() + } else if numOutputs == 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| { + // XXX: Allow selection of at&t or intel + InlineAsmCall(bcx, a, c, inputs, output, volatile, alignstack, lib::llvm::AD_ATT) + } + }; + + // Again, based on how many outputs we have + if numOutputs == 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; + +} diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 0da1a9acef212..3138fe420a97f 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -127,6 +127,7 @@ use lib::llvm::{ValueRef, TypeRef, llvm, True}; use middle::borrowck::root_map_key; use middle::trans::_match; use middle::trans::adt; +use middle::trans::asm; use middle::trans::base; use middle::trans::base::*; use middle::trans::build::*; @@ -559,106 +560,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { } ast::expr_inline_asm(asm, ref ins, ref outs, clobs, volatile, alignstack) => { - let mut constraints = ~[]; - let mut cleanups = ~[]; - let mut aoutputs = ~[]; - - let outputs = do outs.map |&(c, out)| { - constraints.push(copy *c); - - let aoutty = ty::arg { - mode: ast::expl(ast::by_copy), - 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_copy), - ty: expr_ty(bcx, e) - }; - - unpack_result!(bcx, { - callee::trans_arg_expr(bcx, outty, e, &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_copy), - 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; - } - - debug!("Asm Constraints: %?", constraints); - - 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| { - InlineAsmCall(bcx, a, c, inputs, output, volatile, - alignstack, lib::llvm::AD_ATT) - } - }; - - 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; + return asm::trans_inline_asm(bcx, asm, *ins, *outs, clobs, volatile, alignstack); } _ => { bcx.tcx().sess.span_bug( diff --git a/src/librustc/rustc.rc b/src/librustc/rustc.rc index e3df3b692fb87..456f9743afab4 100644 --- a/src/librustc/rustc.rc +++ b/src/librustc/rustc.rc @@ -80,6 +80,7 @@ pub mod middle { pub mod reachable; pub mod machine; pub mod adt; + pub mod asm; } pub mod ty; pub mod resolve; From 203d691a6bf6795f3d1f77378696a4506dd550f2 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 27 Mar 2013 13:42:21 -0700 Subject: [PATCH 2/6] libsyntax: use a struct for inline asm in ast. --- src/librustc/middle/liveness.rs | 19 ++++++++++++------- src/librustc/middle/trans/asm.rs | 18 ++++++++---------- src/librustc/middle/trans/expr.rs | 5 ++--- src/librustc/middle/trans/type_use.rs | 6 +++--- src/librustc/middle/typeck/check/mod.rs | 6 +++--- src/libsyntax/ast.rs | 17 +++++++++++++---- src/libsyntax/ext/asm.rs | 12 +++++++++--- src/libsyntax/fold.rs | 16 +++++++++------- src/libsyntax/print/pprust.rs | 12 ++++++------ src/libsyntax/visit.rs | 6 +++--- 10 files changed, 68 insertions(+), 49 deletions(-) diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 15fc4317bf3a8..9a419c85894ad 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1346,11 +1346,11 @@ pub impl Liveness { self.propagate_through_expr(e, succ) } - expr_inline_asm(_, ref ins, ref outs, _, _, _) =>{ - let succ = do ins.foldr(succ) |&(_, expr), succ| { + expr_inline_asm(ref ia) =>{ + let succ = do ia.inputs.foldr(succ) |&(_, expr), succ| { self.propagate_through_expr(expr, succ) }; - do outs.foldr(succ) |&(_, expr), succ| { + do ia.outputs.foldr(succ) |&(_, expr), succ| { self.propagate_through_expr(expr, succ) } } @@ -1620,14 +1620,19 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) { visit::visit_expr(expr, self, vt); } - expr_inline_asm(_, ref ins, ref outs, _, _, _) => { - for ins.each |&(_, in)| { + expr_inline_asm(ref ia) => { + for ia.inputs.each |&(_, in)| { (vt.visit_expr)(in, self, vt); } // Output operands must be lvalues - for outs.each |&(_, out)| { - self.check_lvalue(out, vt); + for ia.outputs.each |&(_, out)| { + match out.node { + expr_addr_of(_, inner) => { + self.check_lvalue(inner, vt); + } + _ => {} + } (vt.visit_expr)(out, self, vt); } diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index ceb1b7ed1ecda..a658908f9781a 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -21,11 +21,9 @@ use middle::trans::common::*; use middle::ty; use syntax::ast; -use syntax::ast::*; // Take an inline assembly expression and splat it out via LLVM -pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[(@~str, @expr)], - clobs: @~str, volatile: bool, alignstack: bool) -> block { +pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { let mut bcx = bcx; let mut constraints = ~[]; @@ -33,7 +31,7 @@ pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[ let mut aoutputs = ~[]; // Prepare the output operands - let outputs = do outs.map |&(c, out)| { + let outputs = do ia.outputs.map |&(c, out)| { constraints.push(copy *c); let aoutty = ty::arg { @@ -66,7 +64,7 @@ pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[ cleanups.clear(); // Now the input operands - let inputs = do ins.map |&(c, in)| { + let inputs = do ia.inputs.map |&(c, in)| { constraints.push(copy *c); let inty = ty::arg { @@ -87,10 +85,10 @@ pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[ let mut constraints = str::connect(constraints, ","); // Add the clobbers to our constraints list - if *clobs != ~"" && constraints != ~"" { - constraints += ~"," + *clobs; + if *ia.clobbers != ~"" && constraints != ~"" { + constraints += ~"," + *ia.clobbers; } else { - constraints += *clobs; + constraints += *ia.clobbers; } debug!("Asm Constraints: %?", constraints); @@ -106,10 +104,10 @@ pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[ T_struct(outputs.map(|o| val_ty(*o))) }; - let r = do str::as_c_str(*asm) |a| { + let r = do str::as_c_str(*ia.asm) |a| { do str::as_c_str(constraints) |c| { // XXX: Allow selection of at&t or intel - InlineAsmCall(bcx, a, c, inputs, output, volatile, alignstack, lib::llvm::AD_ATT) + InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, lib::llvm::AD_ATT) } }; diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 3138fe420a97f..9cd9916932302 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -558,9 +558,8 @@ 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, - clobs, volatile, alignstack) => { - return asm::trans_inline_asm(bcx, asm, *ins, *outs, clobs, volatile, alignstack); + ast::expr_inline_asm(ref a) => { + return asm::trans_inline_asm(bcx, a); } _ => { bcx.tcx().sess.span_bug( diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index cad2a03f7a1ef..cee92af6620b6 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -360,11 +360,11 @@ 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, _, _, _) => { - for ins.each |&(_, in)| { + expr_inline_asm(ref ia) => { + for ia.inputs.each |&(_, in)| { node_type_needs(cx, use_repr, in.id); } - for outs.each |&(_, out)| { + for ia.outputs.each |&(_, out)| { node_type_needs(cx, use_repr, out.id); } } diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 85efc9fa738e8..6d4af492c972e 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -2332,13 +2332,13 @@ 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(_, ref ins, ref outs, _, _, _) => { + ast::expr_inline_asm(ref ia) => { fcx.require_unsafe(expr.span, ~"use of inline assembly"); - for ins.each |&(_, in)| { + for ia.inputs.each |&(_, in)| { check_expr(fcx, in); } - for outs.each |&(_, out)| { + for ia.outputs.each |&(_, out)| { check_expr(fcx, out); } fcx.write_nil(id); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 12d4e9d5e2447..05c5f447993d7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -600,10 +600,7 @@ pub enum expr_ { expr_ret(Option<@expr>), expr_log(log_level, @expr, @expr), - expr_inline_asm(@~str, // asm - ~[(@~str, @expr)], // inputs - ~[(@~str, @expr)], // outputs - @~str, bool, bool), // clobbers, volatile, align stack + expr_inline_asm(inline_asm), expr_mac(mac), @@ -937,6 +934,18 @@ impl to_bytes::IterBytes for Ty { } } +#[auto_encode] +#[auto_decode] +#[deriving(Eq)] +pub struct inline_asm { + asm: @~str, + clobbers: @~str, + inputs: ~[(@~str, @expr)], + outputs: ~[(@~str, @expr)], + volatile: bool, + alignstack: bool +} + #[auto_encode] #[auto_decode] #[deriving(Eq)] diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index a014d8ccb8bc5..c3faf4f1e0945 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -59,7 +59,7 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) match state { Asm => { asm = expr_to_str(cx, p.parse_expr(), - ~"inline assembly must be a string literal."); + ~"inline assembly must be a string literal."); } Outputs => { while *p.token != token::EOF && @@ -163,8 +163,14 @@ 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, - @cons, volatile, alignstack), + node: ast::expr_inline_asm(ast::inline_asm { + asm: @asm, + clobbers: @cons, + inputs: inputs, + outputs: outputs, + volatile: volatile, + alignstack: alignstack + }), span: sp }) } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 9d4cf4e89392f..6ba629a24e1e4 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -559,13 +559,15 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { fld.fold_expr(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_inline_asm(a) => { + expr_inline_asm(inline_asm { + asm: a.asm, + clobbers: a.clobbers, + inputs: a.inputs.map(|&(c, in)| (c, fld.fold_expr(in))), + outputs: a.outputs.map(|&(c, out)| (c, fld.fold_expr(out))), + volatile: a.volatile, + alignstack: a.alignstack + }) } expr_mac(ref mac) => expr_mac(fold_mac((*mac))), expr_struct(path, ref fields, maybe_expr) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 9fffed7074b3d..3b56017b8e085 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1406,16 +1406,16 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { } } } - ast::expr_inline_asm(a, in, out, c, v, _) => { - if v { + ast::expr_inline_asm(a) => { + if a.volatile { word(s.s, ~"__volatile__ asm!"); } else { word(s.s, ~"asm!"); } popen(s); - print_string(s, *a); + print_string(s, *a.asm); word_space(s, ~":"); - for out.each |&(co, o)| { + for a.outputs.each |&(co, o)| { print_string(s, *co); popen(s); print_expr(s, o); @@ -1423,7 +1423,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { word_space(s, ~","); } word_space(s, ~":"); - for in.each |&(co, o)| { + for a.inputs.each |&(co, o)| { print_string(s, *co); popen(s); print_expr(s, o); @@ -1431,7 +1431,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) { word_space(s, ~","); } word_space(s, ~":"); - print_string(s, *c); + print_string(s, *a.clobbers); pclose(s); } ast::expr_mac(ref m) => print_mac(s, (*m)), diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index a159c98d21b27..daa16e867b9da 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -565,11 +565,11 @@ 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 |&(_, in)| { + expr_inline_asm(ref a) => { + for a.inputs.each |&(_, in)| { (v.visit_expr)(in, e, v); } - for outs.each |&(_, out)| { + for a.outputs.each |&(_, out)| { (v.visit_expr)(out, e, v); } } From b867fe41defd95d839c96e2b746d1c7560fd338f Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 27 Mar 2013 14:42:19 -0700 Subject: [PATCH 3/6] libsyntax: Allow selecting intel style asm. --- src/librustc/middle/trans/asm.rs | 7 ++++++- src/libsyntax/ast.rs | 11 ++++++++++- src/libsyntax/ext/asm.rs | 6 +++++- src/libsyntax/fold.rs | 5 +---- 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index a658908f9781a..5ad7299e1e54f 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -104,10 +104,15 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { T_struct(outputs.map(|o| val_ty(*o))) }; + let dialect = match ia.dialect { + ast::asm_att => lib::llvm::AD_ATT, + ast::asm_intel => lib::llvm::AD_Intel + }; + let r = do str::as_c_str(*ia.asm) |a| { do str::as_c_str(constraints) |c| { // XXX: Allow selection of at&t or intel - InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, lib::llvm::AD_ATT) + InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect) } }; diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 05c5f447993d7..c70288902a398 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -934,6 +934,14 @@ impl to_bytes::IterBytes for Ty { } } +#[auto_encode] +#[auto_decode] +#[deriving(Eq)] +pub enum asm_dialect { + asm_att, + asm_intel +} + #[auto_encode] #[auto_decode] #[deriving(Eq)] @@ -943,7 +951,8 @@ pub struct inline_asm { inputs: ~[(@~str, @expr)], outputs: ~[(@~str, @expr)], volatile: bool, - alignstack: bool + alignstack: bool, + dialect: asm_dialect } #[auto_encode] diff --git a/src/libsyntax/ext/asm.rs b/src/libsyntax/ext/asm.rs index c3faf4f1e0945..b070948d4059f 100644 --- a/src/libsyntax/ext/asm.rs +++ b/src/libsyntax/ext/asm.rs @@ -53,6 +53,7 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) let mut cons = ~""; let mut volatile = false; let mut alignstack = false; + let mut dialect = ast::asm_att; let mut state = Asm; loop outer: { @@ -125,6 +126,8 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) volatile = true; } else if option == ~"alignstack" { alignstack = true; + } else if option == ~"intel" { + dialect = ast::asm_intel; } if *p.token == token::COMMA { @@ -169,7 +172,8 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree]) inputs: inputs, outputs: outputs, volatile: volatile, - alignstack: alignstack + alignstack: alignstack, + dialect: dialect }), span: sp }) diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 6ba629a24e1e4..e54c495323f4e 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -561,12 +561,9 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ { } expr_inline_asm(a) => { expr_inline_asm(inline_asm { - asm: a.asm, - clobbers: a.clobbers, inputs: a.inputs.map(|&(c, in)| (c, fld.fold_expr(in))), outputs: a.outputs.map(|&(c, out)| (c, fld.fold_expr(out))), - volatile: a.volatile, - alignstack: a.alignstack + .. a }) } expr_mac(ref mac) => expr_mac(fold_mac((*mac))), From 778f84524b5e99b39748f89f87e1a5e90d13e6a6 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 27 Mar 2013 15:37:28 -0700 Subject: [PATCH 4/6] librustc: add default per arch clobbers for asm. --- src/librustc/middle/trans/asm.rs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 5ad7299e1e54f..798d684e0bd98 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -84,11 +84,18 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { let mut constraints = str::connect(constraints, ","); + let mut clobbers = getClobbers(); + if *ia.clobbers != ~"" && clobbers != ~"" { + clobbers = *ia.clobbers + ~"," + clobbers; + } else { + clobbers += *ia.clobbers; + }; + // Add the clobbers to our constraints list - if *ia.clobbers != ~"" && constraints != ~"" { - constraints += ~"," + *ia.clobbers; + if clobbers != ~"" && constraints != ~"" { + constraints += ~"," + clobbers; } else { - constraints += *ia.clobbers; + constraints += clobbers; } debug!("Asm Constraints: %?", constraints); @@ -131,3 +138,18 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { return bcx; } + +// Default per-arch clobbers +// Basically what clang does + +#[cfg(target_arch = "arm")] +#[cfg(target_arch = "mips")] +fn getClobbers() -> ~str { + ~"" +} + +#[cfg(target_arch = "x86")] +#[cfg(target_arch = "x86_64")] +fn getClobbers() -> ~str { + ~"~{dirflag},~{fpsr},~{flags}" +} From 63df1e9085c14b80cc86df55b234d16627f09b01 Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Wed, 27 Mar 2013 16:29:32 -0700 Subject: [PATCH 5/6] librustc: remove already addressed XXX --- src/librustc/middle/trans/asm.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 798d684e0bd98..d7602191bb3a7 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -118,7 +118,6 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { let r = do str::as_c_str(*ia.asm) |a| { do str::as_c_str(constraints) |c| { - // XXX: Allow selection of at&t or intel InlineAsmCall(bcx, a, c, inputs, output, ia.volatile, ia.alignstack, dialect) } }; From a3996c1626003472437b9c29e179583daf9e53bf Mon Sep 17 00:00:00 2001 From: Luqman Aden Date: Thu, 28 Mar 2013 16:34:10 -0700 Subject: [PATCH 6/6] Tidy. --- src/librustc/middle/trans/asm.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index d7602191bb3a7..b3b23a8730d1a 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -122,7 +122,7 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { } }; - // Again, based on how many outputs we have + // Again, based on how many outputs we have if numOutputs == 1 { let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); Store(bcx, r, op);