diff --git a/src/etc/vim/syntax/rust.vim b/src/etc/vim/syntax/rust.vim index f811fbf5855..ccd1ddc2430 100644 --- a/src/etc/vim/syntax/rust.vim +++ b/src/etc/vim/syntax/rust.vim @@ -11,7 +11,7 @@ elseif exists("b:current_syntax") endif syn match rustAssert "\ ValueRef; } } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 0c17b371694..d300698da59 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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); } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 9e0ecb5a218..5881f95f298 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -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); } } diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 182697b290f..734f4651f3b 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -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); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index 45104480b4c..93459042d23 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -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 { diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index e38b0be7bcc..9012d258718 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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, diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 710bb5eb346..9a0c330d2d1 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -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(*) => () } } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index b4ef87491a8..6e21439fc35 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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) | diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 6617fa3b27c..bd36eb1cf56 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -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; } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 55d027549e3..1dd88e6408b 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -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(*) | diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 27dba9c2b5e..b7c30360613 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -600,6 +600,8 @@ pub enum expr_ { expr_again(Option), expr_ret(Option<@expr>), expr_log(log_level, @expr, @expr), + + expr_inline_asm(@~str /* asm */, @~str /* constraints */), expr_mac(mac), diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 427760c920f..15097f57b02 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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( diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 99c1c2cb1fe..6076ad0ce0e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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(); diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 81aacbf173d..5cfe0bef9b8 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -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", diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 62f593f15c1..350ab0cf9b2 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index f04894729bd..95ab603f584 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -562,6 +562,7 @@ pub fn visit_expr(ex: @expr, e: E, v: vt) { } 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); } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 3af936d3461..f5efed5f3a0 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -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(Ty), AsmString, + Constraints, HasSideEffects, + IsAlignStack)); +// IsAlignStack, InlineAsm::AD_Intel)); +} diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in index ceedf438296..8b1c9d5ec7f 100644 --- a/src/rustllvm/rustllvm.def.in +++ b/src/rustllvm/rustllvm.def.in @@ -583,3 +583,4 @@ LLVMX86MMXTypeInContext LLVMConstNamedStruct LLVMStructCreateNamed LLVMStructSetBody +LLVMInlineAsm