To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

Commit 225ffa5f authored by Pavel Zakopaylo's avatar Pavel Zakopaylo
Browse files

Fixed misc issues to make tr64 tests pass

-> Made API and tests use `transmute` for f64/u64 instead of `as`
-> Changed relevant logical shifts to (correctly) be arithmetic shifts
-> Fixed small typo in tests
-> (misc) Made STORE correctly handle arbitrary (< 64) sized ints
parent fbf7e93a
......@@ -22,6 +22,8 @@
// TODO: Move architecture independent codes in here, inst_sel and asm_backend to somewhere else...
pub mod inst_sel;
use utils::bit_utils::bits_ones;
mod codegen;
pub use compiler::backend::aarch64::codegen::CodeGenerator;
......@@ -1179,12 +1181,6 @@ fn hfa_length(t : P<MuType>) -> usize
}
}
#[inline(always)]
// Returns the number that has 'n' 1's in a row (i.e. 2^n-1)
pub fn bits_ones(n: usize) -> u64 {
if n == 64 { (-(1 as i64)) as u64 }
else { (1 << n) - 1 }
}
// val is an unsigned multiple of n and val/n fits in 12 bits
#[inline(always)]
pub fn is_valid_immediate_offset(val: i64, n : usize) -> bool {
......@@ -2555,4 +2551,4 @@ fn is_int_ex_reg(val: &P<Value>) -> bool
fn is_fp_reg(val: &P<Value>) -> bool
{
RegGroup::get_from_value(&val) == RegGroup::FPR && (val.is_reg() || val.is_const())
}
\ No newline at end of file
}
......@@ -26,6 +26,20 @@ pub fn lower_bits_u8(value: u8, len: usize) -> u8 {
// u64
#[inline(always)]
// Returns the number that has 'n' 1's in a row (i.e. 2^n-1)
pub fn bits_ones(n: usize) -> u64 {
if n == 64 { (-(1 as i64)) as u64 }
else { (1 << n) - 1 }
}
#[inline(always)]
pub fn u64_asr(val: u64, shift: u32) -> u64 {
let _val: i64 = val as i64;
let res: i64 = _val >> shift;
res as u64
}
#[inline(always)]
pub fn set_nth_bit_u64 (value: u64, index: usize, set_value: u8) -> u64 {
value ^ (((-(set_value as i64) as u64) ^ value) & (1 << index))
......
......@@ -41,6 +41,9 @@ use std::sync::RwLock;
use std::sync::RwLockWriteGuard;
use std::sync::atomic::{AtomicUsize, AtomicBool, ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT, Ordering};
use std;
use utils::bit_utils::{bits_ones, u64_asr};
// FIXME:
// besides fields in VM, there are some 'globals' we need to persist
// such as STRUCT_TAG_MAP
......@@ -1410,14 +1413,12 @@ impl <'a> VM {
unsafe {
match val.v {
APIHandleValue::Int(ival, bits) => {
let trunc: u64 = ival & bits_ones(bits);
match bits {
1 => addr.store::<u8>((ival as u8) & 0b1u8),
6 => addr.store::<u8>((ival as u8) & 0b111111u8),
8 => addr.store::<u8>(ival as u8),
16 => addr.store::<u16>(ival as u16),
32 => addr.store::<u32>(ival as u32),
52 => addr.store::<u64>(ival & ((1 << 51)-1)),
64 => addr.store::<u64>(ival),
1 ... 8 => addr.store::<u8>(trunc as u8),
9 ... 16 => addr.store::<u16>(trunc as u16),
17 ... 32 => addr.store::<u32>(trunc as u32),
33 ... 64 => addr.store::<u64>(trunc as u64),
_ => panic!("unimplemented int length")
}
},
......@@ -1653,7 +1654,7 @@ impl <'a> VM {
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Double(
value.v.as_tr64() as f64
unsafe { std::mem::transmute(value.v.as_tr64()) }
)
})
}
......@@ -1680,7 +1681,7 @@ impl <'a> VM {
v : APIHandleValue::Ref(types::REF_VOID_TYPE.clone(),
unsafe { Address::from_usize(
((opnd & 0x7ffffffffff8u64) |
((opnd & 0x8000000000000000u64) >> 16)) as usize
u64_asr((opnd & 0x8000000000000000u64), 16)) as usize
) })
})
}
......@@ -1692,7 +1693,7 @@ impl <'a> VM {
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Int(
(((opnd & 0x000f800000000000u64) >> 46) | ((opnd & 0x4) >> 2)),
(u64_asr((opnd & 0x000f800000000000u64), 46) | (u64_asr((opnd & 0x4), 2))),
6
)
})
......@@ -1701,7 +1702,7 @@ impl <'a> VM {
// See: `fpToTr64`
pub fn handle_tr64_from_fp(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let double_bits = value.v.as_double() as u64;
let double_bits = unsafe { std::mem::transmute(value.v.as_double()) };
let result_bits = if value.v.as_double().is_nan() {
double_bits & 0xfff8000000000000u64 | 0x0000000000000008u64
......
......@@ -18,6 +18,7 @@ use mu::ast::types::*;
use mu::utils::Address;
use std::f64;
use std::mem::transmute;
/**
* Helper functions to test VM:: methods with literal values
......@@ -97,7 +98,7 @@ fn test_other_bit_pattern_is_double() {
assert!(vm.handle_tr64_is_fp(&tr64(0x123456789abcdef0u64)));
assert!(vm.handle_tr64_is_fp(&tr64(0x7ff123456789abccu64)));
assert!(vm.handle_tr64_is_fp(&tr64(0xfffffffffffffffcu64)));
assert!(vm.handle_tr64_is_fp(&tr64(3.1415927f64 as u64)));
unsafe { assert!(vm.handle_tr64_is_fp(&tr64(transmute(3.1415927f64)))); }
}
#[test]
......@@ -114,11 +115,13 @@ fn test_encode_int() {
fn test_encode_double() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_from_fp(&double(3.14_f64)).v.as_tr64(), 3.14_f64 as u64);
assert_eq!(vm.handle_tr64_from_fp(&double(-3.14_f64)).v.as_tr64(), -3.14_f64 as u64);
assert_eq!(vm.handle_tr64_from_fp(&double(f64::INFINITY)).v.as_tr64(), 0x7ff0000000000000u64);
assert_eq!(vm.handle_tr64_from_fp(&double(0x7ff123456789abcdu64 as f64)).v.as_tr64(), 0x7ff0000000000008u64);
assert!((vm.handle_tr64_from_fp(&double(0x7ff123456789abcdu64 as f64)).v.as_tr64() as f64).is_nan());
unsafe {
assert_eq!(vm.handle_tr64_from_fp(&double(3.14_f64)).v.as_tr64(), transmute(3.14_f64));
assert_eq!(vm.handle_tr64_from_fp(&double(-3.14_f64)).v.as_tr64(), transmute(-3.14_f64));
assert_eq!(vm.handle_tr64_from_fp(&double(f64::INFINITY)).v.as_tr64(), 0x7ff0000000000000u64);
assert_eq!(vm.handle_tr64_from_fp(&double(transmute(0x7ff123456789abcdu64))).v.as_tr64(), 0x7ff0000000000008u64);
assert!(transmute::<u64, f64>((vm.handle_tr64_from_fp(&double(transmute(0x7ff123456789abcdu64))).v.as_tr64())).is_nan());
}
}
#[test]
......@@ -156,7 +159,7 @@ fn test_decode_tagref() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_to_ref(&tr64(0x7ff0555555555552u64)).v.as_ref().1.as_usize() as u64, 0x555555555550u64);
assert_eq!(vm.handle_tr64_to_ref(&tr64(0xfff02aaaaaaaaaaau64)).v.as_ref().1.as_usize() as u64, 0x555555555550u64);
assert_eq!(vm.handle_tr64_to_ref(&tr64(0xfff02aaaaaaaaaaau64)).v.as_ref().1.as_usize() as u64, 0xffffaaaaaaaaaaa8u64);
assert_eq!(vm.handle_tr64_to_tag(&tr64(0x7ff0555555555552u64)).v.as_int(), 0u64);
assert_eq!(vm.handle_tr64_to_tag(&tr64(0x7fff800000000006u64)).v.as_int(), 0x3fu64);
assert_eq!(vm.handle_tr64_to_tag(&tr64(0x7ffa800000000002u64)).v.as_int(), 0x2au64);
......
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