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.6% of users enabled 2FA.

Commit 81a4c700 authored by qinsoon's avatar qinsoon
Browse files

put floatingpoint constant to memory

parent 98fee628
......@@ -26,4 +26,5 @@ lazy_static = "*"
log = "*"
simple_logger = "*"
rodal = { git = "https://gitlab.anu.edu.au/mu/rodal", version = ">= 0.0.5" }
regex = "*"
#rodal = { path = "../../../rodal_test/rodal", version = ">= 0.0.5" }
......@@ -1486,7 +1486,8 @@ pub fn mangle_name(name: MuName) -> MuName {
"__mu_".to_string() + name.as_str()
}
// WARNING: This only reverses mangle_name above when no warning is issued)
/// demangles a Mu name
// WARNING: This only reverses mangle_name above when no warning is issued)
pub fn demangle_name(mut name: MuName) -> MuName {
let name = if cfg!(target_os = "macos") && name.starts_with("___mu_") {
name.split_off(1)
......@@ -1509,57 +1510,28 @@ pub fn demangle_name(mut name: MuName) -> MuName {
name
}
// TODO: Why the hell isn't this working?
pub fn demangle_text(text: String) -> String {
let text = text.as_bytes();
let n = text.len();
let mut output = String::new();
extern crate regex;
// We have a mangled name
let mut last_i = 0; // The last i value that we dumped to output
let mut i = 0;
// TODO: this should work for utf-8 stuff right? (sinces all mangled names are in ascii)
while i < n {
let c = text[i] as char;
// We're at the beginining of the string
// wait for a word boundry
if c.is_alphanumeric() || c == '_' {
// We just found a mangled name
if text[i..].starts_with("__mu_".as_bytes()) {
output += std::str::from_utf8(&text[last_i..i]).unwrap();
let start = i;
// Find the end of the name
while i < n {
let c = text[i] as char;
if !c.is_alphanumeric() && c != '_' {
break; // We found the end!
}
i += 1;
}
/// identifies mu names and demangles them
pub fn demangle_text(text: String) -> String {
use self::regex::Regex;
output +=
demangle_name(String::from_utf8(text[start..i].to_vec()).unwrap()).as_str();
// Skip to the end of the name
last_i = i;
continue;
} else {
// Skip to the end of this alphanumeric sequence
while i < n {
let c = text[i] as char;
if !c.is_alphanumeric() && c != '_' {
break; // We found the end!
}
i += 1;
}
}
lazy_static!{
static ref IDENT_NAME: Regex = if cfg!(target_os = "macos") {
Regex::new(r"___mu_\w+").unwrap()
} else {
Regex::new(r"__mu_\w+").unwrap()
};
}
continue;
}
// Not the start of mangled name, continue
i += 1;
let mut res = text.clone();
for cap in IDENT_NAME.captures_iter(&text) {
let name = cap.get(0).unwrap().as_str().to_string();
let demangled = demangle_name(name.clone());
res = res.replacen(&name, &demangled, 1);
}
// Return output plus whatever is left of the string
output + std::str::from_utf8(&text[last_i..n]).unwrap()
res
}
......
......@@ -33,6 +33,8 @@
#[macro_use]
extern crate rodal;
#[macro_use]
extern crate log;
extern crate simple_logger;
#[macro_use]
extern crate lazy_static;
......
......@@ -3747,8 +3747,6 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
// constants in text section
file.write("\t.text\n".as_bytes()).unwrap();
// alignment for constant are 16 bytes
write_const_align(&mut file);
// write constants
for (id, constant) in cf.consts.iter() {
let mem = cf.const_mem.get(id).unwrap();
......@@ -3768,6 +3766,7 @@ pub fn emit_code(fv: &mut MuFunctionVersion, vm: &VM) {
Ok(_) => info!("emit code to {}", file_path.to_str().unwrap())
}
}
info!("write demangled code...");
// Read the file we just wrote above an demangle it
{
let mut demangled_path = path::PathBuf::new();
......@@ -3827,11 +3826,6 @@ fn check_align(align: ByteSize) -> ByteSize {
}
}
/// writes constant alignmnet (16 bytes)
fn write_const_align(f: &mut File) {
write_align(f, MAX_ALIGN);
}
/// writes alignment in bytes for linux
#[cfg(not(feature = "sel4-rumprun"))]
#[cfg(target_os = "linux")]
......@@ -3881,6 +3875,7 @@ fn write_const(f: &mut File, constant: P<Value>, loc: P<Value>) {
)
}
};
write_align(f, MAX_ALIGN);
writeln!(f, "{}:", symbol(mangle_name(label))).unwrap();
// actual value
......@@ -3930,16 +3925,14 @@ fn write_const_value(f: &mut File, constant: P<Value>) {
.unwrap();
}
&Constant::Float(val) => {
let bytes: [u8; 4] = unsafe { mem::transmute(val) };
f.write("\t.long ".as_bytes()).unwrap();
f.write(&bytes).unwrap();
f.write("\n".as_bytes()).unwrap();
use utils::mem::f32_to_raw;
f.write_fmt(format_args!("\t.long {}\n", f32_to_raw(val) as u32))
.unwrap();
}
&Constant::Double(val) => {
let bytes: [u8; 8] = unsafe { mem::transmute(val) };
f.write("\t.quad ".as_bytes()).unwrap();
f.write(&bytes).unwrap();
f.write("\n".as_bytes()).unwrap();
use utils::mem::f64_to_raw;
f.write_fmt(format_args!("\t.quad {}\n", f64_to_raw(val) as u64))
.unwrap();
}
&Constant::NullRef => f.write_fmt(format_args!("\t.quad 0\n")).unwrap(),
&Constant::ExternSym(ref name) => f.write_fmt(format_args!("\t.quad {}\n", name)).unwrap(),
......
......@@ -1018,14 +1018,12 @@ impl<'a> InstructionSelection {
// punpckldq UITOFP_C0, tmp_res -> tmp_res
// (interleaving low bytes:
// xmm = xmm[0] mem[0] xmm[1] mem[1])
let mem_c0 =
self.get_mem_for_const(UITOFP_C0.clone(), vm);
let mem_c0 = self.get_mem_for_const(&UITOFP_C0, vm);
self.backend
.emit_punpckldq_f64_mem128(&tmp_res, &mem_c0);
// subpd UITOFP_C1, tmp_res -> tmp_res
let mem_c1 =
self.get_mem_for_const(UITOFP_C1.clone(), vm);
let mem_c1 = self.get_mem_for_const(&UITOFP_C1, vm);
self.backend
.emit_subpd_f64_mem128(&tmp_res, &mem_c1);
......@@ -1206,7 +1204,7 @@ impl<'a> InstructionSelection {
// movsd FPTOUI_C_DOUBLE -> %tmp1
let mem_c =
self.get_mem_for_const(FPTOUI_C_DOUBLE.clone(), vm);
self.get_mem_for_const(&FPTOUI_C_DOUBLE, vm);
self.backend.emit_movsd_f64_mem64(&tmp1, &mem_c);
// movapd %tmp_op -> %tmp2
......@@ -1276,8 +1274,7 @@ impl<'a> InstructionSelection {
);
// movss FPTOUI_C_FLOAT -> %tmp1
let mem_c =
self.get_mem_for_const(FPTOUI_C_FLOAT.clone(), vm);
let mem_c = self.get_mem_for_const(&FPTOUI_C_FLOAT, vm);
self.backend.emit_movss_f32_mem32(&tmp1, &mem_c);
// movaps %tmp_op -> %tmp2
......@@ -3995,7 +3992,7 @@ impl<'a> InstructionSelection {
if x86_64::is_valid_x86_imm(arg) {
self.backend.emit_mov_r_imm(reg, int_const as i32);
} else {
// FIXME: put the constant to memory
assert!(reg.ty.get_int_length().unwrap() == 64);
self.backend.emit_mov_r64_imm64(reg, int_const as i64);
}
} else {
......@@ -4623,7 +4620,7 @@ impl<'a> InstructionSelection {
let arg_tys = arg_values.iter().map(|x| x.ty.clone()).collect();
let callconv = swapstack::compute_arguments(&arg_tys);
// store stack arguments first - as we may kill our own stack soon
// pass stack arguments
let mut stack_args = vec![];
for i in 0..callconv.len() {
let ref cc = callconv[i];
......@@ -4660,6 +4657,7 @@ impl<'a> InstructionSelection {
vm
);
// restore first GPR
self.backend.emit_pop_r64(&x86_64::RDI);
}
......@@ -5458,39 +5456,16 @@ impl<'a> InstructionSelection {
TreeNode_::Value(ref pv) => {
match pv.v {
Value_::SSAVar(_) => pv.clone(),
Value_::Constant(Constant::Double(val)) => {
use std::mem;
// val into u64
let val_u64: u64 = unsafe { mem::transmute(val) };
// mov val_u64 -> tmp_int
let tmp_int = self.make_temporary(f_context, UINT64_TYPE.clone(), vm);
self.backend.emit_mov_r64_imm64(&tmp_int, val_u64 as i64);
// movq tmp_int -> tmp_fp
Value_::Constant(Constant::Double(_)) => {
let mem = self.get_mem_for_const(pv, vm);
let tmp_fp = self.make_temporary(f_context, DOUBLE_TYPE.clone(), vm);
self.backend.emit_mov_fpr_r64(&tmp_fp, &tmp_int);
self.backend.emit_movsd_f64_mem64(&tmp_fp, &mem);
tmp_fp
}
Value_::Constant(Constant::Float(val)) => {
use std::mem;
// val into u32
let val_u32: u32 = unsafe { mem::transmute(val) };
// mov val_u32 -> tmp_int
let tmp_int = self.make_temporary(f_context, UINT32_TYPE.clone(), vm);
self.backend.emit_mov_r_imm(&tmp_int, val_u32 as i32);
// movq tmp_int (64) -> tmp_fp
Value_::Constant(Constant::Float(_)) => {
let mem = self.get_mem_for_const(pv, vm);
let tmp_fp = self.make_temporary(f_context, FLOAT_TYPE.clone(), vm);
self.backend.emit_mov_fpr_r64(
&tmp_fp,
unsafe { &tmp_int.as_type(UINT64_TYPE.clone()) }
);
self.backend.emit_movss_f32_mem32(&tmp_fp, &mem);
tmp_fp
}
_ => panic!("expected fpreg")
......@@ -6408,13 +6383,13 @@ impl<'a> InstructionSelection {
}
/// puts a constant in memory, and returns its memory location P<Value>
fn get_mem_for_const(&mut self, val: P<Value>, vm: &VM) -> P<Value> {
fn get_mem_for_const(&mut self, val: &P<Value>, vm: &VM) -> P<Value> {
let id = val.id();
if self.current_constants_locs.contains_key(&id) {
self.current_constants_locs.get(&id).unwrap().clone()
} else {
let const_value_loc = vm.allocate_const(val.clone());
let const_value_loc = vm.allocate_const(val);
let const_mem_val = match const_value_loc {
ValueLocation::Relocatable(_, ref name) => {
P(Value {
......
......@@ -196,13 +196,13 @@ impl ValueLocation {
pub fn from_constant(c: Constant) -> ValueLocation {
match c {
Constant::Int(int_val) => {
ValueLocation::Constant(RegGroup::GPR, utils::mem::u64_to_raw(int_val))
ValueLocation::Constant(RegGroup::GPR, utils::mem::u64_to_raw(int_val) as Word)
}
Constant::Float(f32_val) => {
ValueLocation::Constant(RegGroup::FPR, utils::mem::f32_to_raw(f32_val))
ValueLocation::Constant(RegGroup::FPR, utils::mem::f32_to_raw(f32_val) as Word)
}
Constant::Double(f64_val) => {
ValueLocation::Constant(RegGroup::FPR, utils::mem::f64_to_raw(f64_val))
ValueLocation::Constant(RegGroup::FPR, utils::mem::f64_to_raw(f64_val) as Word)
}
_ => unimplemented!()
}
......
......@@ -17,38 +17,31 @@ pub extern crate memmap;
/// secured memory operations: memset, memzero, etc.
pub extern crate memsec;
use Word;
#[allow(unused_imports)] // import both endianness (we may not use big endian though)
use byteorder::{LittleEndian, BigEndian, ReadBytesExt, WriteBytesExt, ByteOrder};
/// returns bit representations for u64
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub fn u64_to_raw(val: u64) -> Word {
pub fn u64_to_raw(val: u64) -> u64 {
let mut ret = vec![];
ret.write_u64::<LittleEndian>(val).unwrap();
as_word(ret)
LittleEndian::read_uint(&mut ret, 8)
}
/// returns bit representations for f32
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub fn f32_to_raw(val: f32) -> Word {
pub fn f32_to_raw(val: f32) -> u32 {
let mut ret = vec![];
ret.write_f32::<LittleEndian>(val).unwrap();
as_word(ret)
LittleEndian::read_uint(&mut ret, 4) as u32
}
/// returns bit representations for f64
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub fn f64_to_raw(val: f64) -> Word {
pub fn f64_to_raw(val: f64) -> u64 {
let mut ret = vec![];
ret.write_f64::<LittleEndian>(val).unwrap();
as_word(ret)
}
/// returns bit representations for Vec<u8>
#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
pub fn as_word(mut u8_array: Vec<u8>) -> Word {
LittleEndian::read_uint(&mut u8_array, 8) as Word
LittleEndian::read_uint(&mut ret, 8)
}
#[cfg(test)]
......
......@@ -557,7 +557,7 @@ impl<'a> VM {
/// allocates memory for a constant that needs to be put in memory
/// For AOT, we simply create a label for it, and let code emitter allocate the memory
#[cfg(feature = "aot")]
pub fn allocate_const(&self, val: P<Value>) -> ValueLocation {
pub fn allocate_const(&self, val: &P<Value>) -> ValueLocation {
let id = val.id();
let name = format!("CONST_{}_{}", id, val.name());
......
......@@ -319,7 +319,7 @@ fn sitofp() -> VM {
}
#[test]
fn test_ui64tofp() {
fn test_ui64tofp_simple() {
build_and_run_test!(ui64tofp, ui64tofp_test1);
build_and_run_test!(ui64tofp, ui64tofp_test2);
}
......
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