GitLab will be upgraded to the 12.10.14-ce.0 on 28 Sept 2020 at 2.00pm (AEDT) to 2.30pm (AEDT). During the update, GitLab and Mattermost services will not be available. If you have any concerns with this, please talk to us at N110 (b) CSIT building.

Commit b42a0385 authored by qinsoon's avatar qinsoon

implement pass floating point as argument to function

parent 872adc0f
......@@ -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