提交 5aa734d6 编写于 作者: L Luqman Aden

Parse operands properly and add a way to indicate volatile asm.

上级 885d0d3d
......@@ -873,12 +873,12 @@ pub fn add_comment(bcx: block, text: &str) {
}
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
dia: AsmDialect) -> ValueRef {
volatile: lib::llvm::Bool, dia: AsmDialect) -> ValueRef {
unsafe {
count_insn(cx, "inlineasm");
let llfty = T_fn(~[], T_void());
let v = llvm::LLVMInlineAsm(llfty, asm, cons, False, False, dia);
let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, False, dia);
Call(cx, v, ~[])
}
......
......@@ -691,10 +691,14 @@ 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) => {
ast::expr_inline_asm(asm, cons, volatile) => {
// 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, lib::llvm::AD_ATT);
let v = if volatile { lib::llvm::True }
else { lib::llvm::False };
InlineAsmCall(bcx, a, c, v, lib::llvm::AD_ATT);
}
}
return bcx;
......
......@@ -601,7 +601,8 @@ pub enum expr_ {
expr_ret(Option<@expr>),
expr_log(log_level, @expr, @expr),
expr_inline_asm(@~str /* asm */, @~str /* constraints */),
/* asm, clobbers + constraints, volatile */
expr_inline_asm(@~str, @~str, bool),
expr_mac(mac),
......
......@@ -20,29 +20,147 @@
use codemap::span;
use ext::base;
use ext::base::*;
use parse;
use parse::token;
enum State {
Asm,
Outputs,
Inputs,
Clobbers,
Options
}
fn next_state(s: State) -> Option<State> {
match s {
Asm => Some(Outputs),
Outputs => Some(Inputs),
Inputs => Some(Clobbers),
Clobbers => Some(Options),
Options => None
}
}
pub fn expand_asm(cx: ext_ctxt, sp: span, tts: &[ast::token_tree])
-> base::MacResult {
let args = get_exprs_from_tts(cx, tts);
if args.len() == 0 {
cx.span_fatal(sp, "ast! takes at least 1 argument.");
let p = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg(),
vec::from_slice(tts));
let mut asm = ~"";
let mut outputs = ~[];
let mut inputs = ~[];
let mut cons = ~"";
let mut volatile = false;
let mut state = Asm;
loop outer: {
match state {
Asm => {
asm = expr_to_str(cx, p.parse_expr(),
~"inline assembly must be a string literal.");
}
Outputs => {
while *p.token != token::EOF &&
*p.token != token::COLON &&
*p.token != token::MOD_SEP {
if outputs.len() != 0 {
p.eat(&token::COMMA);
}
let constraint = p.parse_str();
p.expect(&token::LPAREN);
let out = p.parse_expr();
p.expect(&token::RPAREN);
outputs.push((constraint, out));
}
}
Inputs => {
while *p.token != token::EOF &&
*p.token != token::COLON &&
*p.token != token::MOD_SEP {
if inputs.len() != 0 {
p.eat(&token::COMMA);
}
let constraint = p.parse_str();
p.expect(&token::LPAREN);
let in = p.parse_expr();
p.expect(&token::RPAREN);
inputs.push((constraint, in));
}
}
Clobbers => {
let mut clobs = ~[];
while *p.token != token::EOF &&
*p.token != token::COLON &&
*p.token != token::MOD_SEP {
if clobs.len() != 0 {
p.eat(&token::COMMA);
}
let clob = ~"~{" + *p.parse_str() + ~"}";
clobs.push(clob);
}
cons = str::connect(clobs, ",");
}
Options => {
let option = *p.parse_str();
if option == ~"volatile" {
volatile = true;
}
if *p.token == token::COMMA {
p.eat(&token::COMMA);
}
}
}
while *p.token == token::COLON ||
*p.token == token::MOD_SEP ||
*p.token == token::EOF {
state = if *p.token == token::COLON {
p.bump();
match next_state(state) {
Some(x) => x,
None => break outer
}
} else if *p.token == token::MOD_SEP {
p.bump();
let s = match next_state(state) {
Some(x) => x,
None => break outer
};
match next_state(s) {
Some(x) => x,
None => break outer
}
} else if *p.token == token::EOF {
break outer;
} else {
state
};
}
}
let asm =
expr_to_str(cx, args[0],
~"inline assembly must be a string literal.");
let cons = if args.len() > 1 {
expr_to_str(cx, args[1],
~"constraints must be a string literal.")
} else { ~"" };
MRExpr(@ast::expr {
id: cx.next_id(),
callee_id: cx.next_id(),
node: ast::expr_inline_asm(@asm, @cons),
node: ast::expr_inline_asm(@asm, @cons, volatile),
span: sp
})
}
//
// Local Variables:
// mode: rust
......
......@@ -1398,8 +1398,12 @@ fn print_field(s: @ps, field: ast::field) {
}
}
}
ast::expr_inline_asm(a, c) => {
word(s.s, ~"__asm__");
ast::expr_inline_asm(a, c, v) => {
if v {
word(s.s, ~"__volatile__ asm!");
} else {
word(s.s, ~"asm!");
}
popen(s);
print_string(s, *a);
word_space(s, ~",");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册