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

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

put floatingpoint constant to memory

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