Commit a7654e7e authored by qinsoon's avatar qinsoon

[wip] more int128 test. dylib for testing includes libmu

parent db6a93a3
Pipeline #416 failed with stage
in 11 minutes and 3 seconds
......@@ -33,4 +33,5 @@ rustc-serialize = "*"
time = "0.1.34"
maplit = "0.1.4"
docopt = "0.6"
petgraph = "0.4.1"
\ No newline at end of file
petgraph = "0.4.1"
extprim = "*"
\ No newline at end of file
......@@ -2460,6 +2460,17 @@ impl CodeGenerator for ASMCodeGen {
fn emit_sub_r_mem(&mut self, dest: Reg, src: Mem) {
self.internal_binop_def_r_mem("sub", dest, src)
}
// sbb
fn emit_sbb_r_r (&mut self, dest: Reg, src: Reg) {
self.internal_binop_def_r_r("sbb", dest, src)
}
fn emit_sbb_r_mem(&mut self, dest: Reg, src: Mem) {
self.internal_binop_def_r_mem("sbb", dest, src)
}
fn emit_sbb_r_imm(&mut self, dest: Reg, src: i32) {
self.internal_binop_def_r_imm("sbb", dest, src)
}
fn emit_mul_r(&mut self, src: &P<Value>) {
let len = check_op_len(src);
......@@ -2508,6 +2519,10 @@ impl CodeGenerator for ASMCodeGen {
unimplemented!()
}
fn emit_imul_r_r(&mut self, dest: Reg, src: Reg) {
self.internal_binop_def_r_r("imul", dest, src)
}
fn emit_div_r (&mut self, src: &P<Value>) {
let len = check_op_len(src);
......
......@@ -142,10 +142,18 @@ pub trait CodeGenerator {
fn emit_sub_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_sub_r_imm(&mut self, dest: Reg, src: i32);
// sub with borrow
fn emit_sbb_r_r (&mut self, dest: Reg, src: Reg);
fn emit_sbb_r_mem(&mut self, dest: Reg, src: Mem);
fn emit_sbb_r_imm(&mut self, dest: Reg, src: i32);
// multiply
fn emit_mul_r (&mut self, src: Reg);
fn emit_mul_mem(&mut self, src: Mem);
// signed multiply
fn emit_imul_r_r(&mut self, dest: Reg, src: Reg);
// div
fn emit_div_r (&mut self, src: Reg);
fn emit_div_mem (&mut self, src: Mem);
......
......@@ -8,6 +8,7 @@ extern crate stderrlog;
extern crate maplit;
#[macro_use]
extern crate field_offset;
extern crate extprim;
#[macro_use]
pub extern crate ast;
......
......@@ -128,6 +128,46 @@ lazy_static! {
jit: RwLock::new(None)
};
pub static ref UDIV_U128 : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![UINT64_TYPE.clone(); 2],
arg_tys: vec![UINT64_TYPE.clone(); 4]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_udiv_u128")),
jit: RwLock::new(None)
};
pub static ref SDIV_I128 : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![UINT64_TYPE.clone(); 2],
arg_tys: vec![UINT64_TYPE.clone(); 4]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_sdiv_i128")),
jit: RwLock::new(None)
};
pub static ref UREM_U128 : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![UINT64_TYPE.clone(); 2],
arg_tys: vec![UINT64_TYPE.clone(); 4]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_urem_u128")),
jit: RwLock::new(None)
};
pub static ref SREM_I128 : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
hdr: MuEntityHeader::unnamed(ir::new_internal_id()),
ret_tys: vec![UINT64_TYPE.clone(); 2],
arg_tys: vec![UINT64_TYPE.clone(); 4]
}),
aot: ValueLocation::Relocatable(RegGroup::GPR, String::from("muentry_srem_i128")),
jit: RwLock::new(None)
};
// impl/decl: mod.rs
pub static ref PRINT_HEX : RuntimeEntrypoint = RuntimeEntrypoint {
sig: P(MuFuncSig {
......
......@@ -12,4 +12,31 @@ pub extern fn muentry_frem_float(a: f32, b: f32) -> f32 {
use std::ops::Rem;
a.rem(b)
}
use extprim::u128::u128;
use extprim::i128::i128;
#[no_mangle]
#[allow(unreachable_code)]
pub extern fn muentry_udiv_u128(a: u128, b: u128) -> u128 {
a.wrapping_div(b)
}
#[no_mangle]
#[allow(unreachable_code)]
pub extern fn muentry_sdiv_i128(a: i128, b: i128) -> i128 {
a.wrapping_div(b)
}
#[no_mangle]
#[allow(unreachable_code)]
pub extern fn muentry_urem_u128(a: u128, b: u128) -> u128 {
a.wrapping_rem(b)
}
#[no_mangle]
#[allow(unreachable_code)]
pub extern fn muentry_srem_i128(a: i128, b: i128) -> i128 {
a.wrapping_rem(b)
}
\ No newline at end of file
......@@ -64,6 +64,15 @@ fn link_dylib_internal (files: Vec<PathBuf>, lib: &Vec<String>, libpath: &Vec<St
let mut cc = Command::new(get_test_clang_path());
// include mu static lib
let libmu_path = if cfg!(debug_assertions) {
"target/debug/libmu.a"
} else {
"target/release/libmu.a"
};
let libmu = get_path_under_mu(libmu_path);
cc.arg(format!("{}", libmu.to_str().unwrap()));
// external libs
for path in libpath.iter() {
cc.arg(format!("-L{}", path));
......
extern crate libloading;
extern crate extprim;
use mu::ast::ir::*;
use mu::ast::inst::*;
......@@ -17,11 +18,17 @@ fn test_add_u128() {
let lib = testutil::compile_fnc("add_u128", &add_u128);
unsafe {
use std::u64;
let add_u128 : libloading::Symbol<unsafe extern fn(u64, u64, u64, u64) -> (u64, u64)> = lib.get(b"add_u128").unwrap();
let res = add_u128(1, 0, 1, 0);
println!("add_u128(1, 1) = {:?}", res);
assert!(res == (2, 0));
let res = add_u128(u64::MAX, 0, 1, 0);
println!("add_u128(u64::MAX, 1) = {:?}", res);
assert!(res == (0, 1));
}
}
......@@ -54,5 +61,112 @@ fn add_u128() -> VM {
define_func_ver!((vm) add_u128_v1 (entry: blk_entry) {blk_entry});
vm
}
#[test]
fn test_mul_u128() {
let lib = testutil::compile_fnc("mul_u128", &mul_u128);
unsafe {
use std::u64;
let mul_u128 : libloading::Symbol<unsafe extern fn(u64, u64, u64, u64) -> (u64, u64)> = lib.get(b"mul_u128").unwrap();
let res = mul_u128(6, 0, 7, 0);
println!("mul_u128(6, 7) = {:?}", res);
assert!(res == (42, 0));
let res = mul_u128(6, 6, 7, 7);
println!("mul_u128(??, ??) = {:?}", res);
assert!(res == (42, 84));
}
}
fn mul_u128() -> VM {
let vm = VM::new();
typedef! ((vm) u128 = mu_int(128));
funcsig! ((vm) sig = (u128, u128) -> (u128));
funcdecl! ((vm) <sig> mul_u128);
funcdef! ((vm) <sig> mul_u128 VERSION mul_u128_v1);
block! ((vm, mul_u128_v1) blk_entry);
ssa! ((vm, mul_u128_v1) <u128> a);
ssa! ((vm, mul_u128_v1) <u128> b);
// sum = Add %a %b
ssa! ((vm, mul_u128_v1) <u128> sum);
inst! ((vm, mul_u128_v1) blk_entry_mul_u128:
sum = BINOP (BinOp::Mul) a b
);
inst! ((vm, mul_u128_v1) blk_entry_ret:
RET (sum)
);
define_block! ((vm, mul_u128_v1) blk_entry(a, b) {
blk_entry_mul_u128, blk_entry_ret
});
define_func_ver!((vm) mul_u128_v1 (entry: blk_entry) {blk_entry});
vm
}
#[test]
fn test_udiv_u128() {
let lib = testutil::compile_fnc("udiv_u128", &udiv_u128);
unsafe {
use self::extprim::u128::u128;
let udiv_u128 : libloading::Symbol<unsafe extern fn(u64, u64, u64, u64) -> (u64, u64)> = lib.get(b"udiv_u128").unwrap();
let res = udiv_u128(42, 0, 7, 0);
println!("udiv_u128(42, 7) = {:?}", res);
assert!(res == (6, 0));
let res = udiv_u128(41, 42, 6, 7);
let a = u128::from_parts(42, 41); // hi, lo
let b = u128::from_parts(7, 6);
let expect = a.wrapping_div(b);
println!("udiv_u128(??, ??) = {:?}", res);
assert!(expect.low64() == res.0);
assert!(expect.high64() == res.1)
}
}
fn udiv_u128() -> VM {
let vm = VM::new();
typedef! ((vm) u128 = mu_int(128));
funcsig! ((vm) sig = (u128, u128) -> (u128));
funcdecl! ((vm) <sig> udiv_u128);
funcdef! ((vm) <sig> udiv_u128 VERSION udiv_u128_v1);
block! ((vm, udiv_u128_v1) blk_entry);
ssa! ((vm, udiv_u128_v1) <u128> a);
ssa! ((vm, udiv_u128_v1) <u128> b);
// sum = Add %a %b
ssa! ((vm, udiv_u128_v1) <u128> sum);
inst! ((vm, udiv_u128_v1) blk_entry_udiv_u128:
sum = BINOP (BinOp::Udiv) a b
);
inst! ((vm, udiv_u128_v1) blk_entry_ret:
RET (sum)
);
define_block! ((vm, udiv_u128_v1) blk_entry(a, b) {
blk_entry_udiv_u128, blk_entry_ret
});
define_func_ver!((vm) udiv_u128_v1 (entry: blk_entry) {blk_entry});
vm
}
\ No newline at end of file
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