Commit 383f03b3 authored by qinsoon's avatar qinsoon

fix wrong impl about shiftiref

parent b19c268f
......@@ -3363,15 +3363,20 @@ impl <'a> InstructionSelection {
} else {
let tmp_index = self.emit_ireg(offset, f_content, f_context, vm);
// make a copy of it
// (because we may need to alter index, and we dont want to chagne the original value)
let tmp_index_copy = self.make_temporary(f_context, tmp_index.ty.clone(), vm);
self.emit_move_value_to_value(&tmp_index_copy, &tmp_index);
let scale : u8 = match ele_ty_size {
8 | 4 | 2 | 1 => ele_ty_size as u8,
16| 32| 64 => {
let shift = math::is_power_of_two(ele_ty_size).unwrap();
// scale is 8, but index = index << shift
self.backend.emit_shl_r_imm8(&tmp_index, shift as i8);
// tmp_index_copy = tmp_index_copy << index
self.backend.emit_shl_r_imm8(&tmp_index_copy, shift as i8);
8
1
}
_ => panic!("unexpected var ty size: {}", ele_ty_size)
};
......@@ -3381,7 +3386,7 @@ impl <'a> InstructionSelection {
TreeNode_::Instruction(Instruction{v: Instruction_::GetVarPartIRef{..}, ..}) => {
let mem = self.emit_get_mem_from_inst_inner(base, f_content, f_context, vm);
let ret = self.addr_append_index_scale(mem, tmp_index, scale, vm);
let ret = self.addr_append_index_scale(mem, tmp_index_copy, scale, vm);
trace!("MEM from SHIFTIREF(GETVARPARTIREF(_), ireg): {}", ret);
ret
......@@ -3393,7 +3398,7 @@ impl <'a> InstructionSelection {
let ret = MemoryLocation::Address {
base: tmp,
offset: None,
index: Some(tmp_index),
index: Some(tmp_index_copy),
scale: Some(scale)
};
......
......@@ -1368,3 +1368,181 @@ pub fn hybrid_var_part_insts() -> VM {
vm
}
#[test]
fn test_shift_iref_ele_4bytes() {
let lib = testutil::compile_fnc("shift_iref_ele_4bytes", &shift_iref_ele_4bytes);
unsafe {
let shift_iref_ele_4bytes : libloading::Symbol<unsafe extern fn(u64, u64) -> u64> = lib.get(b"shift_iref_ele_4bytes").unwrap();
let res = shift_iref_ele_4bytes(0, 0);
println!("shift_iref_ele_4bytes(0, 0) = {}", res);
assert_eq!(res, 0);
let res = shift_iref_ele_4bytes(0, 1);
println!("shift_iref_ele_4bytes(0, 1) = {}", res);
assert_eq!(res, 4);
let res = shift_iref_ele_4bytes(0, 2);
println!("shift_iref_ele_4bytes(0, 2) = {}", res);
assert_eq!(res, 8);
}
}
fn shift_iref_ele_4bytes() -> VM {
let vm = VM::new();
typedef! ((vm) int32 = mu_int(32));
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) elem = mu_struct(int32));
typedef! ((vm) iref_elem = mu_iref(elem));
funcsig! ((vm) sig = (iref_elem, int64) -> (iref_elem));
funcdecl! ((vm) <sig> shift_iref_ele_4bytes);
funcdef! ((vm) <sig> shift_iref_ele_4bytes VERSION shift_iref_ele_4bytes_v1);
// blk entry
block! ((vm, shift_iref_ele_4bytes_v1) blk_entry);
ssa! ((vm, shift_iref_ele_4bytes_v1) <iref_elem> base);
ssa! ((vm, shift_iref_ele_4bytes_v1) <int64> index);
ssa! ((vm, shift_iref_ele_4bytes_v1) <iref_elem> res);
inst! ((vm, shift_iref_ele_4bytes_v1) blk_entry_shiftiref:
res = SHIFTIREF base index (is_ptr: false)
);
inst! ((vm, shift_iref_ele_4bytes_v1) blk_entry_ret:
RET (res)
);
define_block! ((vm, shift_iref_ele_4bytes_v1) blk_entry(base, index) {
blk_entry_shiftiref, blk_entry_ret
});
define_func_ver!((vm) shift_iref_ele_4bytes_v1 (entry: blk_entry) {
blk_entry
});
vm
}
#[test]
fn test_shift_iref_ele_8bytes() {
let lib = testutil::compile_fnc("shift_iref_ele_8bytes", &shift_iref_ele_8bytes);
unsafe {
let shift_iref_ele_8bytes : libloading::Symbol<unsafe extern fn(u64, u64) -> u64> = lib.get(b"shift_iref_ele_8bytes").unwrap();
let res = shift_iref_ele_8bytes(0, 0);
println!("shift_iref_ele_8bytes(0, 0) = {}", res);
assert_eq!(res, 0);
let res = shift_iref_ele_8bytes(0, 1);
println!("shift_iref_ele_8bytes(0, 1) = {}", res);
assert_eq!(res, 8);
let res = shift_iref_ele_8bytes(0, 2);
println!("shift_iref_ele_8bytes(0, 2) = {}", res);
assert_eq!(res, 16);
}
}
fn shift_iref_ele_8bytes() -> VM {
let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) elem = mu_struct(int64));
typedef! ((vm) iref_elem = mu_iref(elem));
funcsig! ((vm) sig = (iref_elem, int64) -> (iref_elem));
funcdecl! ((vm) <sig> shift_iref_ele_8bytes);
funcdef! ((vm) <sig> shift_iref_ele_8bytes VERSION shift_iref_ele_8bytes_v1);
// blk entry
block! ((vm, shift_iref_ele_8bytes_v1) blk_entry);
ssa! ((vm, shift_iref_ele_8bytes_v1) <iref_elem> base);
ssa! ((vm, shift_iref_ele_8bytes_v1) <int64> index);
ssa! ((vm, shift_iref_ele_8bytes_v1) <iref_elem> res);
inst! ((vm, shift_iref_ele_8bytes_v1) blk_entry_shiftiref:
res = SHIFTIREF base index (is_ptr: false)
);
inst! ((vm, shift_iref_ele_8bytes_v1) blk_entry_ret:
RET (res)
);
define_block! ((vm, shift_iref_ele_8bytes_v1) blk_entry(base, index) {
blk_entry_shiftiref, blk_entry_ret
});
define_func_ver!((vm) shift_iref_ele_8bytes_v1 (entry: blk_entry) {
blk_entry
});
vm
}
#[test]
fn test_shift_iref_ele_16bytes() {
let lib = testutil::compile_fnc("shift_iref_ele_16bytes", &shift_iref_ele_16bytes);
unsafe {
let shift_iref_ele_16bytes : libloading::Symbol<unsafe extern fn(u64, u64) -> u64> = lib.get(b"shift_iref_ele_16bytes").unwrap();
let res = shift_iref_ele_16bytes(0, 0);
println!("shift_iref_ele_16bytes(0, 0) = {}", res);
assert_eq!(res, 0);
let res = shift_iref_ele_16bytes(0, 1);
println!("shift_iref_ele_16bytes(0, 1) = {}", res);
assert_eq!(res, 16);
let res = shift_iref_ele_16bytes(0, 2);
println!("shift_iref_ele_16bytes(0, 2) = {}", res);
assert_eq!(res, 32);
}
}
fn shift_iref_ele_16bytes() -> VM {
let vm = VM::new();
typedef! ((vm) int64 = mu_int(64));
typedef! ((vm) elem = mu_struct(int64, int64));
typedef! ((vm) iref_elem = mu_iref(elem));
funcsig! ((vm) sig = (iref_elem, int64) -> (iref_elem));
funcdecl! ((vm) <sig> shift_iref_ele_16bytes);
funcdef! ((vm) <sig> shift_iref_ele_16bytes VERSION shift_iref_ele_16bytes_v1);
// blk entry
block! ((vm, shift_iref_ele_16bytes_v1) blk_entry);
ssa! ((vm, shift_iref_ele_16bytes_v1) <iref_elem> base);
ssa! ((vm, shift_iref_ele_16bytes_v1) <int64> index);
ssa! ((vm, shift_iref_ele_16bytes_v1) <iref_elem> res);
inst! ((vm, shift_iref_ele_16bytes_v1) blk_entry_shiftiref:
res = SHIFTIREF base index (is_ptr: false)
);
inst! ((vm, shift_iref_ele_16bytes_v1) blk_entry_ret:
RET (res)
);
define_block! ((vm, shift_iref_ele_16bytes_v1) blk_entry(base, index) {
blk_entry_shiftiref, blk_entry_ret
});
define_func_ver!((vm) shift_iref_ele_16bytes_v1 (entry: blk_entry) {
blk_entry
});
vm
}
\ No newline at end of file
......@@ -29,7 +29,6 @@ def test_rpython_dict_new_1():
fn()
@pytest.mark.xfail(reason='segment fault')
@may_spawn_proc
def test_rpython_dict_new_100():
def new_100():
......@@ -42,18 +41,6 @@ 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):
a = {}
for i in range(0, 100):
a[i] = i
return 0
res = run_boot_image(main, '/tmp/test_image_dict_new_100', vmargs="--disable-inline")
assert res.returncode == 0, res.err
@may_spawn_proc
def test_rpython_dict_lookup():
......
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