Fix native qw storage for `Datacell`

next
Sayan Nandan 1 year ago
parent eca185d560
commit b25899e04b
No known key found for this signature in database
GPG Key ID: 42EEDF4AE9D96B54

@ -32,7 +32,7 @@ use {
spec::{Dataspec1D, DataspecMeta1D}, spec::{Dataspec1D, DataspecMeta1D},
tag::{CUTag, DataTag, TagClass}, tag::{CUTag, DataTag, TagClass},
}, },
mem::{NativeQword, SystemDword, WordRW}, mem::{NativeQword, SystemDword, SystemTword, WordRW},
}, },
core::{fmt, mem, mem::ManuallyDrop, slice, str}, core::{fmt, mem, mem::ManuallyDrop, slice, str},
parking_lot::RwLock, parking_lot::RwLock,
@ -213,11 +213,12 @@ impl<'a> From<LitIR<'a>> for Datacell {
match l.kind().tag_class() { match l.kind().tag_class() {
tag if tag < TagClass::Bin => unsafe { tag if tag < TagClass::Bin => unsafe {
// UNSAFE(@ohsayan): Correct because we are using the same tag, and in this case the type doesn't need any advanced construction // UNSAFE(@ohsayan): Correct because we are using the same tag, and in this case the type doesn't need any advanced construction
let [a, b] = l.data().load_double(); let data = l.data().load_qw();
let ptr = l.data().load_double()[1];
Datacell::new( Datacell::new(
CUTag::from(l.kind()), CUTag::from(l.kind()),
// DO NOT RELY ON the payload's bit pattern; it's padded // DO NOT RELY ON the payload's bit pattern; it's padded
DataRaw::word(SystemDword::store_fat(a, b)), DataRaw::word(SystemTword::store_qw_nw(data, ptr as usize)),
) )
}, },
TagClass::Bin | TagClass::Str => unsafe { TagClass::Bin | TagClass::Str => unsafe {
@ -286,7 +287,7 @@ impl Datacell {
} }
} }
unsafe fn load_word<'a, T: WordRW<NativeQword, Target<'a> = T>>(&'a self) -> T { unsafe fn load_word<'a, T: WordRW<NativeQword, Target<'a> = T>>(&'a self) -> T {
self.data.word.ld() self.data.word.dword_ld()
} }
unsafe fn _new(tag: CUTag, data: DataRaw, init: bool) -> Self { unsafe fn _new(tag: CUTag, data: DataRaw, init: bool) -> Self {
Self { init, tag, data } Self { init, tag, data }

@ -117,7 +117,7 @@ pub unsafe trait Dataspec1D: DataspecMeta1D + DataspecRaw1D {
// bool // bool
/// Load a bool (this is unsafe for logical verity) /// Load a bool (this is unsafe for logical verity)
unsafe fn read_bool_uck(&self) -> bool { unsafe fn read_bool_uck(&self) -> bool {
self.data().ld() self.data().dword_ld()
} }
/// Load a bool /// Load a bool
fn read_bool_try(&self) -> Option<bool> { fn read_bool_try(&self) -> Option<bool> {
@ -135,7 +135,7 @@ pub unsafe trait Dataspec1D: DataspecMeta1D + DataspecRaw1D {
// uint // uint
/// Load a uint (this is unsafe for logical verity) /// Load a uint (this is unsafe for logical verity)
unsafe fn read_uint_uck(&self) -> u64 { unsafe fn read_uint_uck(&self) -> u64 {
self.data().ld() self.data().dword_ld()
} }
/// Load a uint /// Load a uint
fn read_uint_try(&self) -> Option<u64> { fn read_uint_try(&self) -> Option<u64> {
@ -156,7 +156,7 @@ pub unsafe trait Dataspec1D: DataspecMeta1D + DataspecRaw1D {
// sint // sint
/// Load a sint (unsafe for logical verity) /// Load a sint (unsafe for logical verity)
unsafe fn read_sint_uck(&self) -> i64 { unsafe fn read_sint_uck(&self) -> i64 {
self.data().ld() self.data().dword_ld()
} }
/// Load a sint /// Load a sint
fn read_sint_try(&self) -> Option<i64> { fn read_sint_try(&self) -> Option<i64> {
@ -172,7 +172,7 @@ pub unsafe trait Dataspec1D: DataspecMeta1D + DataspecRaw1D {
// float // float
/// Load a float (unsafe for logical verity) /// Load a float (unsafe for logical verity)
unsafe fn read_float_uck(&self) -> f64 { unsafe fn read_float_uck(&self) -> f64 {
self.data().ld() self.data().dword_ld()
} }
/// Load a float /// Load a float
fn read_float_try(&self) -> Option<f64> { fn read_float_try(&self) -> Option<f64> {
@ -190,7 +190,7 @@ pub unsafe trait Dataspec1D: DataspecMeta1D + DataspecRaw1D {
/// ## Safety /// ## Safety
/// Are you a binary? Did you store it correctly? Are you a victim of segfaults? /// Are you a binary? Did you store it correctly? Are you a victim of segfaults?
unsafe fn read_bin_uck(&self) -> &[u8] { unsafe fn read_bin_uck(&self) -> &[u8] {
let (l, p) = self.data().ld(); let (l, p) = self.data().dword_ld();
slice::from_raw_parts(p, l) slice::from_raw_parts(p, l)
} }
/// Load a bin /// Load a bin

@ -28,6 +28,21 @@ use super::{NativeDword, NativeQword, NativeTword, SpecialPaddedWord};
static ZERO_BLOCK: [u8; 0] = []; static ZERO_BLOCK: [u8; 0] = [];
#[cfg(target_pointer_width = "32")]
fn quadsplit(q: u64) -> [usize; 2] {
unsafe {
// UNSAFE(@ohsayan): simple numeric ops
core::mem::transmute(q)
}
}
#[cfg(target_pointer_width = "32")]
fn quadmerge(v: [usize; 2]) -> u64 {
unsafe {
// UNSAFE(@ohsayan): simple numeric ops
core::mem::transmute(v)
}
}
/// Native quad pointer stack (must also be usable as a double and triple pointer stack. see [`SystemTword`] and [`SystemDword`]) /// Native quad pointer stack (must also be usable as a double and triple pointer stack. see [`SystemTword`] and [`SystemDword`])
pub trait SystemQword: SystemTword { pub trait SystemQword: SystemTword {
fn store_full(a: usize, b: usize, c: usize, d: usize) -> Self; fn store_full(a: usize, b: usize, c: usize, d: usize) -> Self;
@ -38,7 +53,7 @@ pub trait SystemQword: SystemTword {
{ {
WordRW::store(v) WordRW::store(v)
} }
fn ld<'a, T>(&'a self) -> T fn qword_ld<'a, T>(&'a self) -> T
where where
T: WordRW<Self, Target<'a> = T>, T: WordRW<Self, Target<'a> = T>,
{ {
@ -48,6 +63,10 @@ pub trait SystemQword: SystemTword {
/// Native tripe pointer stack (must also be usable as a double pointer stack, see [`SystemDword`]) /// Native tripe pointer stack (must also be usable as a double pointer stack, see [`SystemDword`])
pub trait SystemTword: SystemDword { pub trait SystemTword: SystemDword {
/// Store a quad and a native word
fn store_qw_nw(a: u64, b: usize) -> Self;
/// Load a quad and a native word
fn load_qw_nw(&self) -> (u64, usize);
fn store_full(a: usize, b: usize, c: usize) -> Self; fn store_full(a: usize, b: usize, c: usize) -> Self;
fn load_triple(&self) -> [usize; 3]; fn load_triple(&self) -> [usize; 3];
fn store<'a, T>(v: T) -> Self fn store<'a, T>(v: T) -> Self
@ -56,7 +75,7 @@ pub trait SystemTword: SystemDword {
{ {
WordRW::store(v) WordRW::store(v)
} }
fn ld<'a, T>(&'a self) -> T fn tword_ld<'a, T>(&'a self) -> T
where where
T: WordRW<Self, Target<'a> = T>, T: WordRW<Self, Target<'a> = T>,
{ {
@ -76,7 +95,7 @@ pub trait SystemDword: Sized {
{ {
WordRW::store(v) WordRW::store(v)
} }
fn ld<'a, T>(&'a self) -> T fn dword_ld<'a, T>(&'a self) -> T
where where
T: WordRW<Self, Target<'a> = T>, T: WordRW<Self, Target<'a> = T>,
{ {
@ -105,10 +124,7 @@ impl SystemDword for NativeDword {
let x; let x;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
x = unsafe { x = quadsplit(u);
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute(u)
};
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
{ {
@ -125,10 +141,7 @@ impl SystemDword for NativeDword {
let x; let x;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
x = unsafe { x = quadmerge(self.0);
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute_copy(self)
}
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
{ {
@ -151,6 +164,35 @@ impl SystemTword for NativeTword {
fn load_triple(&self) -> [usize; 3] { fn load_triple(&self) -> [usize; 3] {
self.0 self.0
} }
#[inline(always)]
fn store_qw_nw(a: u64, b: usize) -> Self {
let ret;
#[cfg(target_pointer_width = "32")]
{
let [qw_1, qw_2] = quadsplit(a);
ret = [qw_1, qw_2, b];
}
#[cfg(target_pointer_width = "64")]
{
ret = [a as usize, b, 0];
}
Self(ret)
}
#[inline(always)]
fn load_qw_nw(&self) -> (u64, usize) {
let ret;
#[cfg(target_pointer_width = "32")]
{
let qw = quadmerge([self.0[0], self.0[1]]);
let nw = self.0[2];
ret = (qw, nw);
}
#[cfg(target_pointer_width = "64")]
{
ret = (self.0[0] as u64, self.0[1]);
}
ret
}
} }
impl SystemDword for NativeTword { impl SystemDword for NativeTword {
@ -159,10 +201,7 @@ impl SystemDword for NativeTword {
let x; let x;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
let [a, b]: [usize; 2] = unsafe { let [a, b]: [usize; 2] = quadsplit(u);
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute(u)
};
x = [a, b, 0]; x = [a, b, 0];
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
@ -180,11 +219,7 @@ impl SystemDword for NativeTword {
let x; let x;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
let ab = [self.0[0], self.0[1]]; x = quadmerge([self.0[0], self.0[1]]);
x = unsafe {
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute(ab)
};
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
{ {
@ -214,6 +249,35 @@ impl SystemTword for NativeQword {
fn load_triple(&self) -> [usize; 3] { fn load_triple(&self) -> [usize; 3] {
[self.0[0], self.0[1], self.0[2]] [self.0[0], self.0[1], self.0[2]]
} }
/// Store a quadword and a native word
fn store_qw_nw(a: u64, b: usize) -> Self {
let ret;
#[cfg(target_pointer_width = "32")]
{
let [qw_1, qw_2] = quadsplit(a);
ret = [qw_1, qw_2, b, 0];
}
#[cfg(target_pointer_width = "64")]
{
ret = [a as usize, b, 0, 0];
}
Self(ret)
}
#[inline(always)]
fn load_qw_nw(&self) -> (u64, usize) {
let ret;
#[cfg(target_pointer_width = "32")]
{
let qw = quadmerge([self.0[0], self.0[1]]);
let nw = self.0[2];
ret = (qw, nw);
}
#[cfg(target_pointer_width = "64")]
{
ret = (self.0[0] as u64, self.0[1]);
}
ret
}
} }
impl SystemDword for NativeQword { impl SystemDword for NativeQword {
@ -221,10 +285,7 @@ impl SystemDword for NativeQword {
let ret; let ret;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
let [a, b]: [usize; 2] = unsafe { let [a, b] = quadsplit(u);
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute(u)
};
ret = <Self as SystemQword>::store_full(a, b, 0, 0); ret = <Self as SystemQword>::store_full(a, b, 0, 0);
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
@ -240,10 +301,7 @@ impl SystemDword for NativeQword {
let ret; let ret;
#[cfg(target_pointer_width = "32")] #[cfg(target_pointer_width = "32")]
{ {
ret = unsafe { ret = quadmerge([self.0[0], self.0[1]]);
// UNSAFE(@ohsayan): same layout and this is a stupidly simple cast and it's wild that the rust std doesn't have a simpler way to do it
core::mem::transmute([self.0[0], self.0[1]])
};
} }
#[cfg(target_pointer_width = "64")] #[cfg(target_pointer_width = "64")]
{ {

Loading…
Cancel
Save