Skip to content

Commit 5aa734d

Browse files
committed
Parse operands properly and add a way to indicate volatile asm.
1 parent 885d0d3 commit 5aa734d

File tree

5 files changed

+145
-18
lines changed

5 files changed

+145
-18
lines changed

src/librustc/middle/trans/build.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -873,12 +873,12 @@ pub fn add_comment(bcx: block, text: &str) {
873873
}
874874
875875
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
876-
dia: AsmDialect) -> ValueRef {
876+
volatile: lib::llvm::Bool, dia: AsmDialect) -> ValueRef {
877877
unsafe {
878878
count_insn(cx, "inlineasm");
879879
880880
let llfty = T_fn(~[], T_void());
881-
let v = llvm::LLVMInlineAsm(llfty, asm, cons, False, False, dia);
881+
let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, False, dia);
882882
883883
Call(cx, v, ~[])
884884
}

src/librustc/middle/trans/expr.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -691,10 +691,14 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
691691
ast::expr_assign_op(op, dst, src) => {
692692
return trans_assign_op(bcx, expr, op, dst, src);
693693
}
694-
ast::expr_inline_asm(asm, cons) => {
694+
ast::expr_inline_asm(asm, cons, volatile) => {
695+
// XXX: cons doesn't actual contain ALL the stuff we should
696+
// be passing since the constraints for in/outputs aren't included
695697
do str::as_c_str(*asm) |a| {
696698
do str::as_c_str(*cons) |c| {
697-
InlineAsmCall(bcx, a, c, lib::llvm::AD_ATT);
699+
let v = if volatile { lib::llvm::True }
700+
else { lib::llvm::False };
701+
InlineAsmCall(bcx, a, c, v, lib::llvm::AD_ATT);
698702
}
699703
}
700704
return bcx;

src/libsyntax/ast.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ pub enum expr_ {
601601
expr_ret(Option<@expr>),
602602
expr_log(log_level, @expr, @expr),
603603
604-
expr_inline_asm(@~str /* asm */, @~str /* constraints */),
604+
/* asm, clobbers + constraints, volatile */
605+
expr_inline_asm(@~str, @~str, bool),
605606
606607
expr_mac(mac),
607608

src/libsyntax/ext/asm.rs

Lines changed: 129 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,29 +20,147 @@ use ast;
2020
use codemap::span;
2121
use ext::base;
2222
use ext::base::*;
23+
use parse;
24+
use parse::token;
25+
26+
enum State {
27+
Asm,
28+
Outputs,
29+
Inputs,
30+
Clobbers,
31+
Options
32+
}
33+
34+
fn next_state(s: State) -> Option<State> {
35+
match s {
36+
Asm => Some(Outputs),
37+
Outputs => Some(Inputs),
38+
Inputs => Some(Clobbers),
39+
Clobbers => Some(Options),
40+
Options => None
41+
}
42+
}
2343

2444
pub fn expand_asm(cx: ext_ctxt, sp: span, tts: &[ast::token_tree])
2545
-> base::MacResult {
26-
let args = get_exprs_from_tts(cx, tts);
27-
if args.len() == 0 {
28-
cx.span_fatal(sp, "ast! takes at least 1 argument.");
46+
47+
let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
48+
vec::from_slice(tts));
49+
50+
let mut asm = ~"";
51+
let mut outputs = ~[];
52+
let mut inputs = ~[];
53+
let mut cons = ~"";
54+
let mut volatile = false;
55+
56+
let mut state = Asm;
57+
loop outer: {
58+
59+
match state {
60+
Asm => {
61+
asm = expr_to_str(cx, p.parse_expr(),
62+
~"inline assembly must be a string literal.");
63+
}
64+
Outputs => {
65+
while *p.token != token::EOF &&
66+
*p.token != token::COLON &&
67+
*p.token != token::MOD_SEP {
68+
69+
if outputs.len() != 0 {
70+
p.eat(&token::COMMA);
71+
}
72+
73+
let constraint = p.parse_str();
74+
p.expect(&token::LPAREN);
75+
let out = p.parse_expr();
76+
p.expect(&token::RPAREN);
77+
78+
outputs.push((constraint, out));
79+
}
80+
}
81+
Inputs => {
82+
while *p.token != token::EOF &&
83+
*p.token != token::COLON &&
84+
*p.token != token::MOD_SEP {
85+
86+
if inputs.len() != 0 {
87+
p.eat(&token::COMMA);
88+
}
89+
90+
let constraint = p.parse_str();
91+
p.expect(&token::LPAREN);
92+
let in = p.parse_expr();
93+
p.expect(&token::RPAREN);
94+
95+
inputs.push((constraint, in));
96+
}
97+
}
98+
Clobbers => {
99+
let mut clobs = ~[];
100+
while *p.token != token::EOF &&
101+
*p.token != token::COLON &&
102+
*p.token != token::MOD_SEP {
103+
104+
if clobs.len() != 0 {
105+
p.eat(&token::COMMA);
106+
}
107+
108+
let clob = ~"~{" + *p.parse_str() + ~"}";
109+
clobs.push(clob);
110+
}
111+
112+
cons = str::connect(clobs, ",");
113+
}
114+
Options => {
115+
let option = *p.parse_str();
116+
117+
if option == ~"volatile" {
118+
volatile = true;
119+
}
120+
121+
if *p.token == token::COMMA {
122+
p.eat(&token::COMMA);
123+
}
124+
}
125+
}
126+
127+
while *p.token == token::COLON ||
128+
*p.token == token::MOD_SEP ||
129+
*p.token == token::EOF {
130+
state = if *p.token == token::COLON {
131+
p.bump();
132+
match next_state(state) {
133+
Some(x) => x,
134+
None => break outer
135+
}
136+
} else if *p.token == token::MOD_SEP {
137+
p.bump();
138+
let s = match next_state(state) {
139+
Some(x) => x,
140+
None => break outer
141+
};
142+
match next_state(s) {
143+
Some(x) => x,
144+
None => break outer
145+
}
146+
} else if *p.token == token::EOF {
147+
break outer;
148+
} else {
149+
state
150+
};
151+
}
29152
}
30-
let asm =
31-
expr_to_str(cx, args[0],
32-
~"inline assembly must be a string literal.");
33-
let cons = if args.len() > 1 {
34-
expr_to_str(cx, args[1],
35-
~"constraints must be a string literal.")
36-
} else { ~"" };
37153

38154
MRExpr(@ast::expr {
39155
id: cx.next_id(),
40156
callee_id: cx.next_id(),
41-
node: ast::expr_inline_asm(@asm, @cons),
157+
node: ast::expr_inline_asm(@asm, @cons, volatile),
42158
span: sp
43159
})
44160
}
45161

162+
163+
46164
//
47165
// Local Variables:
48166
// mode: rust

src/libsyntax/print/pprust.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1398,8 +1398,12 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
13981398
}
13991399
}
14001400
}
1401-
ast::expr_inline_asm(a, c) => {
1402-
word(s.s, ~"__asm__");
1401+
ast::expr_inline_asm(a, c, v) => {
1402+
if v {
1403+
word(s.s, ~"__volatile__ asm!");
1404+
} else {
1405+
word(s.s, ~"asm!");
1406+
}
14031407
popen(s);
14041408
print_string(s, *a);
14051409
word_space(s, ~",");

0 commit comments

Comments
 (0)