To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.7% of users enabled 2FA.

Commit 2322717d authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Merge branch 'develop' of gitlab.anu.edu.au:mu/mu-impl-fast into develop

parents 9461cf01 97122e24
......@@ -1111,7 +1111,7 @@ impl Clone for MuEntityHeader {
}
pub fn name_check(name: MuName) -> MuName {
let name = name.replace('.', "_");
let name = name.replace('.', "$");
if name.starts_with("@") || name.starts_with("%") {
let (_, name) = name.split_at(1);
......
......@@ -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;
......@@ -1190,12 +1192,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 {
......
......@@ -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
......@@ -1126,14 +1129,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")
}
},
......@@ -1369,7 +1370,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()) }
)
})
}
......@@ -1396,7 +1397,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
) })
})
}
......@@ -1408,7 +1409,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
)
})
......@@ -1417,7 +1418,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
......
......@@ -24,6 +24,7 @@ mod ir_macros;
mod test_ir;
mod test_compiler;
mod test_runtime;
mod test_api;
mod common {
use std::fmt;
......
// Copyright 2017 The Australian National University
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
mod test_tr64;
......@@ -17,6 +17,9 @@ use mu::vm::handle::*;
use mu::ast::types::*;
use mu::utils::Address;
use std::f64;
use std::mem::transmute;
/**
* Helper functions to test VM:: methods with literal values
*
......@@ -52,11 +55,11 @@ fn int52(val: u64) -> APIHandle {
}
}
fn ref_void(val: usize) -> APIHandle {
fn ref_void(val: u64) -> APIHandle {
APIHandle {
id: 0, // arbitrary
v : APIHandleValue::Ref(REF_VOID_TYPE.clone(),
unsafe { Address::from_usize(val) })
unsafe { Address::from_usize(val as usize) })
}
}
......@@ -78,65 +81,87 @@ fn test_nan_with_suffix_1_is_integer() {
assert!(vm.handle_tr64_is_int(&tr64(0xffffffffffffffffu64)));
}
// FIXME: Convert the rest of these into Rust tests, as above
/*
it should "treat a NaN with suffix 10 as a double." in {
OpHelper.tr64IsRef(0x7ff0000000000002L) shouldBe true
OpHelper.tr64IsRef(0xfff0000000000002L) shouldBe true
OpHelper.tr64IsRef(0xfffffffffffffffeL) shouldBe true
}
it should "treat other bit patterns as double" in {
OpHelper.tr64IsFP(0x0L) shouldBe true
OpHelper.tr64IsFP(0x123456789abcdef0L) shouldBe true
OpHelper.tr64IsFP(0x7ff123456789abccL) shouldBe true
OpHelper.tr64IsFP(0xfffffffffffffffcL) shouldBe true
OpHelper.tr64IsFP(doubleToRawLongBits(3.1415927)) shouldBe true
}
it should "encode integers" in {
OpHelper.intToTr64(0x0000000000000L) shouldBe 0x7ff0000000000001L
OpHelper.intToTr64(0xfffffffffffffL) shouldBe 0xffffffffffffffffL
OpHelper.intToTr64(0x5555555555555L) shouldBe 0x7ffaaaaaaaaaaaabL
OpHelper.intToTr64(0xaaaaaaaaaaaaaL) shouldBe 0xfff5555555555555L
}
it should "encode double" in {
OpHelper.fpToTr64(3.14) shouldBe java.lang.Double.doubleToRawLongBits(3.14)
OpHelper.fpToTr64(-3.14) shouldBe java.lang.Double.doubleToRawLongBits(-3.14)
OpHelper.fpToTr64(java.lang.Double.POSITIVE_INFINITY) shouldBe 0x7ff0000000000000L
OpHelper.fpToTr64(longBitsToDouble(0x7ff123456789abcdL)) shouldBe 0x7ff0000000000008L
isNaN(longBitsToDouble(OpHelper.fpToTr64(longBitsToDouble(0x7ff123456789abcdL)))) shouldBe true
}
it should "encode ref and tag" in {
OpHelper.refToTr64(0x000000000000L, 0x00L) shouldBe 0x7ff0000000000002L
OpHelper.refToTr64(0x7ffffffffff8L, 0x00L) shouldBe 0x7ff07ffffffffffaL
OpHelper.refToTr64(0xfffffffffffffff8L, 0x00L) shouldBe 0xfff07ffffffffffaL
OpHelper.refToTr64(0x000000000000L, 0x3fL) shouldBe 0x7fff800000000006L
}
it should "decode integer" in {
OpHelper.tr64ToInt(0x7ff0000000000001L) shouldBe 0
OpHelper.tr64ToInt(0xfff0000000000001L) shouldBe 0x8000000000000L
OpHelper.tr64ToInt(0xfff5555555555555L) shouldBe 0xaaaaaaaaaaaaaL
OpHelper.tr64ToInt(0x7ffaaaaaaaaaaaabL) shouldBe 0x5555555555555L
}
it should "decode double" in {
OpHelper.tr64ToFP(0x0000000000000000L) shouldBe +0.0
OpHelper.tr64ToFP(0x8000000000000000L) shouldBe -0.0
OpHelper.tr64ToFP(0x3ff0000000000000L) shouldBe 1.0
isNaN(OpHelper.tr64ToFP(0x7ff0000000000008L)) shouldBe true
}
it should "decodde ref and tag" in {
OpHelper.tr64ToRef(0x7ff0555555555552L) shouldBe 0x555555555550L
OpHelper.tr64ToRef(0xfff02aaaaaaaaaaaL) shouldBe 0xffffaaaaaaaaaaa8L
OpHelper.tr64ToTag(0x7ff0555555555552L) shouldBe 0
OpHelper.tr64ToTag(0x7fff800000000006L) shouldBe 0x3f
OpHelper.tr64ToTag(0x7ffa800000000002L) shouldBe 0x2a
OpHelper.tr64ToTag(0x7ff5000000000006L) shouldBe 0x15
}
*/
#[test]
fn test_nan_with_suffix_10_is_ref() {
let vm = VM::new();
assert!(vm.handle_tr64_is_ref(&tr64(0x7ff0000000000002u64)));
assert!(vm.handle_tr64_is_ref(&tr64(0xfff0000000000002u64)));
assert!(vm.handle_tr64_is_ref(&tr64(0xfffffffffffffffeu64)));
}
#[test]
fn test_other_bit_pattern_is_double() {
let vm = VM::new();
assert!(vm.handle_tr64_is_fp(&tr64(0x0u64)));
assert!(vm.handle_tr64_is_fp(&tr64(0x123456789abcdef0u64)));
assert!(vm.handle_tr64_is_fp(&tr64(0x7ff123456789abccu64)));
assert!(vm.handle_tr64_is_fp(&tr64(0xfffffffffffffffcu64)));
unsafe { assert!(vm.handle_tr64_is_fp(&tr64(transmute(3.1415927f64)))); }
}
#[test]
fn test_encode_int() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_from_int(&int52(0x0000000000000u64)).v.as_tr64(), 0x7ff0000000000001u64);
assert_eq!(vm.handle_tr64_from_int(&int52(0xfffffffffffffu64)).v.as_tr64(), 0xffffffffffffffffu64);
assert_eq!(vm.handle_tr64_from_int(&int52(0x5555555555555u64)).v.as_tr64(), 0x7ffaaaaaaaaaaaabu64);
assert_eq!(vm.handle_tr64_from_int(&int52(0xaaaaaaaaaaaaau64)).v.as_tr64(), 0xfff5555555555555u64);
}
#[test]
fn test_encode_double() {
let vm = VM::new();
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]
fn test_encode_tagref() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_from_ref(&ref_void(0x000000000000u64), &tag(0x00u64)).v.as_tr64(), 0x7ff0000000000002u64);
assert_eq!(vm.handle_tr64_from_ref(&ref_void(0x7ffffffffff8u64), &tag(0x00u64)).v.as_tr64(), 0x7ff07ffffffffffau64);
assert_eq!(vm.handle_tr64_from_ref(&ref_void(0xfffffffffffffff8u64), &tag(0x00u64)).v.as_tr64(), 0xfff07ffffffffffau64);
assert_eq!(vm.handle_tr64_from_ref(&ref_void(0x000000000000u64), &tag(0x3fu64)).v.as_tr64(), 0x7fff800000000006u64);
}
#[test]
fn test_decode_integer() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_to_int(&tr64(0x7ff0000000000001u64)).v.as_int(), 0u64);
assert_eq!(vm.handle_tr64_to_int(&tr64(0xfff0000000000001u64)).v.as_int(), 0x8000000000000u64);
assert_eq!(vm.handle_tr64_to_int(&tr64(0xfff5555555555555u64)).v.as_int(), 0xaaaaaaaaaaaaau64);
assert_eq!(vm.handle_tr64_to_int(&tr64(0x7ffaaaaaaaaaaaabu64)).v.as_int(), 0x5555555555555u64);
}
#[test]
fn test_decode_double() {
let vm = VM::new();
assert_eq!(vm.handle_tr64_to_fp(&tr64(0x0000000000000000u64)).v.as_double(), 0.0_f64);
assert_eq!(vm.handle_tr64_to_fp(&tr64(0x8000000000000000u64)).v.as_double(), -0.0_f64);
assert_eq!(vm.handle_tr64_to_fp(&tr64(0x3ff0000000000000u64)).v.as_double(), 1.0_f64);
assert!(vm.handle_tr64_to_fp(&tr64(0x7ff0000000000008)).v.as_double().is_nan());
}
#[test]
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, 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);
assert_eq!(vm.handle_tr64_to_tag(&tr64(0x7ff5000000000006u64)).v.as_int(), 0x15u64);
}
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