Commit ed6a477b authored by qinsoon's avatar qinsoon

int128 const

parent 4d292d54
......@@ -915,6 +915,7 @@ impl fmt::Display for SSAVarEntry {
#[derive(Debug, Clone, PartialEq, RustcEncodable, RustcDecodable)]
pub enum Constant {
Int(u64),
IntEx(Vec<u64>),
Float(f32),
Double(f64),
// IRef(Address),
......@@ -931,6 +932,7 @@ impl fmt::Display for Constant {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
&Constant::Int(v) => write!(f, "{}", v as i64),
&Constant::IntEx(ref v) => write!(f, "IntEx {:?}", v),
&Constant::Float(v) => write!(f, "{}", v),
&Constant::Double(v) => write!(f, "{}", v),
// &Constant::IRef(v) => write!(f, "{}", v),
......
......@@ -1925,7 +1925,7 @@ impl <'a> InstructionSelection {
trace!("emit shl-iregex-iregex");
let (op1_l, op1_h) = self.emit_ireg_ex(op1, f_content, f_context, vm);
let (op2_l, op2_h) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (op2_l, _) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (res_l, res_h) = self.split_int128(&res_tmp, f_context, vm);
// mov op2_l -> ecx (we do not care higher bits)
......@@ -1996,7 +1996,7 @@ impl <'a> InstructionSelection {
trace!("emit lshr-iregex-iregex");
let (op1_l, op1_h) = self.emit_ireg_ex(op1, f_content, f_context, vm);
let (op2_l, op2_h) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (op2_l, _) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (res_l, res_h) = self.split_int128(&res_tmp, f_context, vm);
// mov op2_l -> ecx (we do not care higher bits)
......@@ -2067,7 +2067,7 @@ impl <'a> InstructionSelection {
trace!("emit ashr-iregex-iregex");
let (op1_l, op1_h) = self.emit_ireg_ex(op1, f_content, f_context, vm);
let (op2_l, op2_h) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (op2_l, _) = self.emit_ireg_ex(op2, f_content, f_context, vm);
let (res_l, res_h) = self.split_int128(&res_tmp, f_context, vm);
// mov op2_l -> ecx
......@@ -3686,9 +3686,17 @@ impl <'a> InstructionSelection {
Value_::SSAVar(_) => {
self.split_int128(pv, f_context, vm)
},
Value_::Constant(ref c) => {
unimplemented!()
}
Value_::Constant(Constant::IntEx(ref val)) => {
assert!(val.len() == 2);
let tmp_l = self.make_temporary(f_context, UINT64_TYPE.clone(), vm);
let tmp_h = self.make_temporary(f_context, UINT64_TYPE.clone(), vm);
self.backend.emit_mov_r64_imm64(&tmp_l, val[0] as i64);
self.backend.emit_mov_r64_imm64(&tmp_h, val[1] as i64);
(tmp_l, tmp_h)
},
_ => panic!("expected ireg_ex")
}
}
......
......@@ -64,6 +64,59 @@ fn add_u128() -> VM {
vm
}
#[test]
fn test_add_const_u128() {
let lib = testutil::compile_fnc("add_const_u128", &add_const_u128);
unsafe {
use std::u64;
let add_const_u128 : libloading::Symbol<unsafe extern fn(u64, u64) -> (u64, u64)> = lib.get(b"add_const_u128").unwrap();
let res = add_const_u128(1, 0);
println!("add_const_u128(1, 1) = {:?}", res);
assert!(res == (2, 0));
let res = add_const_u128(u64::MAX, 0);
println!("add_const_u128(u64::MAX, 1) = {:?}", res);
assert!(res == (0, 1));
}
}
fn add_const_u128() -> VM {
let vm = VM::new();
typedef! ((vm) u128 = mu_int(128));
constdef! ((vm) <u128> b = Constant::IntEx(vec![1, 0]));
funcsig! ((vm) sig = (u128) -> (u128));
funcdecl! ((vm) <sig> add_const_u128);
funcdef! ((vm) <sig> add_const_u128 VERSION add_const_u128_v1);
block! ((vm, add_const_u128_v1) blk_entry);
ssa! ((vm, add_const_u128_v1) <u128> a);
// sum = Add %a %b
ssa! ((vm, add_const_u128_v1) <u128> sum);
consta! ((vm, add_const_u128_v1) b_local = b);
inst! ((vm, add_const_u128_v1) blk_entry_add_const_u128:
sum = BINOP (BinOp::Add) a b_local
);
inst! ((vm, add_const_u128_v1) blk_entry_ret:
RET (sum)
);
define_block! ((vm, add_const_u128_v1) blk_entry(a) {
blk_entry_add_const_u128, blk_entry_ret
});
define_func_ver!((vm) add_const_u128_v1 (entry: blk_entry) {blk_entry});
vm
}
#[test]
fn test_mul_u128() {
let lib = testutil::compile_fnc("mul_u128", &mul_u128);
......
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