Merge to develop - draft2

parent 3288e8b7
......@@ -4976,11 +4976,11 @@ impl<'a> InstructionSelection {
is_native: false
})
});
// mov (got_loc) -> actual_loc
let actual_loc = self.make_temporary(f_context, pv.ty.clone(), vm);
self.emit_move_value_to_value(&actual_loc, &got_loc);
self.make_memory_op_base_offset(
&actual_loc,
0,
......
......@@ -34,7 +34,7 @@ use num::integer::lcm;
#[cfg(feature = "aot")]
pub const AOT_EMIT_CONTEXT_FILE: &'static str = "context.S";
pub const AOT_EMIT_SYM_TABLE_FILE : &'static str = "mu_sym_table.S";
pub const AOT_EMIT_SYM_TABLE_FILE: &'static str = "mu_sym_table.S";
// type alias to make backend code more readable
pub type Reg<'a> = &'a P<Value>;
......
This diff is collapsed.
......@@ -120,4 +120,4 @@ pub fn get_dylib_name(name: &'static str) -> String {
#[cfg(feature = "sel4-rumprun")]
pub fn get_dylib_name(name: &'static str) -> String {
format!("lib{}.UNKNOWN", name)
}
\ No newline at end of file
}
......@@ -104,7 +104,7 @@ use std::os::raw::c_char;
// it replaces the resolve_symbol function provided by Linux and Mac
// all other platforms (except sel4-rumprun) already provide this function
#[cfg(feature = "sel4-rumprun-target-side")]
#[link(name="zebu_c_helpers")]
#[link(name = "zebu_c_helpers")]
extern "C" {
fn c_resolve_symbol(symbol: *const c_char) -> *const c_void;
}
......@@ -238,7 +238,7 @@ pub const PRIMORDIAL_ENTRY: &'static str = "src/runtime/main.c";
/// a C wrapper as main function for executable test boot images"
/// in addition to normal main.c, it checks the returned results of tests
pub const TEST_PRIMORDIAL_ENTRY : &'static str = "src/runtime/main_test.c";
pub const TEST_PRIMORDIAL_ENTRY: &'static str = "src/runtime/main_test.c";
/// starts trace level logging, this function will be called from C
#[no_mangle]
......
......@@ -38,7 +38,7 @@ use std::fmt;
pub const STACK_SIZE: ByteSize = (4 << 20); // 4mb
/// a .25mb Mu stack for sel4-rumprun
#[cfg(feature = "sel4-rumprun")]
pub const STACK_SIZE : ByteSize = (4 << 16); // 256kb
pub const STACK_SIZE: ByteSize = (4 << 16); // 256kb
/// operating system page size
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
......
......@@ -41,4 +41,4 @@ lazy_static! {
lazy_static! {
pub static ref ZEBU_VERSION_STR : String = { "Not Available in sel4-rumprun".to_string() };
pub static ref ZEBU_VERSION_C_STR : CString = CString::new(ZEBU_VERSION_STR.clone()).unwrap();
}
\ No newline at end of file
}
......@@ -246,13 +246,13 @@ impl<'a> VM {
ret
}
/// internal function to create a VM with options for sel4-rumprun
/// default memory sizes are different from other platforms
#[cfg(feature = "sel4-rumprun")]
fn new_internal(options: VMOptions) -> VM {
VM::start_logging(options.flag_log_level);
let mut ret = VM {
next_id: ATOMIC_USIZE_INIT,
vm_options: options,
......@@ -273,12 +273,12 @@ impl<'a> VM {
compiled_callsite_table: RwLock::new(HashMap::new()),
callsite_count: ATOMIC_USIZE_INIT
};
// currently, the default sizes don't work on sel4-rumprun platform
// this is due to memory allocation size limitations
ret.vm_options.flag_gc_immixspace_size = 1<<19;
ret.vm_options.flag_gc_lospace_size = 1<<19;
ret.vm_options.flag_gc_immixspace_size = 1 << 19;
ret.vm_options.flag_gc_lospace_size = 1 << 19;
// insert all internal types
{
let mut types = ret.types.write().unwrap();
......@@ -286,16 +286,16 @@ impl<'a> VM {
types.insert(ty.id(), ty.clone());
}
}
// starts allocating ID from USER_ID_START
ret.next_id.store(USER_ID_START, Ordering::Relaxed);
// init types
types::init_types();
// init runtime
ret.init_runtime();
ret
}
......
......@@ -134,7 +134,7 @@ fn switch() -> VM {
blk_ret1,
blk_ret2
});
emit_test! ((vm)
switch, switch_test1, switch_test1_v1,
Int RET Int,
......@@ -163,7 +163,7 @@ fn switch() -> VM {
switch_sig,
int64(3u64) RET int64(99u64),
);
vm
}
......@@ -210,7 +210,7 @@ fn select_eq_zero() -> VM {
});
define_func_ver!((vm) select_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
select_eq_zero, select_eq_zero_test1, select_eq_zero_test1_v1,
Int RET Int,
......@@ -225,7 +225,7 @@ fn select_eq_zero() -> VM {
sig,
int64(1u64) RET int64(0u64),
);
vm
}
......@@ -275,7 +275,7 @@ fn select_eq_zero_double() -> VM {
});
define_func_ver!((vm) select_double_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
select_eq_zero_double, select_eq_zero_double_test1, select_eq_zero_double_test1_v1,
Int RET Double,
......@@ -290,7 +290,7 @@ fn select_eq_zero_double() -> VM {
sig,
int64(1u64) RET double(0f64),
);
vm
}
......@@ -337,7 +337,7 @@ fn select_u8_eq_zero() -> VM {
});
define_func_ver!((vm) select_u8_eq_zero_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
select_u8_eq_zero, select_u8_eq_zero_test1, select_u8_eq_zero_test1_v1,
Int RET Int,
......@@ -352,7 +352,7 @@ fn select_u8_eq_zero() -> VM {
sig,
int8(1u64) RET int8(0u64),
);
vm
}
......@@ -400,7 +400,7 @@ fn select_sge_zero() -> VM {
});
define_func_ver!((vm) select_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
select_sge_zero, select_sge_zero_test1, select_sge_zero_test1_v1,
Int RET Int,
......@@ -422,7 +422,7 @@ fn select_sge_zero() -> VM {
sig,
int64(-1i64 as u64) RET int64(0u64),
);
vm
}
......@@ -464,7 +464,7 @@ fn sgt_value() -> VM {
});
define_func_ver!((vm) sgt_value_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
sgt_value, sgt_value_test1, sgt_value_test1_v1,
Int, Int RET Int,
......@@ -486,7 +486,7 @@ fn sgt_value() -> VM {
sig,
int64(0u64), int64(255u64) RET int1(0u64),
);
vm
}
......@@ -531,7 +531,7 @@ fn sgt_u8_value() -> VM {
});
define_func_ver!((vm) sgt_u8_value_v1 (entry: blk_entry) {blk_entry});
emit_test! ((vm)
sgt_u8_value, sgt_u8_value_test1, sgt_u8_value_test1_v1,
Int, Int RET Int,
......@@ -574,7 +574,7 @@ fn sgt_u8_value() -> VM {
sig,
int8(-1i8 as u64), int8(-2i8 as u64) RET int1(1u64),
);
vm
}
......@@ -653,7 +653,7 @@ fn sgt_i32_branch() -> VM {
define_func_ver!((vm) sgt_i32_branch_v1 (entry: blk_entry) {
blk_entry, blk_ret1, blk_ret0
});
emit_test! ((vm)
sgt_i32_branch, sgt_i32_branch_test1, sgt_i32_branch_test1_v1,
Int, Int RET Int,
......@@ -717,7 +717,7 @@ fn sgt_i32_branch() -> VM {
sig,
int32(0i32 as u64), int32(0i32 as u64) RET int32(0u64),
);
vm
}
......@@ -796,7 +796,7 @@ fn sge_i32_branch() -> VM {
define_func_ver!((vm) sge_i32_branch_v1 (entry: blk_entry) {
blk_entry, blk_ret1, blk_ret0
});
emit_test! ((vm)
sge_i32_branch, sge_i32_branch_test1, sge_i32_branch_test1_v1,
Int, Int RET Int,
......@@ -860,7 +860,7 @@ fn sge_i32_branch() -> VM {
sig,
int32(0i32 as u64), int32(0i32 as u64) RET int32(1u64),
);
vm
}
......@@ -934,7 +934,7 @@ fn branch2_eq_50p_1() -> VM {
define_func_ver!((vm) branch2_eq_50p_1_v1 (entry: blk_entry) {
blk_entry, blk_true, blk_false
});
emit_test! ((vm)
branch2_eq_50p_1, branch2_eq_50p_1_test1, branch2_eq_50p_1_test1_v1,
Int RET Int,
......@@ -949,7 +949,7 @@ fn branch2_eq_50p_1() -> VM {
sig,
int8(0u64) RET int64(0u64),
);
vm
}
......@@ -1023,7 +1023,7 @@ fn branch2_eq_50p_2() -> VM {
define_func_ver!((vm) branch2_eq_50p_2_v1 (entry: blk_entry) {
blk_entry, blk_false, blk_true
});
emit_test! ((vm)
branch2_eq_50p_2, branch2_eq_50p_2_test1, branch2_eq_50p_2_test1_v1,
Int RET Int,
......@@ -1038,7 +1038,7 @@ fn branch2_eq_50p_2() -> VM {
sig,
int8(0u64) RET int64(0u64),
);
vm
}
......@@ -1137,7 +1137,7 @@ fn branch2_high_prob_branch_cannot_fallthrough() -> VM {
define_func_ver!((vm) branch2_v1 (entry: blk_entry) {
blk_entry, blk_check, blk_true, blk_false
});
emit_test! ((vm)
branch2, branch2_test1, branch2_test1_v1,
Int RET Int,
......@@ -1152,6 +1152,6 @@ fn branch2_high_prob_branch_cannot_fallthrough() -> VM {
sig,
int8(0u64) RET int64(0u64),
);
vm
}
......@@ -24,22 +24,16 @@ use self::mu::vm::*;
use self::mu::linkutils;
use mu::utils::LinkedHashMap;
#[test]
fn test_truncate_then_call() {
let lib = linkutils::aot::compile_fncs(
"truncate_then_call",
vec!["truncate_then_call", "dummy_call"],
&truncate_then_call
);
use std::sync::Arc;
use self::mu::linkutils::aot;
use self::mu::runtime::thread::check_result;
use self::mu::compiler::*;
unsafe {
let truncate_then_call: libloading::Symbol<unsafe extern "C" fn(u64) -> u32> =
lib.get(b"truncate_then_call").unwrap();
use std::f32;
let res = truncate_then_call(1);
println!("truncate_then_call(1) = {}", res);
assert!(res == 1);
}
#[test]
fn test_truncate_then_call() {
build_and_run_test!(truncate_then_call AND dummy_call, truncate_then_call_test1);
}
fn truncate_then_call() -> VM {
......@@ -110,6 +104,14 @@ fn truncate_then_call() -> VM {
define_func_ver!((vm) truncate_then_call_v1 (entry: blk_entry) {
blk_entry
});
emit_test! ((vm)
truncate_then_call, truncate_then_call_test1, truncate_then_call_test1_v1,
Int RET Int,
EQ,
sig,
u64(1u64) RET u32(1u64),
);
}
vm
......@@ -117,22 +119,24 @@ fn truncate_then_call() -> VM {
#[test]
fn test_bitcast_f32_to_u32() {
let lib = linkutils::aot::compile_fnc("bitcast_f32_to_u32", &bitcast_f32_to_u32);
unsafe {
use std::f32;
let bitcast_f32_to_u32: libloading::Symbol<unsafe extern "C" fn(f32) -> u32> =
lib.get(b"bitcast_f32_to_u32").unwrap();
let res = bitcast_f32_to_u32(f32::MAX);
println!("bitcast_f32_to_u32(f32::MAX) = {}", res);
assert!(res == 2139095039u32);
let res = bitcast_f32_to_u32(3.1415926f32);
println!("bitcast_f32_to_u32(PI) = {}", res);
assert!(res == 1078530010u32);
}
// let lib = linkutils::aot::compile_fnc("bitcast_f32_to_u32", &bitcast_f32_to_u32);
//
// unsafe {
// use std::f32;
//
// let bitcast_f32_to_u32: libloading::Symbol<unsafe extern "C" fn(f32) -> u32> =
// lib.get(b"bitcast_f32_to_u32").unwrap();
//
// let res = bitcast_f32_to_u32(f32::MAX);
// println!("bitcast_f32_to_u32(f32::MAX) = {}", res);
// assert!(res == 2139095039u32);
//
// let res = bitcast_f32_to_u32(3.1415926f32);
// println!("bitcast_f32_to_u32(PI) = {}", res);
// assert!(res == 1078530010u32);
// }
build_and_run_test!(bitcast_f32_to_u32, bitcast_f32_to_u32_test1);
build_and_run_test!(bitcast_f32_to_u32, bitcast_f32_to_u32_test2);
}
fn bitcast_f32_to_u32() -> VM {
......@@ -166,5 +170,20 @@ fn bitcast_f32_to_u32() -> VM {
blk_entry
});
emit_test! ((vm)
bitcast_f32_to_u32, bitcast_f32_to_u32_test1, bitcast_f32_to_u32_test1_v1,
Float RET Int,
EQ,
sig,
float(f32::MAX) RET u32(2139095039u32 as u64),
);
emit_test! ((vm)
bitcast_f32_to_u32, bitcast_f32_to_u32_test2, bitcast_f32_to_u32_test2_v1,
Float RET Int,
EQ,
sig,
float(3.1415926f32) RET u32(1078530010u32 as u64),
);
vm
}
......@@ -32,48 +32,8 @@ use std::sync::Arc;
#[test]
fn test_exception_throw_catch_simple() {
VM::start_logging_trace();
let vm = Arc::new(throw_catch_simple());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_throw = vm.id_of("throw_exception");
let func_catch = vm.id_of("catch_exception");
{
let funcs = vm.funcs().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
{
let func = funcs.get(&func_throw).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
{
let func = funcs.get(&func_catch).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
}
vm.set_primordial_thread(func_catch, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(
vec![Mu("throw_exception"), Mu("catch_exception")],
"throw_catch_simple_test",
&vm
);
linkutils::exec_path(executable);
build_and_run_test!(catch_exception AND throw_exception,
catch_exception_test1, throw_catch_simple);
}
fn declare_commons(vm: &VM) {
......@@ -156,6 +116,11 @@ fn create_catch_exception_func(vm: &VM, use_exception_arg: bool) {
define_func_ver!((vm) catch_exception_v1 (entry: blk_0) {
blk_0, blk_normal_cont, blk_exn_cont
});
emit_test! ((vm)
catch_exception, catch_exception_test1, catch_exception_test1_v1,
catch_exception_sig,
);
}
fn create_throw_exception_func(vm: &VM) {
......@@ -208,48 +173,8 @@ fn create_throw_exception_func(vm: &VM) {
#[test]
fn test_exception_throw_catch_dont_use_exception_arg() {
VM::start_logging_trace();
let vm = Arc::new(throw_catch_dont_use_exception_arg());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_throw = vm.id_of("throw_exception");
let func_catch = vm.id_of("catch_exception");
{
let funcs = vm.funcs().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
{
let func = funcs.get(&func_throw).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
{
let func = funcs.get(&func_catch).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
}
vm.set_primordial_thread(func_catch, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(
vec![Mu("throw_exception"), Mu("catch_exception")],
"throw_catch_simple_test",
&vm
);
linkutils::exec_path(executable);
build_and_run_test!(catch_exception AND throw_exception,
catch_exception_test1, throw_catch_dont_use_exception_arg);
}
fn throw_catch_dont_use_exception_arg() -> VM {
......@@ -265,52 +190,8 @@ fn throw_catch_dont_use_exception_arg() -> VM {
#[test]
fn test_exception_throw_catch_and_add() {
VM::start_logging_trace();
let vm = Arc::new(throw_catch_and_add());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_throw = vm.id_of("throw_exception");
let func_catch = vm.id_of("catch_and_add");
{
let funcs = vm.funcs().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
{
let func = funcs.get(&func_throw).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
{
let func = funcs.get(&func_catch).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
}
vm.set_primordial_thread(func_catch, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(
vec![Mu("throw_exception"), Mu("catch_and_add")],
"throw_catch_and_add",
&vm
);
let output = linkutils::exec_path_nocheck(executable);
// throw 1, add 0, 1, 2, 3, 4
assert!(output.status.code().is_some());
assert_eq!(output.status.code().unwrap(), 11);
build_and_run_test!(catch_and_add AND throw_exception,
catch_and_add_test1, throw_catch_and_add);
}
fn throw_catch_and_add() -> VM {
......@@ -340,7 +221,7 @@ fn create_catch_exception_and_add(vm: &VM) {
constdef! ((vm) <type_funcref_throw_exception> const_funcref_throw_exception
= Constant::FuncRef(throw_exception_id));
funcsig! ((vm) catch_exception_sig = () -> ());
funcsig! ((vm) catch_exception_sig = () -> (int64));
funcdecl! ((vm) <catch_exception_sig> catch_and_add);
funcdef! ((vm) <catch_exception_sig> catch_and_add VERSION catch_and_add_v1);
......@@ -457,10 +338,8 @@ fn create_catch_exception_and_add(vm: &VM) {
res4 = BINOP (BinOp::Add) res3 ev4
);
let blk_exception_exit = gen_ccall_exit(res4.clone(), &mut catch_and_add_v1, &vm);
inst! ((vm, catch_and_add_v1) blk_exception_ret:
RET
RET (res4)
);
define_block! ((vm, catch_and_add_v1) blk_exception(ev0, ev1, ev2, ev3, ev4) [exc_arg] {
......@@ -480,63 +359,25 @@ fn create_catch_exception_and_add(vm: &VM) {
blk_exception_add3,
blk_exception_add4,
blk_exception_exit,
blk_exception_ret
});
define_func_ver!((vm) catch_and_add_v1 (entry: blk_entry) {
blk_entry, blk_main, blk_normal, blk_exception
});
emit_test! ((vm)
catch_and_add, catch_and_add_test1, catch_and_add_test1_v1,
RET Int,
EQ,
catch_exception_sig,
RET int64(11u64),
);
}
#[test]
fn test_exception_throw_catch_twice() {
VM::start_logging_trace();
let vm = Arc::new(throw_catch_twice());
let compiler = Compiler::new(CompilerPolicy::default(), &vm);
let func_throw = vm.id_of("throw_exception");
let func_catch = vm.id_of("catch_twice");
{
let funcs = vm.funcs().read().unwrap();
let func_vers = vm.func_vers().read().unwrap();
{
let func = funcs.get(&func_throw).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
{
let func = funcs.get(&func_catch).unwrap().read().unwrap();
let mut func_ver = func_vers
.get(&func.cur_ver.unwrap())
.unwrap()
.write()
.unwrap();
compiler.compile(&mut func_ver);
}
}
vm.set_primordial_thread(func_catch, true, vec![]);
backend::emit_context(&vm);
let executable = aot::link_primordial(
vec![Mu("throw_exception"), Mu("catch_twice")],
"throw_catch_twice",
&vm
);
let output = linkutils::exec_path_nocheck(executable);
// throw 1 twice, add 1 and 1 (equals 2)
assert!(output.status.code().is_some());
assert_eq!(output.status.code().unwrap(), 2);
build_and_run_test!(catch_twice AND throw_exception, catch_twice_test1, throw_catch_twice);
}
fn throw_catch_twice() -> VM {
......@@ -562,7 +403,7 @@ fn create_catch_twice(vm: &VM) {
constdef! ((vm) <type_funcref_throw_exception> const_funcref_throw_exception
= Constant::FuncRef(throw_exception_id));
funcsig! ((vm) catch_exception_sig = () -> ());
funcsig! ((vm) catch_exception_sig = () -> (int64));
funcdecl! ((vm) <catch_exception_sig> catch_twice);
funcdef! ((vm) <catch_exception_sig> catch_twice VERSION catch_twice_v1);
......@@ -628,10 +469,8 @@ fn create_catch_twice(vm: &VM) {
res = BINOP (BinOp::Add) exc_arg1_val exc_arg2_val
);
let blk_exception2_exit = gen_ccall_exit(res.clone(), &mut catch_twice_v1, &vm);
inst! ((vm, catch_twice_v1) blk_exception2_ret:
RET
RET (res)
);
define_block! ((vm, catch_twice_v1) blk_exception2(blk_exception2_exc_arg1) [exc_arg2] {
......@@ -641,7 +480,6 @@ fn create_catch_twice(vm: &VM) {
blk_exception2_load2,
blk_exception2_add,
blk_exception2_exit,
blk_exception2_ret
});
......@@ -651,4 +489,12 @@ fn create_catch_twice(vm: &VM) {
blk_exception1,
blk_exception2
});
emit_test! ((vm)
catch_twice, catch_twice_test1, catch_twice_test1_v1,
RET Int,
EQ,
catch_exception_sig,
RET int64(2u64),
);
}
This diff is collapsed.
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