From: Luqman Aden Date: Wed, 27 Mar 2013 19:50:57 +0000 (-0700) Subject: librustc: Move inline asm stuff to different mod. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=727a565f1e65c415b018f26d878a0d3ebdc9e3ea;p=rust.git librustc: Move inline asm stuff to different mod. --- diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs new file mode 100644 index 00000000000..ceb1b7ed1ec --- /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 0da1a9acef2..3138fe420a9 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -127,6 +127,7 @@ 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 e3df3b692fb..456f9743afa 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;