mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-30 02:33:55 +00:00
Parse inline assembly.
This commit is contained in:
parent
4e350c7ce7
commit
ecccc0d649
@ -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(*) |
|
||||
|
@ -601,6 +601,8 @@ pub enum expr_ {
|
||||
expr_ret(Option<@expr>),
|
||||
expr_log(log_level, @expr, @expr),
|
||||
|
||||
expr_inline_asm(@~str /* asm */, @~str /* constraints */),
|
||||
|
||||
expr_mac(mac),
|
||||
|
||||
// A struct literal expression.
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user