Skip to content

Commit 727a565

Browse files
committed
librustc: Move inline asm stuff to different mod.
1 parent 30b1957 commit 727a565

File tree

3 files changed

+133
-100
lines changed

3 files changed

+133
-100
lines changed

src/librustc/middle/trans/asm.rs

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/*!
12+
# Translation of inline assembly.
13+
*/
14+
15+
use core::prelude::*;
16+
17+
use lib;
18+
use middle::trans::build::*;
19+
use middle::trans::callee;
20+
use middle::trans::common::*;
21+
use middle::ty;
22+
23+
use syntax::ast;
24+
use syntax::ast::*;
25+
26+
// Take an inline assembly expression and splat it out via LLVM
27+
pub fn trans_inline_asm(bcx: block, asm: @~str, ins: &[(@~str, @expr)], outs: &[(@~str, @expr)],
28+
clobs: @~str, volatile: bool, alignstack: bool) -> block {
29+
30+
let mut bcx = bcx;
31+
let mut constraints = ~[];
32+
let mut cleanups = ~[];
33+
let mut aoutputs = ~[];
34+
35+
// Prepare the output operands
36+
let outputs = do outs.map |&(c, out)| {
37+
constraints.push(copy *c);
38+
39+
let aoutty = ty::arg {
40+
mode: ast::expl(ast::by_copy),
41+
ty: expr_ty(bcx, out)
42+
};
43+
aoutputs.push(unpack_result!(bcx, {
44+
callee::trans_arg_expr(bcx, aoutty, out, &mut cleanups, None, callee::DontAutorefArg)
45+
}));
46+
47+
let e = match out.node {
48+
ast::expr_addr_of(_, e) => e,
49+
_ => fail!(~"Expression must be addr of")
50+
};
51+
52+
let outty = ty::arg {
53+
mode: ast::expl(ast::by_copy),
54+
ty: expr_ty(bcx, e)
55+
};
56+
57+
unpack_result!(bcx, {
58+
callee::trans_arg_expr(bcx, outty, e, &mut cleanups, None, callee::DontAutorefArg)
59+
})
60+
61+
};
62+
63+
for cleanups.each |c| {
64+
revoke_clean(bcx, *c);
65+
}
66+
cleanups.clear();
67+
68+
// Now the input operands
69+
let inputs = do ins.map |&(c, in)| {
70+
constraints.push(copy *c);
71+
72+
let inty = ty::arg {
73+
mode: ast::expl(ast::by_copy),
74+
ty: expr_ty(bcx, in)
75+
};
76+
77+
unpack_result!(bcx, {
78+
callee::trans_arg_expr(bcx, inty, in, &mut cleanups, None, callee::DontAutorefArg)
79+
})
80+
81+
};
82+
83+
for cleanups.each |c| {
84+
revoke_clean(bcx, *c);
85+
}
86+
87+
let mut constraints = str::connect(constraints, ",");
88+
89+
// Add the clobbers to our constraints list
90+
if *clobs != ~"" && constraints != ~"" {
91+
constraints += ~"," + *clobs;
92+
} else {
93+
constraints += *clobs;
94+
}
95+
96+
debug!("Asm Constraints: %?", constraints);
97+
98+
let numOutputs = outputs.len();
99+
100+
// Depending on how many outputs we have, the return type is different
101+
let output = if numOutputs == 0 {
102+
T_void()
103+
} else if numOutputs == 1 {
104+
val_ty(outputs[0])
105+
} else {
106+
T_struct(outputs.map(|o| val_ty(*o)))
107+
};
108+
109+
let r = do str::as_c_str(*asm) |a| {
110+
do str::as_c_str(constraints) |c| {
111+
// XXX: Allow selection of at&t or intel
112+
InlineAsmCall(bcx, a, c, inputs, output, volatile, alignstack, lib::llvm::AD_ATT)
113+
}
114+
};
115+
116+
// Again, based on how many outputs we have
117+
if numOutputs == 1 {
118+
let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0])));
119+
Store(bcx, r, op);
120+
} else {
121+
for aoutputs.eachi |i, o| {
122+
let v = ExtractValue(bcx, r, i);
123+
let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i])));
124+
Store(bcx, v, op);
125+
}
126+
}
127+
128+
return bcx;
129+
130+
}

src/librustc/middle/trans/expr.rs

Lines changed: 2 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ use lib::llvm::{ValueRef, TypeRef, llvm, True};
127127
use middle::borrowck::root_map_key;
128128
use middle::trans::_match;
129129
use middle::trans::adt;
130+
use middle::trans::asm;
130131
use middle::trans::base;
131132
use middle::trans::base::*;
132133
use middle::trans::build::*;
@@ -559,106 +560,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
559560
}
560561
ast::expr_inline_asm(asm, ref ins, ref outs,
561562
clobs, volatile, alignstack) => {
562-
let mut constraints = ~[];
563-
let mut cleanups = ~[];
564-
let mut aoutputs = ~[];
565-
566-
let outputs = do outs.map |&(c, out)| {
567-
constraints.push(copy *c);
568-
569-
let aoutty = ty::arg {
570-
mode: ast::expl(ast::by_copy),
571-
ty: expr_ty(bcx, out)
572-
};
573-
aoutputs.push(unpack_result!(bcx, {
574-
callee::trans_arg_expr(bcx, aoutty, out, &mut cleanups,
575-
None, callee::DontAutorefArg)
576-
}));
577-
578-
let e = match out.node {
579-
ast::expr_addr_of(_, e) => e,
580-
_ => fail!(~"Expression must be addr of")
581-
};
582-
583-
let outty = ty::arg {
584-
mode: ast::expl(ast::by_copy),
585-
ty: expr_ty(bcx, e)
586-
};
587-
588-
unpack_result!(bcx, {
589-
callee::trans_arg_expr(bcx, outty, e, &mut cleanups,
590-
None, callee::DontAutorefArg)
591-
})
592-
593-
};
594-
595-
for cleanups.each |c| {
596-
revoke_clean(bcx, *c);
597-
}
598-
cleanups = ~[];
599-
600-
let inputs = do ins.map |&(c, in)| {
601-
constraints.push(copy *c);
602-
603-
let inty = ty::arg {
604-
mode: ast::expl(ast::by_copy),
605-
ty: expr_ty(bcx, in)
606-
};
607-
608-
unpack_result!(bcx, {
609-
callee::trans_arg_expr(bcx, inty, in, &mut cleanups,
610-
None, callee::DontAutorefArg)
611-
})
612-
613-
};
614-
615-
for cleanups.each |c| {
616-
revoke_clean(bcx, *c);
617-
}
618-
619-
let mut constraints = str::connect(constraints, ",");
620-
621-
// Add the clobbers
622-
if *clobs != ~"" {
623-
if constraints == ~"" {
624-
constraints += *clobs;
625-
} else {
626-
constraints += ~"," + *clobs;
627-
}
628-
} else {
629-
constraints += *clobs;
630-
}
631-
632-
debug!("Asm Constraints: %?", constraints);
633-
634-
let output = if outputs.len() == 0 {
635-
T_void()
636-
} else if outputs.len() == 1 {
637-
val_ty(outputs[0])
638-
} else {
639-
T_struct(outputs.map(|o| val_ty(*o)))
640-
};
641-
642-
let r = do str::as_c_str(*asm) |a| {
643-
do str::as_c_str(constraints) |c| {
644-
InlineAsmCall(bcx, a, c, inputs, output, volatile,
645-
alignstack, lib::llvm::AD_ATT)
646-
}
647-
};
648-
649-
if outputs.len() == 1 {
650-
let op = PointerCast(bcx, aoutputs[0],
651-
T_ptr(val_ty(outputs[0])));
652-
Store(bcx, r, op);
653-
} else {
654-
for aoutputs.eachi |i, o| {
655-
let v = ExtractValue(bcx, r, i);
656-
let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i])));
657-
Store(bcx, v, op);
658-
}
659-
}
660-
661-
return bcx;
563+
return asm::trans_inline_asm(bcx, asm, *ins, *outs, clobs, volatile, alignstack);
662564
}
663565
_ => {
664566
bcx.tcx().sess.span_bug(

src/librustc/rustc.rc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ pub mod middle {
8080
pub mod reachable;
8181
pub mod machine;
8282
pub mod adt;
83+
pub mod asm;
8384
}
8485
pub mod ty;
8586
pub mod resolve;

0 commit comments

Comments
 (0)