提交 ecccc0d6 编写于 作者: L Luqman Aden

Parse inline assembly.

上级 4e350c7c
......@@ -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 unsafe fn LLVMConstNamedStruct(S: TypeRef,
/** 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 @@ fn propagate_through_expr(&self, expr: @expr, succ: LiveNode)
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 @@ fn cat_expr_unadjusted(&self, expr: @ast::expr) -> cmt {
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 @@ fn use_expr(&self,
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 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 @@ fn check_loop_body(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 @@ fn guarantor(rcx: @mut Rcx, expr: @ast::expr) -> Option<ty::Region> {
// 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 @@ fn fold_field_(field: field, fld: @ast_fold) -> field {
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_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 @@ fn parse_bottom_expr(&self) -> @expr {
}
}
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 @@ fn print_field(s: @ps, field: ast::field) {
}
}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册