Commit b42a0385 authored by qinsoon's avatar qinsoon

implement pass floating point as argument to function

parent 872adc0f
Pipeline #371 passed with stage
in 60 minutes and 4 seconds
......@@ -2230,6 +2230,8 @@ impl <'a> InstructionSelection {
// in the meantime record args that do not fit in registers
let mut stack_args : Vec<P<Value>> = vec![];
let mut gpr_arg_count = 0;
let mut fpr_arg_count = 0;
for arg in args.iter() {
if arg.is_int_reg() {
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
......@@ -2246,32 +2248,39 @@ impl <'a> InstructionSelection {
stack_args.push(arg.clone());
}
} else if arg.is_int_const() {
let arg_gpr = {
let ref reg64 = x86_64::ARGUMENT_GPRs[gpr_arg_count];
let expected_len = arg.ty.get_int_length().unwrap();
x86_64::get_alias_for_length(reg64.id(), expected_len)
};
let int_const = arg.extract_int_const();
if x86_64::is_valid_x86_imm(arg) {
let int_const = arg.extract_int_const() as i32;
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
self.backend.emit_mov_r_imm(&arg_gpr, int_const);
gpr_arg_count += 1;
if gpr_arg_count < x86_64::ARGUMENT_GPRs.len() {
let arg_gpr = {
let ref reg64 = x86_64::ARGUMENT_GPRs[gpr_arg_count];
let expected_len = arg.ty.get_int_length().unwrap();
x86_64::get_alias_for_length(reg64.id(), expected_len)
};
if x86_64::is_valid_x86_imm(arg) {
self.backend.emit_mov_r_imm(&arg_gpr, int_const as i32);
} else {
// use stack to pass argument
stack_args.push(arg.clone());
// FIXME: put the constant to memory
self.backend.emit_mov_r64_imm64(&arg_gpr, int_const as i64);
}
} else {
// FIXME: put the constant to memory
let int_const = arg.extract_int_const() as i64;
self.backend.emit_mov_r64_imm64(&arg_gpr, int_const);
gpr_arg_count += 1;
} else {
// use stack to pass argument
stack_args.push(arg.clone());
}
} else if arg.is_mem() {
unimplemented!()
} else if arg.is_fp_reg() {
if fpr_arg_count < x86_64::ARGUMENT_FPRs.len() {
let arg_fpr = x86_64::ARGUMENT_FPRs[fpr_arg_count].clone();
self.emit_move_value_to_value(&arg_fpr, &arg);
fpr_arg_count += 1;
} else {
stack_args.push(arg.clone());
}
} else {
// floating point
// struct, etc
unimplemented!()
}
}
......@@ -2433,11 +2442,14 @@ impl <'a> InstructionSelection {
for arg_index in calldata.args.iter() {
let ref arg = ops[*arg_index];
if self.match_ireg(arg) {
if self.match_iimm(arg) {
let arg = self.node_iimm_to_value(arg);
arg_values.push(arg);
} else if self.match_ireg(arg) {
let arg = self.emit_ireg(arg, f_content, f_context, vm);
arg_values.push(arg);
} else if self.match_iimm(arg) {
let arg = self.node_iimm_to_value(arg);
} else if self.match_fpreg(arg) {
let arg = self.emit_fpreg(arg, f_content, f_context, vm);
arg_values.push(arg);
} else {
unimplemented!();
......@@ -2518,11 +2530,14 @@ impl <'a> InstructionSelection {
for arg_index in calldata.args.iter() {
let ref arg = ops[*arg_index];
if self.match_ireg(arg) {
if self.match_iimm(arg) {
let arg = self.node_iimm_to_value(arg);
arg_values.push(arg);
} else if self.match_ireg(arg) {
let arg = self.emit_ireg(arg, f_content, f_context, vm);
arg_values.push(arg);
} else if self.match_iimm(arg) {
let arg = self.node_iimm_to_value(arg);
} else if self.match_fpreg(arg) {
let arg = self.emit_fpreg(arg, f_content, f_context, vm);
arg_values.push(arg);
} else {
unimplemented!();
......@@ -2565,7 +2580,7 @@ impl <'a> InstructionSelection {
let callsite = self.new_callsite_label(Some(cur_node));
self.backend.emit_call_near_mem64(callsite, &target, potentially_excepting)
} else {
unimplemented!()
panic!("unexpected callee as {}", func);
}
};
......
extern crate libloading;
use mu::ast::types::*;
use mu::ast::ir::*;
use mu::ast::ptr::*;
......@@ -7,6 +9,7 @@ use mu::compiler::*;
use std::sync::RwLock;
use std::sync::Arc;
use mu::testutil;
use mu::testutil::aot;
use mu::utils::LinkedHashMap;
......@@ -417,5 +420,82 @@ fn pass_2args_by_stack() -> VM {
blk_main
});
vm
}
#[test]
fn test_pass_fp_arg() {
let lib = testutil::compile_fncs("pass_fp_arg", vec!["pass_fp_arg", "foo"], &pass_fp_arg);
unsafe {
let pass_fp_arg : libloading::Symbol<unsafe extern fn (f64) -> f64> = lib.get(b"pass_fp_arg").unwrap();
let res1 = pass_fp_arg(0f64);
println!("pass_fp_arg(0.0) = {}", res1);
assert!(res1 == 0f64);
let res2 = pass_fp_arg(3.14f64);
println!("pass_fp_arg(3.14) = {}", res2);
assert!(res2 == 3.14f64);
}
}
fn pass_fp_arg() -> VM {
let vm = VM::new_with_opts("init_mu --disable-inline");
typedef! ((vm) double = mu_double);
// foo
funcsig! ((vm) foo_sig = (double) -> (double));
funcdecl! ((vm) <foo_sig> foo);
funcdef! ((vm) <foo_sig> foo VERSION foo_v1);
// blk_entry
ssa! ((vm, foo_v1) <double> x);
block! ((vm, foo_v1) blk_entry);
inst! ((vm, foo_v1) blk_entry_ret:
RET (x)
);
define_block! ((vm, foo_v1) blk_entry(x) {
blk_entry_ret
});
define_func_ver!((vm) foo_v1 (entry: blk_entry) {
blk_entry
});
// pass_fp_arg
funcsig! ((vm) sig = (double) -> (double));
funcdecl! ((vm) <sig> pass_fp_arg);
funcdef! ((vm) <sig> pass_fp_arg VERSION pass_fp_arg_v1);
typedef! ((vm) type_funcref_foo = mu_funcref(foo_sig));
constdef! ((vm) <type_funcref_foo> const_funcref_foo = Constant::FuncRef(vm.id_of("foo")));
// blk_entry
ssa! ((vm, pass_fp_arg_v1) <double> x);
block! ((vm, pass_fp_arg_v1) blk_entry);
ssa! ((vm, pass_fp_arg_v1) <double> res);
consta! ((vm, pass_fp_arg_v1) const_funcref_foo_local = const_funcref_foo);
inst! ((vm, pass_fp_arg_v1) blk_entry_call:
res = EXPRCALL (CallConvention::Mu, is_abort: false) const_funcref_foo_local (x)
);
inst! ((vm, pass_fp_arg_v1) blk_entry_ret:
RET (res)
);
define_block!((vm, pass_fp_arg_v1) blk_entry(x) {
blk_entry_call,
blk_entry_ret
});
define_func_ver!((vm) pass_fp_arg_v1 (entry: blk_entry) {
blk_entry
});
vm
}
\ No newline at end of file
......@@ -1158,7 +1158,6 @@ def test_rpytarget_richards():
res = run_boot_image(main, '/tmp/test_richards-mu', args=['5'])
assert res.returncode == 0, res.err
@pytest.mark.xfail(reason='expecting fix')
@may_spawn_proc
def test_dtoa():
from rpython.rlib.rdtoa import dtoa
......
......@@ -42,6 +42,7 @@ def test_rpython_dict_new_100():
fn()
@pytest.mark.xfail(reason='segment fault')
@may_spawn_proc
def test_rpython_image_dict_new_100():
def main(argv):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment