Parse inline assembly.

This commit is contained in:
Luqman Aden 2013-03-09 22:37:50 -08:00
parent 4e350c7ce7
commit ecccc0d649
19 changed files with 72 additions and 8 deletions

View File

@ -11,7 +11,7 @@ elseif exists("b:current_syntax")
endif
syn match rustAssert "\<assert\(\w\)*"
syn keyword rustKeyword as break
syn keyword rustKeyword __asm__ as break
syn keyword rustKeyword copy do drop else extern
syn keyword rustKeyword for if impl let log
syn keyword rustKeyword loop match mod once priv pub pure

View File

@ -1433,6 +1433,11 @@ pub mod llvm {
/** Enables LLVM debug output. */
pub unsafe fn LLVMSetDebug(Enabled: c_int);
/** Prepares inline assembly. */
pub unsafe fn LLVMInlineAsm(Ty: TypeRef, AsmString: *c_char,
Constraints: *c_char, SideEffects: Bool,
AlignStack: Bool) -> ValueRef;
}
}

View File

@ -620,7 +620,8 @@ fn visit_expr(expr: @expr, &&self: @mut IrMaps, vt: vt<@mut IrMaps>) {
expr_do_body(*) | expr_cast(*) | expr_unary(*) | expr_break(_) |
expr_again(_) | expr_lit(_) | expr_ret(*) | expr_block(*) |
expr_assign(*) | expr_swap(*) | expr_assign_op(*) | expr_mac(*) |
expr_struct(*) | expr_repeat(*) | expr_paren(*) => {
expr_struct(*) | expr_repeat(*) | expr_paren(*) |
expr_inline_asm(*) => {
visit::visit_expr(expr, self, vt);
}
}
@ -1345,6 +1346,7 @@ pub impl Liveness {
self.propagate_through_expr(e, succ)
}
expr_inline_asm(*) |
expr_lit(*) => {
succ
}
@ -1618,7 +1620,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) |
expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) |
expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
expr_paren(*) => {
expr_paren(*) | expr_inline_asm(*) => {
visit::visit_expr(expr, self, vt);
}
}

View File

@ -447,7 +447,7 @@ pub impl mem_categorization_ctxt {
ast::expr_while(*) | ast::expr_block(*) | ast::expr_loop(*) |
ast::expr_match(*) | ast::expr_lit(*) | ast::expr_break(*) |
ast::expr_mac(*) | ast::expr_again(*) | ast::expr_struct(*) |
ast::expr_repeat(*) => {
ast::expr_repeat(*) | ast::expr_inline_asm(*) => {
return self.cat_rvalue(expr, expr_ty);
}
}

View File

@ -560,7 +560,8 @@ pub impl VisitContext {
expr_break(*) |
expr_again(*) |
expr_lit(*) => {}
expr_lit(*) |
expr_inline_asm(*) => {}
expr_loop(ref blk, _) => {
self.consume_block(blk, visitor);

View File

@ -18,7 +18,7 @@ use syntax::codemap::span;
use core::prelude::*;
use core::cast;
use core::libc::{c_uint, c_int, c_ulonglong};
use core::libc::{c_uint, c_int, c_ulonglong, c_char};
use core::libc;
use core::option::Some;
use core::ptr;
@ -872,6 +872,17 @@ pub fn add_comment(bcx: block, text: &str) {
}
}
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char) -> ValueRef {
unsafe {
count_insn(cx, "inlineasm");
let llfty = T_fn(~[], T_void());
let v = llvm::LLVMInlineAsm(llfty, asm, cons, False, False);
Call(cx, v, ~[])
}
}
pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef {
if cx.unreachable { return _UndefReturn(cx, Fn); }
unsafe {

View File

@ -691,6 +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) => {
do str::as_c_str(*asm) |a| {
do str::as_c_str(*cons) |c| {
InlineAsmCall(bcx, a, c);
}
}
return bcx;
}
_ => {
bcx.tcx().sess.span_bug(
expr.span,

View File

@ -353,7 +353,7 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
expr_match(*) | expr_block(_) | expr_if(*) | expr_while(*) |
expr_break(_) | expr_again(_) | expr_unary(_, _) | expr_lit(_) |
expr_mac(_) | expr_addr_of(_, _) | expr_ret(_) | expr_loop(_, _) |
expr_loop_body(_) | expr_do_body(_) => ()
expr_loop_body(_) | expr_do_body(_) | expr_inline_asm(*) => ()
}
}

View File

@ -3076,6 +3076,7 @@ pub fn expr_kind(tcx: ctxt,
ast::expr_block(*) |
ast::expr_copy(*) |
ast::expr_repeat(*) |
ast::expr_inline_asm(*) |
ast::expr_lit(@codemap::spanned {node: lit_str(_), _}) |
ast::expr_vstore(_, ast::expr_vstore_slice) |
ast::expr_vstore(_, ast::expr_vstore_mut_slice) |

View File

@ -2303,6 +2303,7 @@ 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(*) => { fcx.write_nil(id); }
ast::expr_mac(_) => tcx.sess.bug(~"unexpanded macro"),
ast::expr_break(_) => { fcx.write_bot(id); bot = true; }
ast::expr_again(_) => { fcx.write_bot(id); bot = true; }

View File

@ -682,6 +682,7 @@ pub mod guarantor {
// All of these expressions are rvalues and hence their
// value is not guaranteed by a region pointer.
ast::expr_inline_asm(*) |
ast::expr_mac(*) |
ast::expr_lit(_) |
ast::expr_unary(*) |

View File

@ -600,6 +600,8 @@ pub enum expr_ {
expr_again(Option<ident>),
expr_ret(Option<@expr>),
expr_log(log_level, @expr, @expr),
expr_inline_asm(@~str /* asm */, @~str /* constraints */),
expr_mac(mac),

View File

@ -560,6 +560,7 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
fld.fold_expr(e)
)
}
expr_inline_asm(*) => copy *e,
expr_mac(ref mac) => expr_mac(fold_mac((*mac))),
expr_struct(path, ref fields, maybe_expr) => {
expr_struct(

View File

@ -27,7 +27,7 @@ use ast::{expr_field, expr_fn_block, expr_if, expr_index};
use ast::{expr_lit, expr_log, expr_loop, expr_loop_body, expr_mac};
use ast::{expr_method_call, expr_paren, expr_path, expr_repeat};
use ast::{expr_ret, expr_swap, expr_struct, expr_tup, expr_unary};
use ast::{expr_vec, expr_vstore, expr_vstore_mut_box};
use ast::{expr_vec, expr_vstore, expr_vstore_mut_box, expr_inline_asm};
use ast::{expr_vstore_fixed, expr_vstore_slice, expr_vstore_box};
use ast::{expr_vstore_mut_slice, expr_while, extern_fn, field, fn_decl};
use ast::{expr_vstore_uniq, TyClosure, TyBareFn, Onceness, Once, Many};
@ -1184,6 +1184,14 @@ pub impl Parser {
}
}
hi = self.span.hi;
} else if self.eat_keyword(&~"__asm__") {
self.expect(&token::LPAREN);
let asm = self.parse_str();
self.expect(&token::COMMA);
let cons = self.parse_str();
ex = expr_inline_asm(asm, cons);
hi = self.span.hi;
self.expect(&token::RPAREN);
} else if self.eat_keyword(&~"log") {
self.expect(&token::LPAREN);
let lvl = self.parse_expr();

View File

@ -488,6 +488,7 @@ pub fn temporary_keyword_table() -> HashMap<~str, ()> {
pub fn strict_keyword_table() -> HashMap<~str, ()> {
let words = HashMap();
let keys = ~[
~"__asm__",
~"as", ~"assert",
~"break",
~"const", ~"copy",

View File

@ -1398,6 +1398,14 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
}
}
}
ast::expr_inline_asm(a, c) => {
word(s.s, ~"__asm__");
popen(s);
print_string(s, *a);
word_space(s, ~", ");
print_string(s, *c);
pclose(s);
}
ast::expr_mac(ref m) => print_mac(s, (*m)),
ast::expr_paren(e) => {
popen(s);

View File

@ -562,6 +562,7 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
}
expr_mac(ref mac) => visit_mac((*mac), e, v),
expr_paren(x) => (v.visit_expr)(x, e, v),
expr_inline_asm(*) => (),
}
(v.visit_expr_post)(ex, e, v);
}

View File

@ -15,6 +15,7 @@
//
//===----------------------------------------------------------------------===
#include "llvm/InlineAsm.h"
#include "llvm/LLVMContext.h"
#include "llvm/Linker.h"
#include "llvm/PassManager.h"
@ -539,3 +540,14 @@ extern "C" void LLVMSetDebug(int Enabled) {
DebugFlag = Enabled;
#endif
}
extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
char *AsmString,
char *Constraints,
LLVMBool HasSideEffects,
LLVMBool IsAlignStack) {
return wrap(InlineAsm::get(unwrap<FunctionType>(Ty), AsmString,
Constraints, HasSideEffects,
IsAlignStack));
// IsAlignStack, InlineAsm::AD_Intel));
}

View File

@ -583,3 +583,4 @@ LLVMX86MMXTypeInContext
LLVMConstNamedStruct
LLVMStructCreateNamed
LLVMStructSetBody
LLVMInlineAsm