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

@ -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

@ -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;
}
}

@ -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);
}
}

@ -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);
}
}

@ -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);

@ -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 {

@ -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,

@ -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(*) => ()
}
}

@ -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) |

@ -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; }

@ -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(*) |

@ -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),

@ -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(

@ -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();

@ -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",

@ -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);

@ -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);
}

@ -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));
}

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