Commit eab0ba47 authored by Pavel Zakopaylo's avatar Pavel Zakopaylo

Implemented tr64-related API calls

parent 0454a7fa
......@@ -109,6 +109,14 @@ impl Address {
use std::usize;
Address(usize::MAX)
}
#[inline(always)]
pub unsafe fn raw(&self) -> usize {
self.0
}
#[inline(always)]
pub unsafe fn from_raw(raw : usize) -> Address {
Address(raw)
}
}
impl PartialOrd for Address {
......
......@@ -373,43 +373,43 @@ impl MuCtx {
}
pub fn tr64_is_fp(&mut self, value: &APIHandle) -> bool {
panic!("Not implemented")
self.get_mvm().vm.handle_tr64_is_fp(value)
}
pub fn tr64_is_int(&mut self, value: &APIHandle) -> bool {
panic!("Not implemented")
self.get_mvm().vm.handle_tr64_is_int(value)
}
pub fn tr64_is_ref(&mut self, value: &APIHandle) -> bool {
panic!("Not implemented")
self.get_mvm().vm.handle_tr64_is_ref(value)
}
pub fn tr64_to_fp(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_to_fp(value))
}
pub fn tr64_to_int(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_to_int(value))
}
pub fn tr64_to_ref(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_to_ref(value))
}
pub fn tr64_to_tag(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_to_tag(value))
}
pub fn tr64_from_fp(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_from_fp(value))
}
pub fn tr64_from_int(&mut self, value: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_from_int(value))
}
pub fn tr64_from_ref(&mut self, reff: &APIHandle, tag: &APIHandle) -> *const APIHandle {
panic!("Not implemented")
prepare_handle(self.get_mvm().vm.handle_tr64_from_ref(reff, tag))
}
pub fn enable_watchpoint(&mut self, wpid: CMuWPID) {
......@@ -486,4 +486,4 @@ fn impl_memorder(order: CMuMemOrd) -> MemoryOrder {
CMU_ORD_SEQ_CST => MemoryOrder::SeqCst,
_ => panic!("invalid CMuMemOrd flag: {}", order)
}
}
\ No newline at end of file
}
......@@ -198,4 +198,11 @@ impl APIHandleValue {
_ => panic!("expected FuncRef")
}
}
}
\ No newline at end of file
pub fn as_tr64(&self) -> u64 {
match self {
&APIHandleValue::TagRef64(val) => val,
_ => panic!("expected TagRef64 handle")
}
}
}
......@@ -462,7 +462,7 @@ impl <'a> VM {
compiled_exception_table: RwLock::new(HashMap::new()),
};
// insert all intenral types
// insert all internal types
{
let mut types = ret.types.write().unwrap();
for ty in INTERNAL_TYPES.iter() {
......@@ -1623,4 +1623,130 @@ impl <'a> VM {
pub fn handle_to_ufp(&self, handle: APIHandleArg) -> Address {
handle.v.as_ufp().1
}
/**
* Functions for handling TagRef64-related API calls are taken from:
* https://gitlab.anu.edu.au/mu/mu-impl-ref2/blob/master/src/main/scala/uvm/refimpl/itpr/operationHelpers.scala
*/
// See: `tr64IsFP`
pub fn handle_tr64_is_fp(&self, value:APIHandleArg) -> bool {
let opnd = value.v.as_tr64();
(opnd & 0x7ff0000000000001u64) != 0x7ff0000000000001u64 &&
(opnd & 0x7ff0000000000003u64) != 0x7ff0000000000002u64
}
// See: `tr64IsInt`
pub fn handle_tr64_is_int(&self, value: APIHandleArg) -> bool {
let opnd = value.v.as_tr64();
(opnd & 0x7ff0000000000001u64) == 0x7ff0000000000001u64
}
// See: `tr64IsRef`
pub fn handle_tr64_is_ref(&self, value: APIHandleArg) -> bool {
let opnd = value.v.as_tr64();
(opnd & 0x7ff0000000000003u64) == 0x7ff0000000000002u64
}
// See: `tr64ToFP`
pub fn handle_tr64_to_fp(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Double(
value.v.as_tr64() as f64
)
})
}
// See: `tr64ToInt`
pub fn handle_tr64_to_int(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let opnd = value.v.as_tr64();
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Int(
(((opnd & 0xffffffffffffeu64) >> 1) | ((opnd & 0x8000000000000000u64) >> 12) & (1u64 << 51)),
52
)
})
}
// See: `tr64ToRef`
pub fn handle_tr64_to_ref(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let opnd = value.v.as_tr64();
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Ref(
// FIXME: Shouldn't I be able to refer to an existing ref<void> type??
P(
MuType::new(new_internal_id(), MuType_::muref(
P(
MuType::new(new_internal_id(), MuType_::void())
)
)
)
),
unsafe { Address::from_raw(
((opnd & 0x7ffffffffff8u64) |
(((!(((opnd & 0x8000000000000000u64) << 1) - 1)) >> 17) &
0xffff800000000000u64)) as usize
) } )
})
}
// See: `tr64ToTag`
pub fn handle_tr64_to_tag(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let opnd = value.v.as_tr64();
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::Int(
(((opnd & 0x000f800000000000u64) >> 46) | ((opnd & 0x4) >> 2)),
6
)
})
}
// See: `fpToTr64`
pub fn handle_tr64_from_fp(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let mut bits = value.v.as_double() as u64;
if value.v.as_double().is_nan() {
bits = bits & 0xfff8000000000000u64 | 0x0000000000000008u64;
}
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::TagRef64(bits)
})
}
// See: `intToTr64`
pub fn handle_tr64_from_int(&self, value: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let opnd = value.v.as_int();
self.new_handle(APIHandle {
id: handle_id,
v : APIHandleValue::TagRef64(
(0x7ff0000000000001u64 | ((opnd & 0x7ffffffffffffu64) << 1) |
((opnd & 0x8000000000000u64) << 12))
)
})
}
// See: `refToTr64`
pub fn handle_tr64_from_ref(&self, reff: APIHandleArg, tag: APIHandleArg) -> APIHandleResult {
let handle_id = self.next_id();
let (_, addr) = reff.v.as_ref();
let addr_ = unsafe { addr.raw() as u64 };
let tag_ = tag.v.as_int();
self.new_handle (APIHandle {
id: handle_id,
v : APIHandleValue::TagRef64(
(0x7ff0000000000002u64 | (addr_ & 0x7ffffffffff8u64) | ((addr_ & 0x800000000000u64) << 16)
| ((tag_ & 0x3eu64) << 46) | ((tag_ & 0x1) << 2))
)
})
}
}
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