Actually pass inline asm operands around.
This commit is contained in:
parent
471d2b1765
commit
6d078db952
10 changed files with 100 additions and 24 deletions
|
@ -1347,7 +1347,15 @@ pub impl Liveness {
|
||||||
self.propagate_through_expr(e, succ)
|
self.propagate_through_expr(e, succ)
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_inline_asm(*) |
|
expr_inline_asm(_, ins, outs, _, _, _) =>{
|
||||||
|
let succ = do ins.foldr(succ) |&(_, expr), succ| {
|
||||||
|
self.propagate_through_expr(expr, succ)
|
||||||
|
};
|
||||||
|
do outs.foldr(succ) |&(_, expr), succ| {
|
||||||
|
self.propagate_through_expr(expr, succ)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expr_lit(*) => {
|
expr_lit(*) => {
|
||||||
succ
|
succ
|
||||||
}
|
}
|
||||||
|
@ -1613,6 +1621,20 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
|
||||||
visit::visit_expr(expr, self, vt);
|
visit::visit_expr(expr, self, vt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_inline_asm(_, ins, outs, _, _, _) => {
|
||||||
|
for ins.each |&(_, in)| {
|
||||||
|
(vt.visit_expr)(in, self, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Output operands must be lvalues
|
||||||
|
for outs.each |&(_, out)| {
|
||||||
|
self.check_lvalue(out, vt);
|
||||||
|
(vt.visit_expr)(out, self, vt);
|
||||||
|
}
|
||||||
|
|
||||||
|
visit::visit_expr(expr, self, vt);
|
||||||
|
}
|
||||||
|
|
||||||
// no correctness conditions related to liveness
|
// no correctness conditions related to liveness
|
||||||
expr_call(*) | expr_method_call(*) | expr_if(*) | expr_match(*) |
|
expr_call(*) | expr_method_call(*) | expr_if(*) | expr_match(*) |
|
||||||
expr_while(*) | expr_loop(*) | expr_index(*) | expr_field(*) |
|
expr_while(*) | expr_loop(*) | expr_index(*) | expr_field(*) |
|
||||||
|
@ -1621,7 +1643,7 @@ fn check_expr(expr: @expr, &&self: @Liveness, vt: vt<@Liveness>) {
|
||||||
expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) |
|
expr_cast(*) | expr_unary(*) | expr_ret(*) | expr_break(*) |
|
||||||
expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) |
|
expr_again(*) | expr_lit(_) | expr_block(*) | expr_swap(*) |
|
||||||
expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
|
expr_mac(*) | expr_addr_of(*) | expr_struct(*) | expr_repeat(*) |
|
||||||
expr_paren(*) | expr_inline_asm(*) => {
|
expr_paren(*) => {
|
||||||
visit::visit_expr(expr, self, vt);
|
visit::visit_expr(expr, self, vt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,10 +558,18 @@ pub impl VisitContext {
|
||||||
self.use_expr(base, Read, visitor);
|
self.use_expr(base, Read, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_inline_asm(_, ref ins, ref outs, _, _, _) => {
|
||||||
|
for ins.each |&(c, in)| {
|
||||||
|
// XXX: Do something?
|
||||||
|
}
|
||||||
|
for outs.each |&(c, out)| {
|
||||||
|
// XXX: Do something?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
expr_break(*) |
|
expr_break(*) |
|
||||||
expr_again(*) |
|
expr_again(*) |
|
||||||
expr_lit(*) |
|
expr_lit(*) => {}
|
||||||
expr_inline_asm(*) => {}
|
|
||||||
|
|
||||||
expr_loop(ref blk, _) => {
|
expr_loop(ref blk, _) => {
|
||||||
self.consume_block(blk, visitor);
|
self.consume_block(blk, visitor);
|
||||||
|
|
|
@ -557,6 +557,18 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
|
||||||
ast::expr_paren(a) => {
|
ast::expr_paren(a) => {
|
||||||
return trans_rvalue_stmt_unadjusted(bcx, a);
|
return trans_rvalue_stmt_unadjusted(bcx, a);
|
||||||
}
|
}
|
||||||
|
ast::expr_inline_asm(asm, ref ins, ref outs,
|
||||||
|
cons, volatile, alignstack) => {
|
||||||
|
// XXX: cons doesn't actual contain ALL the stuff we should
|
||||||
|
// be passing since the constraints for in/outputs aren't included
|
||||||
|
do str::as_c_str(*asm) |a| {
|
||||||
|
do str::as_c_str(*cons) |c| {
|
||||||
|
InlineAsmCall(bcx, a, c, volatile, alignstack,
|
||||||
|
lib::llvm::AD_ATT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return bcx;
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bcx.tcx().sess.span_bug(
|
bcx.tcx().sess.span_bug(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
@ -691,17 +703,6 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr,
|
||||||
ast::expr_assign_op(op, dst, src) => {
|
ast::expr_assign_op(op, dst, src) => {
|
||||||
return trans_assign_op(bcx, expr, op, dst, src);
|
return trans_assign_op(bcx, expr, op, dst, src);
|
||||||
}
|
}
|
||||||
ast::expr_inline_asm(asm, cons, volatile, alignstack) => {
|
|
||||||
// XXX: cons doesn't actual contain ALL the stuff we should
|
|
||||||
// be passing since the constraints for in/outputs aren't included
|
|
||||||
do str::as_c_str(*asm) |a| {
|
|
||||||
do str::as_c_str(*cons) |c| {
|
|
||||||
InlineAsmCall(bcx, a, c, volatile, alignstack,
|
|
||||||
lib::llvm::AD_ATT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bcx;
|
|
||||||
}
|
|
||||||
_ => {
|
_ => {
|
||||||
bcx.tcx().sess.span_bug(
|
bcx.tcx().sess.span_bug(
|
||||||
expr.span,
|
expr.span,
|
||||||
|
|
|
@ -348,12 +348,17 @@ pub fn mark_for_expr(cx: Context, e: @expr) {
|
||||||
}
|
}
|
||||||
mark_for_method_call(cx, e.id, e.callee_id);
|
mark_for_method_call(cx, e.id, e.callee_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
expr_inline_asm(_, ref ins, ref outs, _, _, _) => {
|
||||||
|
// XXX Do something, maybe?
|
||||||
|
}
|
||||||
|
|
||||||
expr_paren(e) => mark_for_expr(cx, e),
|
expr_paren(e) => mark_for_expr(cx, e),
|
||||||
|
|
||||||
expr_match(*) | expr_block(_) | expr_if(*) | expr_while(*) |
|
expr_match(*) | expr_block(_) | expr_if(*) | expr_while(*) |
|
||||||
expr_break(_) | expr_again(_) | expr_unary(_, _) | expr_lit(_) |
|
expr_break(_) | expr_again(_) | expr_unary(_, _) | expr_lit(_) |
|
||||||
expr_mac(_) | expr_addr_of(_, _) | expr_ret(_) | expr_loop(_, _) |
|
expr_mac(_) | expr_addr_of(_, _) | expr_ret(_) | expr_loop(_, _) |
|
||||||
expr_loop_body(_) | expr_do_body(_) | expr_inline_asm(*) => ()
|
expr_loop_body(_) | expr_do_body(_) => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2317,8 +2317,15 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt,
|
||||||
let region_lb = ty::re_scope(expr.id);
|
let region_lb = ty::re_scope(expr.id);
|
||||||
instantiate_path(fcx, pth, tpt, expr.span, expr.id, region_lb);
|
instantiate_path(fcx, pth, tpt, expr.span, expr.id, region_lb);
|
||||||
}
|
}
|
||||||
ast::expr_inline_asm(*) => {
|
ast::expr_inline_asm(_, ins, outs, _, _, _) => {
|
||||||
fcx.require_unsafe(expr.span, ~"use of inline assembly");
|
fcx.require_unsafe(expr.span, ~"use of inline assembly");
|
||||||
|
|
||||||
|
for ins.each |&(_, in)| {
|
||||||
|
check_expr(fcx, in);
|
||||||
|
}
|
||||||
|
for outs.each |&(_, out)| {
|
||||||
|
check_expr(fcx, out);
|
||||||
|
}
|
||||||
fcx.write_nil(id);
|
fcx.write_nil(id);
|
||||||
}
|
}
|
||||||
ast::expr_mac(_) => tcx.sess.bug(~"unexpanded macro"),
|
ast::expr_mac(_) => tcx.sess.bug(~"unexpanded macro"),
|
||||||
|
|
|
@ -601,8 +601,10 @@ pub enum expr_ {
|
||||||
expr_ret(Option<@expr>),
|
expr_ret(Option<@expr>),
|
||||||
expr_log(log_level, @expr, @expr),
|
expr_log(log_level, @expr, @expr),
|
||||||
|
|
||||||
/* asm, clobbers + constraints, volatile, align stack */
|
expr_inline_asm(@~str, // asm
|
||||||
expr_inline_asm(@~str, @~str, bool, bool),
|
~[(@~str, @expr)], // inputs
|
||||||
|
~[(@~str, @expr)], // outputs
|
||||||
|
@~str, bool, bool), // clobbers, volatile, align stack
|
||||||
|
|
||||||
expr_mac(mac),
|
expr_mac(mac),
|
||||||
|
|
||||||
|
|
|
@ -156,7 +156,8 @@ pub fn expand_asm(cx: @ext_ctxt, sp: span, tts: &[ast::token_tree])
|
||||||
MRExpr(@ast::expr {
|
MRExpr(@ast::expr {
|
||||||
id: cx.next_id(),
|
id: cx.next_id(),
|
||||||
callee_id: cx.next_id(),
|
callee_id: cx.next_id(),
|
||||||
node: ast::expr_inline_asm(@asm, @cons, volatile, alignstack),
|
node: ast::expr_inline_asm(@asm, inputs, outputs,
|
||||||
|
@cons, volatile, alignstack),
|
||||||
span: sp
|
span: sp
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -560,7 +560,14 @@ pub fn noop_fold_expr(e: &expr_, fld: @ast_fold) -> expr_ {
|
||||||
fld.fold_expr(e)
|
fld.fold_expr(e)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
expr_inline_asm(*) => copy *e,
|
expr_inline_asm(asm, ins, outs, c, v, a) => {
|
||||||
|
expr_inline_asm(
|
||||||
|
asm,
|
||||||
|
ins.map(|&(c, in)| (c, fld.fold_expr(in))),
|
||||||
|
outs.map(|&(c, out)| (c, fld.fold_expr(out))),
|
||||||
|
c, v, a
|
||||||
|
)
|
||||||
|
}
|
||||||
expr_mac(ref mac) => expr_mac(fold_mac((*mac))),
|
expr_mac(ref mac) => expr_mac(fold_mac((*mac))),
|
||||||
expr_struct(path, ref fields, maybe_expr) => {
|
expr_struct(path, ref fields, maybe_expr) => {
|
||||||
expr_struct(
|
expr_struct(
|
||||||
|
|
|
@ -1403,7 +1403,7 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_inline_asm(a, c, v, _) => {
|
ast::expr_inline_asm(a, in, out, c, v, _) => {
|
||||||
if v {
|
if v {
|
||||||
word(s.s, ~"__volatile__ asm!");
|
word(s.s, ~"__volatile__ asm!");
|
||||||
} else {
|
} else {
|
||||||
|
@ -1411,7 +1411,23 @@ pub fn print_expr(s: @ps, &&expr: @ast::expr) {
|
||||||
}
|
}
|
||||||
popen(s);
|
popen(s);
|
||||||
print_string(s, *a);
|
print_string(s, *a);
|
||||||
word_space(s, ~",");
|
word_space(s, ~":");
|
||||||
|
for out.each |&(co, o)| {
|
||||||
|
print_string(s, *co);
|
||||||
|
popen(s);
|
||||||
|
print_expr(s, o);
|
||||||
|
pclose(s);
|
||||||
|
word_space(s, ~",");
|
||||||
|
}
|
||||||
|
word_space(s, ~":");
|
||||||
|
for in.each |&(co, o)| {
|
||||||
|
print_string(s, *co);
|
||||||
|
popen(s);
|
||||||
|
print_expr(s, o);
|
||||||
|
pclose(s);
|
||||||
|
word_space(s, ~",");
|
||||||
|
}
|
||||||
|
word_space(s, ~":");
|
||||||
print_string(s, *c);
|
print_string(s, *c);
|
||||||
pclose(s);
|
pclose(s);
|
||||||
}
|
}
|
||||||
|
|
|
@ -562,7 +562,14 @@ pub fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
||||||
}
|
}
|
||||||
expr_mac(ref mac) => visit_mac((*mac), e, v),
|
expr_mac(ref mac) => visit_mac((*mac), e, v),
|
||||||
expr_paren(x) => (v.visit_expr)(x, e, v),
|
expr_paren(x) => (v.visit_expr)(x, e, v),
|
||||||
expr_inline_asm(*) => (),
|
expr_inline_asm(_, ins, outs, _, _, _) => {
|
||||||
|
for ins.each |&(c, in)| {
|
||||||
|
(v.visit_expr)(in, e, v);
|
||||||
|
}
|
||||||
|
for outs.each |&(c, out)| {
|
||||||
|
(v.visit_expr)(out, e, v);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
(v.visit_expr_post)(ex, e, v);
|
(v.visit_expr_post)(ex, e, v);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue