WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

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 9461cf01 authored by Isaac Oscar Gariano's avatar Isaac Oscar Gariano
Browse files

Added architecture independent parts for tagref64 implmentation

parent 87c59ebf
......@@ -67,46 +67,7 @@ impl Instruction {
Some(resume.exn_dest.target)
},
BinOp(_, _, _)
| BinOpWithStatus(_, _, _, _)
| CmpOp(_, _, _)
| ConvOp{..}
| ExprCall{..}
| ExprCCall{..}
| Load{..}
| Store{..}
| CmpXchg{..}
| AtomicRMW{..}
| New(_)
| AllocA(_)
| NewHybrid(_, _)
| AllocAHybrid(_, _)
| NewStack(_)
| NewThread(_, _)
| NewThreadExn(_, _)
| NewFrameCursor(_)
| GetIRef(_)
| GetFieldIRef{..}
| GetElementIRef{..}
| ShiftIRef{..}
| GetVarPartIRef{..}
| Fence(_)
| Return(_)
| ThreadExit
| Throw(_)
| TailCall(_)
| Branch1(_)
| Branch2{..}
| Select{..}
| WPBranch{..}
| Switch{..}
| CommonInst_GetThreadLocal
| CommonInst_SetThreadLocal(_)
| CommonInst_Pin(_)
| CommonInst_Unpin(_)
| Move(_)
| PrintHex(_)
| SetRetval(_) => None
_ => None
}
}
......@@ -315,9 +276,21 @@ pub enum Instruction_ {
CommonInst_SetThreadLocal(OpIndex),
// pin/unpin
CommonInst_Pin (OpIndex),
CommonInst_Pin(OpIndex),
CommonInst_Unpin(OpIndex),
// Tagref64 stuff
CommonInst_Tr64IsFp(OpIndex),
CommonInst_Tr64IsInt(OpIndex),
CommonInst_Tr64IsRef(OpIndex),
CommonInst_Tr64FromFp(OpIndex),
CommonInst_Tr64FromInt(OpIndex),
CommonInst_Tr64FromRef(OpIndex, OpIndex),
CommonInst_Tr64ToFp(OpIndex),
CommonInst_Tr64ToInt(OpIndex),
CommonInst_Tr64ToRef(OpIndex),
CommonInst_Tr64ToTag(OpIndex),
// internal use: mov from ops[0] to value
Move(OpIndex),
// internal use: print op as hex value
......@@ -447,6 +420,18 @@ impl Instruction_ {
&Instruction_::CommonInst_Pin(op) => format!("COMMONINST Pin {}", ops[op]),
&Instruction_::CommonInst_Unpin(op) => format!("COMMONINST Unpin {}", ops[op]),
// Tagerf64
&Instruction_::CommonInst_Tr64IsFp(op) => format!("COMMONINST Tr64IsFp {}", ops[op]),
&Instruction_::CommonInst_Tr64IsInt(op) => format!("COMMONINST Tr64IsInt {}", ops[op]),
&Instruction_::CommonInst_Tr64IsRef(op) => format!("COMMONINST Tr64IsRef {}", ops[op]),
&Instruction_::CommonInst_Tr64FromFp(op) => format!("COMMONINST Tr64FromFp {}", ops[op]),
&Instruction_::CommonInst_Tr64FromInt(op) => format!("COMMONINST Tr64FromInt {}", ops[op]),
&Instruction_::CommonInst_Tr64FromRef(op1, op2) => format!("COMMONINST Tr64FromRet {} {}", ops[op1], ops[op2]),
&Instruction_::CommonInst_Tr64ToFp(op) => format!("COMMONINST Tr64ToFp {}", ops[op]),
&Instruction_::CommonInst_Tr64ToInt(op) => format!("COMMONINST Tr64ToInt {}", ops[op]),
&Instruction_::CommonInst_Tr64ToRef(op) => format!("COMMONINST Tr64ToRef {}", ops[op]),
&Instruction_::CommonInst_Tr64ToTag(op) => format!("COMMONINST Tr64ToTag {}", ops[op]),
// move
&Instruction_::Move(from) => format!("MOVE {}", ops[from]),
// print hex
......
......@@ -17,38 +17,6 @@ use inst::Instruction_::*;
pub fn is_terminal_inst(inst: &Instruction_) -> bool {
match inst {
&BinOp(_, _, _)
| &BinOpWithStatus(_, _, _, _)
| &CmpOp(_, _, _)
| &ConvOp{..}
| &ExprCall{..}
| &ExprCCall{..}
| &Load{..}
| &Store{..}
| &CmpXchg{..}
| &AtomicRMW{..}
| &New(_)
| &AllocA(_)
| &NewHybrid(_, _)
| &AllocAHybrid(_, _)
| &NewStack(_)
| &NewThread(_, _)
| &NewThreadExn(_, _)
| &NewFrameCursor(_)
| &GetIRef(_)
| &GetFieldIRef{..}
| &GetElementIRef{..}
| &ShiftIRef{..}
| &GetVarPartIRef{..}
| &Select{..}
| &Fence(_)
| &CommonInst_GetThreadLocal
| &CommonInst_SetThreadLocal(_)
| &CommonInst_Pin(_)
| &CommonInst_Unpin(_)
| &Move(_)
| &PrintHex(_)
| &SetRetval(_) => false,
&Return(_)
| &ThreadExit
| &Throw(_)
......@@ -61,7 +29,8 @@ pub fn is_terminal_inst(inst: &Instruction_) -> bool {
| &CCall{..}
| &SwapStack{..}
| &Switch{..}
| &ExnInstruction{..} => true
| &ExnInstruction{..} => true,
_ => false,
}
}
......@@ -72,67 +41,7 @@ pub fn is_non_terminal_inst(inst: &Instruction_) -> bool {
// FIXME: check the correctness
pub fn has_side_effect(inst: &Instruction_) -> bool {
match inst {
&BinOp(_, _, _) => false,
&BinOpWithStatus(_, _, _, _) => false,
&CmpOp(_, _, _) => false,
&ConvOp{..} => false,
&ExprCall{..} => true,
&ExprCCall{..} => true,
&Load{..} => true,
&Store{..} => true,
&CmpXchg{..} => true,
&AtomicRMW{..} => true,
&New(_) => true,
&AllocA(_) => true,
&NewHybrid(_, _) => true,
&AllocAHybrid(_, _) => true,
&NewStack(_) => true,
&NewThread(_, _) => true,
&NewThreadExn(_, _) => true,
&NewFrameCursor(_) => true,
&GetIRef(_) => false,
&GetFieldIRef{..} => false,
&GetElementIRef{..} => false,
&ShiftIRef{..} => false,
&GetVarPartIRef{..} => false,
&Fence(_) => true,
&Return(_) => true,
&ThreadExit => true,
&Throw(_) => true,
&TailCall(_) => true,
&Branch1(_) => true,
&Branch2{..} => true,
&Select{..} => false,
&Watchpoint{..} => true,
&WPBranch{..} => true,
&Call{..} => true,
&CCall{..} => true,
&SwapStack{..} => true,
&Switch{..} => true,
&ExnInstruction{..} => true,
&CommonInst_GetThreadLocal => true,
&CommonInst_SetThreadLocal(_) => true,
&CommonInst_Pin(_) => true,
&CommonInst_Unpin(_) => true,
&Move(_) => false,
&PrintHex(_) => true,
&SetRetval(_) => true,
}
}
pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool {
match inst {
&Watchpoint{..}
| &Call{..}
| &CCall{..}
| &SwapStack{..}
| &ExnInstruction{..} => true,
&BinOp(_, _, _)
| &BinOpWithStatus(_, _, _, _)
| &CmpOp(_, _, _)
| &ConvOp{..}
| &ExprCall{..}
&ExprCall{..}
| &ExprCCall{..}
| &Load{..}
| &Store{..}
......@@ -146,11 +55,6 @@ pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool {
| &NewThread(_, _)
| &NewThreadExn(_, _)
| &NewFrameCursor(_)
| &GetIRef(_)
| &GetFieldIRef{..}
| &GetElementIRef{..}
| &ShiftIRef{..}
| &GetVarPartIRef{..}
| &Fence(_)
| &Return(_)
| &ThreadExit
......@@ -158,15 +62,31 @@ pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool {
| &TailCall(_)
| &Branch1(_)
| &Branch2{..}
| &Select{..}
| &Watchpoint{..}
| &WPBranch{..}
| &Call{..}
| &CCall{..}
| &SwapStack{..}
| &Switch{..}
| &ExnInstruction{..}
| &CommonInst_GetThreadLocal
| &CommonInst_SetThreadLocal(_)
| &CommonInst_Pin(_)
| &CommonInst_Unpin(_)
| &Move(_)
| &PrintHex(_)
| &SetRetval(_) => false
| &SetRetval(_) => true,
_ => false,
}
}
pub fn is_potentially_excepting_instruction(inst: &Instruction_) -> bool {
match inst {
&Watchpoint{..}
| &Call{..}
| &CCall{..}
| &SwapStack{..}
| &ExnInstruction{..} => true,
_ => false
}
}
\ No newline at end of file
......@@ -79,6 +79,17 @@ pub enum OpCode {
CommonInst_Pin,
CommonInst_Unpin,
CommonInst_Tr64IsFp,
CommonInst_Tr64IsInt,
CommonInst_Tr64IsRef,
CommonInst_Tr64FromFp,
CommonInst_Tr64FromInt,
CommonInst_Tr64FromRef,
CommonInst_Tr64ToFp,
CommonInst_Tr64ToInt,
CommonInst_Tr64ToRef,
CommonInst_Tr64ToTag,
Move,
PrintHex,
SetRetval
......@@ -391,8 +402,18 @@ pub fn pick_op_code_for_inst(inst: &Instruction) -> OpCode {
Instruction_::CommonInst_SetThreadLocal(_) => OpCode::CommonInst_SetThreadLocal,
Instruction_::CommonInst_Pin(_) => OpCode::CommonInst_Pin,
Instruction_::CommonInst_Unpin(_) => OpCode::CommonInst_Unpin,
Instruction_::Move(_) => OpCode::Move,
Instruction_::PrintHex(_) => OpCode::PrintHex,
Instruction_::SetRetval(_) => OpCode::SetRetval
Instruction_::CommonInst_Tr64IsFp(_) => OpCode::CommonInst_Tr64IsFp,
Instruction_::CommonInst_Tr64IsInt(_) => OpCode::CommonInst_Tr64IsInt,
Instruction_::CommonInst_Tr64IsRef(_) => OpCode::CommonInst_Tr64IsRef,
Instruction_::CommonInst_Tr64FromFp(_) => OpCode::CommonInst_Tr64FromFp,
Instruction_::CommonInst_Tr64FromInt(_) => OpCode::CommonInst_Tr64FromInt,
Instruction_::CommonInst_Tr64FromRef(_, _) => OpCode::CommonInst_Tr64FromRef,
Instruction_::CommonInst_Tr64ToFp(_) => OpCode::CommonInst_Tr64ToFp,
Instruction_::CommonInst_Tr64ToInt(_) => OpCode::CommonInst_Tr64ToInt,
Instruction_::CommonInst_Tr64ToRef(_) => OpCode::CommonInst_Tr64ToRef,
Instruction_::CommonInst_Tr64ToTag(_) => OpCode::CommonInst_Tr64ToTag,
Instruction_::Move(_) => OpCode::Move,
Instruction_::PrintHex(_) => OpCode::PrintHex,
Instruction_::SetRetval(_) => OpCode::SetRetval
}
}
......@@ -2758,10 +2758,10 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
&Constant::Int(val) => {
let len = ty.get_int_length().unwrap();
match len {
8 => f.write_fmt(format_args!(".byte {}\n", val as u8 )).unwrap(),
16 => f.write_fmt(format_args!(".word {}\n", val as u16)).unwrap(),
32 => f.write_fmt(format_args!(".long {}\n", val as u32)).unwrap(),
64 => f.write_fmt(format_args!(".xword {}\n", val as u64)).unwrap(),
1 ... 8 => f.write_fmt(format_args!(".byte {}\n", get_unsigned_value(val, len) as u8 )).unwrap(),
9 ... 16 => f.write_fmt(format_args!(".word {}\n", get_unsigned_value(val, len) as u16)).unwrap(),
17 ... 32 => f.write_fmt(format_args!(".long {}\n", get_unsigned_value(val, len) as u32)).unwrap(),
33 ... 64 => f.write_fmt(format_args!(".xword {}\n", get_unsigned_value(val, len) as u64)).unwrap(),
_ => panic!("unimplemented int length: {}", len)
}
}
......
......@@ -896,7 +896,8 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
Move(_) => 0,
PrintHex(_) => 10,
SetRetval(_) => 10,
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner)
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner),
_ => unimplemented!(),
}
}
......
......@@ -580,6 +580,7 @@ pub fn estimate_insts_for_ir(inst: &Instruction) -> usize {
Move(_) => 0,
PrintHex(_) => 10,
SetRetval(_) => 10,
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner)
ExnInstruction{ref inner, ..} => estimate_insts_for_ir(&inner),
_ => unimplemented!(),
}
}
......@@ -397,11 +397,7 @@ impl RegGroup {
pub fn get_from_ty(ty: &P<MuType>) -> RegGroup {
match ty.v {
// for now, only use 64bits registers
MuType_::Int(len) if len == 1 => RegGroup::GPR,
MuType_::Int(len) if len == 8 => RegGroup::GPR,
MuType_::Int(len) if len == 16 => RegGroup::GPR,
MuType_::Int(len) if len == 32 => RegGroup::GPR,
MuType_::Int(len) if len == 64 => RegGroup::GPR,
MuType_::Int(len) if len <= 64 => RegGroup::GPR,
MuType_::Int(len) if len == 128=> RegGroup::GPREX,
MuType_::Ref(_)
......
......@@ -577,6 +577,11 @@ struct BundleLoader<'lb, 'lvm> {
built_refi64: Option<P<MuType>>,
built_i1: Option<P<MuType>>,
built_i64: Option<P<MuType>>,
built_double: Option<P<MuType>>,
built_i52: Option<P<MuType>>,
built_i6: Option<P<MuType>>,
built_ref_void: Option<P<MuType>>,
built_tagref64: Option<P<MuType>>,
built_funcref_of: IdPMap<MuType>,
built_ref_of: IdPMap<MuType>,
......@@ -608,6 +613,11 @@ fn load_bundle(b: &mut MuIRBuilder) {
built_refi64: Default::default(),
built_i1: Default::default(),
built_i64: Default::default(),
built_double: Default::default(),
built_i52: Default::default(),
built_i6: Default::default(),
built_ref_void: Default::default(),
built_tagref64: Default::default(),
built_funcref_of: Default::default(),
built_ref_of: Default::default(),
built_iref_of: Default::default(),
......@@ -720,6 +730,25 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
impl_ty
}
fn ensure_i6(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_i6 {
return impl_ty.clone();
}
let id = self.vm.next_id();
let impl_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Int(6),
});
trace!("Ensure i6 is defined: {} {:?}", id, impl_ty);
self.built_types.insert(id, impl_ty.clone());
self.built_i6 = Some(impl_ty.clone());
impl_ty
}
fn ensure_i64(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_i64 {
return impl_ty.clone();
......@@ -740,6 +769,90 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
impl_ty
}
fn ensure_tagref64(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_tagref64 {
return impl_ty.clone();
}
let id = self.vm.next_id();
let impl_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Tagref64,
});
trace!("Ensure tagref64 is defined: {} {:?}", id, impl_ty);
self.built_types.insert(id, impl_ty.clone());
self.built_tagref64 = Some(impl_ty.clone());
impl_ty
}
fn ensure_i52(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_i52 {
return impl_ty.clone();
}
let id = self.vm.next_id();
let impl_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Int(52),
});
trace!("Ensure i52 is defined: {} {:?}", id, impl_ty);
self.built_types.insert(id, impl_ty.clone());
self.built_i52 = Some(impl_ty.clone());
impl_ty
}
fn ensure_double(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_double {
return impl_ty.clone();
}
let id = self.vm.next_id();
let impl_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Double,
});
trace!("Ensure double is defined: {} {:?}", id, impl_ty);
self.built_types.insert(id, impl_ty.clone());
self.built_double = Some(impl_ty.clone());
impl_ty
}
fn ensure_ref_void(&mut self) -> P<MuType> {
if let Some(ref impl_ty) = self.built_ref_void {
return impl_ty.clone();
}
let id = self.vm.next_id();
let impl_void_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Void
});
let impl_ty = P(MuType {
hdr: MuEntityHeader::unnamed(id),
v: MuType_::Ref(impl_void_ty.clone()),
});
trace!("Ensure ref<void> is defined: {} {:?}", id, impl_ty);
self.built_types.insert(id, impl_void_ty.clone());
self.built_types.insert(id, impl_ty.clone());
self.built_ref_void = Some(impl_ty.clone());
impl_ty
}
fn ensure_constint_of(&mut self, value: u64) -> P<TreeNode> {
if let Some(c) = self.built_constint_of.get(&value) {
return self.new_global(c.clone());
......@@ -2065,6 +2178,177 @@ impl<'lb, 'lvm> BundleLoader<'lb, 'lvm> {
v: Instruction_::ThreadExit
}
}
CMU_CI_UVM_TR64_IS_FP => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
// int<1>
let impl_i1 = self.ensure_i1();
let impl_opnd = self.get_treenode(fcb, args[0]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_i1).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd],
v: Instruction_::CommonInst_Tr64IsFp(0),
}
}
CMU_CI_UVM_TR64_IS_INT => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
// int<1>
let impl_i1 = self.ensure_i1();
let impl_opnd = self.get_treenode(fcb, args[0]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_i1).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd],
v: Instruction_::CommonInst_Tr64IsInt(0),
}
}
CMU_CI_UVM_TR64_IS_REF => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
// int<1>
let impl_i1 = self.ensure_i1();
let impl_opnd = self.get_treenode(fcb, args[0]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_i1).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd],
v: Instruction_::CommonInst_Tr64IsRef(0),
}
}
CMU_CI_UVM_TR64_FROM_FP => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
// tagref64
let impl_tagref64 = self.ensure_tagref64();
let impl_opnd = self.get_treenode(fcb, args[0]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_tagref64).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd],
v: Instruction_::CommonInst_Tr64FromFp(0),
}
}
CMU_CI_UVM_TR64_FROM_INT => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
// tagref64
let impl_tagref64 = self.ensure_tagref64();
let impl_opnd = self.get_treenode(fcb, args[0]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_tagref64).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd],
v: Instruction_::CommonInst_Tr64FromInt(0),
}
}
CMU_CI_UVM_TR64_FROM_REF => {
assert!(result_ids.len() == 1);
assert!(args.len() == 2);
assert!(tys.len() == 0);
// tagref64
let impl_tagref64 = self.ensure_tagref64();
let impl_opnd1 = self.get_treenode(fcb, args[0]);
let impl_opnd2 = self.get_treenode(fcb, args[1]);
let impl_rv = self.new_ssa(fcb, result_ids[0], impl_tagref64).clone_value();
Instruction {
hdr: hdr,
value: Some(vec![impl_rv]),
ops: vec![impl_opnd1, impl_opnd2],
v: Instruction_::CommonInst_Tr64FromRef(0, 1),
}
}
CMU_CI_UVM_TR64_TO_FP => {
assert!(result_ids.len() == 1);
assert!(args.len() == 1);
assert!(tys.len() == 0);
</