Initial support for output operands in asm.

This commit is contained in:
Luqman Aden 2013-03-13 01:21:52 -07:00 committed by Luqman Aden
parent d8ab47e7f9
commit 59dcbd9f1c
2 changed files with 37 additions and 11 deletions

View File

@ -873,7 +873,7 @@ pub fn add_comment(bcx: block, text: &str) {
}
pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
inputs: &[ValueRef],
inputs: &[ValueRef], output: ValueRef,
volatile: bool, alignstack: bool,
dia: AsmDialect) -> ValueRef {
unsafe {
@ -885,10 +885,12 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char,
else { lib::llvm::False };
let argtys = do inputs.map |v| {
io::println(fmt!("ARG TYPE: %?", val_str(cx.ccx().tn, *v)));
io::println(fmt!("INPUT TYPE: %?", val_str(cx.ccx().tn, *v)));
val_ty(*v)
};
let llfty = T_fn(argtys, T_void());
io::println(fmt!("OUTPUT TYPE: %?", val_str(cx.ccx().tn, output)));
let llfty = T_fn(argtys, val_ty(output));
let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile,
alignstack, dia as c_uint);

View File

@ -562,17 +562,33 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
let mut constraints = ~[];
let mut cleanups = ~[];
// TODO: Handle outputs
let outputs = do outs.map |&(c, out)| {
constraints.push(copy *c);
let outty = ty::arg {
mode: ast::expl(ast::by_val),
ty: expr_ty(bcx, out)
};
unpack_result!(bcx, {
callee::trans_arg_expr(bcx, outty, out, &mut cleanups,
None, callee::DontAutorefArg)
})
};
for cleanups.each |c| {
revoke_clean(bcx, *c);
}
cleanups = ~[];
let inputs = do ins.map |&(c, in)| {
constraints.push(copy *c);
let inty = ty::arg {
mode: ast::expl(ast::by_val),
ty: expr_ty(bcx, in)
};
unpack_result!(bcx, {
callee::trans_arg_expr(bcx, inty, in, &mut cleanups,
@ -598,14 +614,22 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block {
constraints += *clobs;
}
io::println(fmt!("Inputs: %?\nConstraints: %?\n", ins, constraints));
io::println(fmt!("Constraints: %?\n", constraints));
do str::as_c_str(*asm) |a| {
// TODO: Handle >1 outputs
let output = outputs[0];
let r = do str::as_c_str(*asm) |a| {
do str::as_c_str(constraints) |c| {
InlineAsmCall(bcx, a, c, inputs, volatile, alignstack,
lib::llvm::AD_ATT);
InlineAsmCall(bcx, a, c, inputs, output, volatile,
alignstack, lib::llvm::AD_ATT)
}
}
};
// TODO: Handle >1 outputs
let op = PointerCast(bcx, output, T_ptr(val_ty(output)));
Store(bcx, r, op);
return bcx;
}
_ => {