use crate::*;
use std::ops::Index;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct ProcIntDataConfig {
config: InfParMachineConfig,
temp_buffer_len_in_bits: usize,
entry_len: usize, mem_address_len: usize, temp_buffer_len: usize, temp_buffer_last_mask: u32,
mem_address_pos_pos: usize,
mem_cell_pos: usize,
data_part_pos: usize,
rest_pos: usize,
}
impl ProcIntDataConfig {
pub fn new(config: InfParMachineConfig, env_config: InfParEnvConfig) -> Self {
let cell_len = 1usize << config.cell_len_bits;
let mem_address_len = if let Some(max_mem_size) = env_config.max_mem_size {
if (max_mem_size as u128) > ((((cell_len as u128) << 32) + 7) >> 3) {
2
} else {
1
}
} else {
2
};
let temp_buffer_len = ((env_config.max_temp_buffer_len as usize) + 31) >> 5;
let mem_address_pos_pos = mem_address_len + temp_buffer_len;
let mem_cell_pos = mem_address_pos_pos + 1;
let data_part_pos = mem_cell_pos + (((cell_len << 1) + 31) >> 5);
let rest_pos = data_part_pos + ((config.data_part_len as usize + 31) >> 5);
let rest_pos = if (config.data_part_len & 31) != 0 && (config.data_part_len & 31) <= 22 {
rest_pos - 1
} else {
rest_pos
};
let entry_len = rest_pos + 1;
Self {
config,
temp_buffer_len_in_bits: env_config.max_temp_buffer_len as usize,
entry_len,
mem_address_len,
temp_buffer_len,
temp_buffer_last_mask: if (env_config.max_temp_buffer_len & 31) != 0 {
(1u32 << (env_config.max_temp_buffer_len & 31)) - 1u32
} else {
u32::MAX
},
mem_address_pos_pos,
mem_cell_pos,
data_part_pos,
rest_pos,
}
}
#[inline]
pub fn len(&self) -> usize {
self.entry_len
}
#[inline]
pub fn mem_address_len(&self) -> usize {
self.mem_address_len << 5
}
#[inline]
pub fn config(&self) -> &InfParMachineConfig {
&self.config
}
#[inline]
pub fn temp_buffer_len_in_bits(&self) -> usize {
self.temp_buffer_len_in_bits
}
#[inline]
pub fn rest_pos(&self) -> usize {
self.rest_pos
}
#[inline]
pub fn mem_cell_pos(&self) -> usize {
self.mem_cell_pos
}
#[inline]
pub fn write_mem_cell_pos(&self) -> usize {
let cell_len = 1 << self.config.cell_len_bits;
self.mem_cell_pos + (cell_len >> 5)
}
#[inline]
pub fn data_part_pos_pos(&self) -> usize {
self.mem_address_pos_pos
}
#[inline]
pub fn data_part_pos(&self) -> usize {
self.data_part_pos
}
pub fn mem_address(&self, entry: &[u32]) -> u64 {
if self.mem_address_len >= 2 {
(entry[0] as u64) | ((entry[1] as u64) << 32)
} else {
entry[0] as u64
}
}
pub fn mem_address_all(&self, entry: &[u32]) -> Vec<u32> {
Vec::from(&entry[0..self.mem_address_len])
}
pub fn mem_address_slice(&self, entry: &[u32], out: &mut [u32]) -> usize {
out[0..self.mem_address_len].copy_from_slice(&entry[0..self.mem_address_len]);
self.mem_address_len
}
pub fn temp_buffer(&self, entry: &[u32]) -> Vec<u32> {
let mut wds =
Vec::from(&entry[self.mem_address_len..self.mem_address_len + self.temp_buffer_len]);
*wds.last_mut().unwrap() &= self.temp_buffer_last_mask;
wds
}
pub fn temp_buffer_slice(&self, entry: &[u32], out: &mut [u32]) -> usize {
out[0..self.temp_buffer_len].copy_from_slice(
&entry[self.mem_address_len..self.mem_address_len + self.temp_buffer_len],
);
out[self.temp_buffer_len - 1] &= self.temp_buffer_last_mask;
self.temp_buffer_len
}
pub fn mem_address_pos(&self, entry: &[u32]) -> u32 {
entry[self.mem_address_pos_pos] & 0xff
}
pub fn temp_buffer_pos(&self, entry: &[u32]) -> u32 {
(entry[self.mem_address_pos_pos] >> 8) & 0xffff
}
pub fn proc_id_pos(&self, entry: &[u32]) -> u32 {
entry[self.mem_address_pos_pos] >> 24
}
pub fn read_mem_cell(&self, entry: &[u32]) -> u64 {
let cell_len = 1 << self.config.cell_len_bits;
if cell_len <= 32 {
(entry[self.mem_cell_pos] as u64) & ((1u64 << cell_len) - 1u64)
} else {
(entry[self.mem_cell_pos] as u64) | ((entry[self.mem_cell_pos + 1] as u64) << 32)
}
}
pub fn read_mem_cell_all(&self, entry: &[u32]) -> Vec<u32> {
let cell_len = 1 << self.config.cell_len_bits;
if cell_len <= 32 {
vec![entry[self.mem_cell_pos] & u32::try_from((1u64 << cell_len) - 1u64).unwrap()]
} else {
Vec::from(&entry[self.mem_cell_pos..self.mem_cell_pos + (cell_len >> 5)])
}
}
pub fn read_mem_cell_slice(&self, entry: &[u32], out: &mut [u32]) -> usize {
let cell_len = 1 << self.config.cell_len_bits;
if cell_len <= 32 {
out[0] = entry[self.mem_cell_pos] & u32::try_from((1u64 << cell_len) - 1u64).unwrap();
1
} else {
let cell_len_in_dwords = (cell_len >> 5) as usize;
out[0..cell_len_in_dwords]
.copy_from_slice(&entry[self.mem_cell_pos..self.mem_cell_pos + cell_len_in_dwords]);
cell_len_in_dwords
}
}
pub fn set_read_mem_cell_all(&self, entry: &mut [u32], mem_cell: &[u32]) {
let cell_len = 1 << self.config.cell_len_bits;
if cell_len <= 16 {
entry[self.mem_cell_pos] = (entry[self.mem_cell_pos] & 0xffff0000)
| (mem_cell[0] & ((1u32 << cell_len) - 1u32));
} else if cell_len <= 32 {
entry[self.mem_cell_pos] = mem_cell[0];
} else {
entry[self.mem_cell_pos..self.mem_cell_pos + (cell_len >> 5)].copy_from_slice(mem_cell);
}
}
pub fn write_mem_cell(&self, entry: &[u32]) -> u64 {
let cell_len = 1 << self.config.cell_len_bits;
let mem_cell_pos_2 = self.mem_cell_pos + (cell_len >> 5);
if cell_len <= 16 {
((entry[self.mem_cell_pos] as u64) >> 16) & ((1u64 << cell_len) - 1u64)
} else if cell_len <= 32 {
(entry[mem_cell_pos_2] as u64) & ((1u64 << cell_len) - 1u64)
} else {
(entry[mem_cell_pos_2] as u64) | ((entry[mem_cell_pos_2 + 1] as u64) << 32)
}
}
pub fn write_mem_cell_all(&self, entry: &[u32]) -> Vec<u32> {
let cell_len = 1 << self.config.cell_len_bits;
let mem_cell_pos_2 = self.mem_cell_pos + (cell_len >> 5);
if cell_len <= 16 {
vec![(entry[self.mem_cell_pos] >> 16) & ((1u32 << cell_len) - 1u32)]
} else if cell_len <= 32 {
vec![entry[mem_cell_pos_2] & u32::try_from((1u64 << cell_len) - 1u64).unwrap()]
} else {
Vec::from(&entry[mem_cell_pos_2..mem_cell_pos_2 + (cell_len >> 5)])
}
}
pub fn write_mem_cell_slice(&self, entry: &[u32], out: &mut [u32]) -> usize {
let cell_len = 1 << self.config.cell_len_bits;
let mem_cell_pos_2 = self.mem_cell_pos + (cell_len >> 5);
if cell_len <= 16 {
out[0] = (entry[self.mem_cell_pos] >> 16)
& u32::try_from((1u64 << cell_len) - 1u64).unwrap();
1
} else if cell_len <= 32 {
out[0] = entry[mem_cell_pos_2] & u32::try_from((1u64 << cell_len) - 1u64).unwrap();
1
} else {
let cell_len_in_dwords = (cell_len >> 5) as usize;
out[0..cell_len_in_dwords]
.copy_from_slice(&entry[mem_cell_pos_2..mem_cell_pos_2 + cell_len_in_dwords]);
cell_len_in_dwords
}
}
pub fn mem_access(&self, entry: &[u32]) -> DataAccess {
match (entry[self.rest_pos] >> 22) & 3 {
0 => DataAccess::Nothing,
1 => DataAccess::ReadOnly,
2 => DataAccess::WriteOnly,
3 => DataAccess::ReadWrite,
_ => {
panic!("Unexpected!")
}
}
}
pub fn mem_access_raw(&self, entry: &[u32]) -> u32 {
(entry[self.rest_pos] >> 22) & 3
}
pub fn mem_read(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> 22) & 1) != 0
}
pub fn mem_write(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> 22) & 2) != 0
}
pub fn read_data_part(&self, entry: &[u32]) -> u64 {
let dp_len = self.config.data_part_len as usize;
if dp_len <= 32 {
(entry[self.data_part_pos] as u64) & ((1u64 << dp_len) - 1u64)
} else {
let wd =
(entry[self.data_part_pos] as u64) | ((entry[self.data_part_pos + 1] as u64) << 32);
if dp_len < 64 {
wd & ((1u64 << dp_len) - 1u64)
} else {
wd
}
}
}
pub fn read_data_part_all(&self, entry: &[u32]) -> Vec<u32> {
let dp_len = self.config.data_part_len as usize;
if dp_len <= 32 {
vec![entry[self.data_part_pos] & u32::try_from((1u64 << dp_len) - 1u64).unwrap()]
} else {
let mut wds =
Vec::from(&entry[self.data_part_pos..self.data_part_pos + ((dp_len + 31) >> 5)]);
if (dp_len & 31) != 0 {
*wds.last_mut().unwrap() &= (1u32 << (dp_len & 31)) - 1;
}
wds
}
}
pub fn read_data_part_slice(&self, entry: &[u32], out: &mut [u32]) -> usize {
let dp_len = self.config.data_part_len as usize;
if dp_len <= 32 {
out[0] = entry[self.data_part_pos] & u32::try_from((1u64 << dp_len) - 1u64).unwrap();
1
} else {
let dp_len_in_dwords = ((dp_len + 31) >> 5) as usize;
out[0..dp_len_in_dwords]
.copy_from_slice(&entry[self.data_part_pos..self.data_part_pos + dp_len_in_dwords]);
if (dp_len & 31) != 0 {
out[dp_len_in_dwords - 1] &= (1u32 << (dp_len & 31)) - 1;
}
dp_len_in_dwords
}
}
pub fn data_part_access(&self, entry: &[u32]) -> DataAccess {
match (entry[self.rest_pos] >> (22 + 2)) & 3 {
0 => DataAccess::Nothing,
1 => DataAccess::ReadOnly,
2 => DataAccess::WriteOnly,
3 => DataAccess::ReadWrite,
_ => {
panic!("Unexpected!")
}
}
}
pub fn data_part_access_raw(&self, entry: &[u32]) -> u32 {
(entry[self.rest_pos] >> (22 + 2)) & 3
}
pub fn data_part_read(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> 22) & 4) != 0
}
pub fn data_part_write(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> 22) & 8) != 0
}
pub fn data_move_dir(&self, entry: &[u32]) -> DataPartMove {
match (entry[self.rest_pos] >> (22 + 4)) & 3 {
0 => DataPartMove::Nothing,
1 => DataPartMove::Forward,
2 => DataPartMove::Backward,
3 => DataPartMove::Backward,
_ => {
panic!("Unexpected!")
}
}
}
pub fn data_move_dir_raw(&self, entry: &[u32]) -> u32 {
(entry[self.rest_pos] >> (22 + 4)) & 3
}
pub fn data_kind(&self, entry: &[u32]) -> DataKind {
match (entry[self.rest_pos] >> (22 + 6)) & 3 {
0 => DataKind::MemAddress,
1 => DataKind::TempBuffer,
2 => DataKind::ProcId,
3 => DataKind::ProcId,
_ => {
panic!("Unexpected!")
}
}
}
pub fn data_kind_raw(&self, entry: &[u32]) -> u32 {
(entry[self.rest_pos] >> (22 + 6)) & 3
}
pub fn stop_machine(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> (22 + 8)) & 1) != 0
}
pub fn data_part_move_done(&self, entry: &[u32]) -> bool {
((entry[self.rest_pos] >> (22 + 9)) & 1) != 0
}
}
pub struct ProcIntDataReader {
data: Vec<u32>,
data_config: ProcIntDataConfig,
}
impl ProcIntDataReader {
pub fn new(config: InfParMachineConfig, env_config: InfParEnvConfig, data: Vec<u32>) -> Self {
let data_config = ProcIntDataConfig::new(config, env_config);
assert_eq!(data.len() % data_config.entry_len, 0);
Self { data, data_config }
}
pub fn new_from_config(data_config: ProcIntDataConfig, data: Vec<u32>) -> Self {
assert_eq!(data.len() % data_config.entry_len, 0);
Self { data, data_config }
}
#[inline]
pub fn data_config(&self) -> &ProcIntDataConfig {
&self.data_config
}
}
impl Index<u64> for ProcIntDataReader {
type Output = [u32];
#[inline]
fn index(&self, index: u64) -> &Self::Output {
let offset = usize::try_from(index)
.unwrap()
.checked_mul(self.data_config.entry_len)
.unwrap();
&self.data[offset..offset + self.data_config.entry_len]
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_proc_int_data_reader() {
let mut temps = [0, 0, 0, 0, 0, 0, 0, 0, 0];
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 7,
cell_len_bits: 3,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 24,
max_mem_size: Some(20 * (1 << 20)),
};
let dh = vec![
24412, 0xabcdef11, 0x1a2b3c4d, 0x1ba3 | (0xcd1 << 16), 0x7ce3 | (0b1001101001 << 22), 5960215, 0xc0a09d51, 0x3046da1c, 0x2a16 | (0x5a1 << 16), 0x6671 | (0b0110000110 << 22), ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(24412, dc.mem_address(&pidr[0]));
assert_eq!(vec![24412], dc.mem_address_all(&pidr[0]));
assert_eq!(1, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!(24412, temps[0]);
assert_eq!(vec![0xcdef11], dc.temp_buffer(&pidr[0]));
assert_eq!(1, dc.temp_buffer_slice(&pidr[0], &mut temps));
assert_eq!(0xcdef11, temps[0]);
assert_eq!(0x4d, dc.mem_address_pos(&pidr[0]));
assert_eq!(0x2b3c, dc.temp_buffer_pos(&pidr[0]));
assert_eq!(0x1a, dc.proc_id_pos(&pidr[0]));
assert_eq!(0xa3, dc.read_mem_cell(&pidr[0]));
assert_eq!(vec![0xa3], dc.read_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.read_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0xa3, temps[0]);
assert_eq!(0xd1, dc.write_mem_cell(&pidr[0]));
assert_eq!(vec![0xd1], dc.write_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.write_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0xd1, temps[0]);
assert_eq!(0x63, dc.read_data_part(&pidr[0]));
assert_eq!(vec![0x63], dc.read_data_part_all(&pidr[0]));
assert_eq!(1, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!(0x63, temps[0]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(true, dc.mem_read(&pidr[0]));
assert_eq!(false, dc.mem_write(&pidr[0]));
assert_eq!(false, dc.data_part_read(&pidr[0]));
assert_eq!(true, dc.data_part_write(&pidr[0]));
assert_eq!(DataPartMove::Backward, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::TempBuffer, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
assert_eq!(5960215, dc.mem_address(&pidr[1]));
assert_eq!(vec![5960215], dc.mem_address_all(&pidr[1]));
assert_eq!(1, dc.mem_address_slice(&pidr[1], &mut temps));
assert_eq!(5960215, temps[0]);
assert_eq!(vec![0xa09d51], dc.temp_buffer(&pidr[1]));
assert_eq!(1, dc.temp_buffer_slice(&pidr[1], &mut temps));
assert_eq!(0xa09d51, temps[0]);
assert_eq!(0x1c, dc.mem_address_pos(&pidr[1]));
assert_eq!(0x46da, dc.temp_buffer_pos(&pidr[1]));
assert_eq!(0x30, dc.proc_id_pos(&pidr[1]));
assert_eq!(0x16, dc.read_mem_cell(&pidr[1]));
assert_eq!(vec![0x16], dc.read_mem_cell_all(&pidr[1]));
assert_eq!(1, dc.read_mem_cell_slice(&pidr[1], &mut temps));
assert_eq!(0x16, temps[0]);
assert_eq!(0xa1, dc.write_mem_cell(&pidr[1]));
assert_eq!(vec![0xa1], dc.write_mem_cell_all(&pidr[1]));
assert_eq!(1, dc.write_mem_cell_slice(&pidr[1], &mut temps));
assert_eq!(0xa1, temps[0]);
assert_eq!(0x71, dc.read_data_part(&pidr[1]));
assert_eq!(vec![0x71], dc.read_data_part_all(&pidr[1]));
assert_eq!(1, dc.read_data_part_slice(&pidr[1], &mut temps));
assert_eq!(0x71, temps[0]);
assert_eq!(DataAccess::WriteOnly, dc.mem_access(&pidr[1]));
assert_eq!(DataAccess::ReadOnly, dc.data_part_access(&pidr[1]));
assert_eq!(false, dc.mem_read(&pidr[1]));
assert_eq!(true, dc.mem_write(&pidr[1]));
assert_eq!(true, dc.data_part_read(&pidr[1]));
assert_eq!(false, dc.data_part_write(&pidr[1]));
assert_eq!(DataPartMove::Nothing, dc.data_move_dir(&pidr[1]));
assert_eq!(DataKind::ProcId, dc.data_kind(&pidr[1]));
assert_eq!(false, dc.data_part_move_done(&pidr[1]));
assert_eq!(true, dc.stop_machine(&pidr[1]));
let mut entry = pidr[0].to_vec();
dc.set_read_mem_cell_all(&mut entry, &[0xda45]);
assert_eq!(0x45, dc.read_mem_cell(&entry));
assert_eq!(0xd1, dc.write_mem_cell(&entry));
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 7,
cell_len_bits: 3,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 64,
max_mem_size: Some(20 * (1 << 20)),
};
let dh = vec![
24412, 0xabcdef11, 0xca03916e, 0x1a2b3c4d, 0x1ba3 | (0xcd1 << 16), 0x7ce3 | (0b1011111001 << 22), ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(24412, dc.mem_address(&pidr[0]));
assert_eq!(vec![24412], dc.mem_address_all(&pidr[0]));
assert_eq!(1, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!(24412, temps[0]);
assert_eq!(vec![0xabcdef11, 0xca03916e], dc.temp_buffer(&pidr[0]));
assert_eq!(2, dc.temp_buffer_slice(&pidr[0], &mut temps));
assert_eq!([0xabcdef11, 0xca03916e], temps[0..2]);
assert_eq!(0x4d, dc.mem_address_pos(&pidr[0]));
assert_eq!(0x2b3c, dc.temp_buffer_pos(&pidr[0]));
assert_eq!(0x1a, dc.proc_id_pos(&pidr[0]));
assert_eq!(0xa3, dc.read_mem_cell(&pidr[0]));
assert_eq!(vec![0xa3], dc.read_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.read_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0xa3, temps[0]);
assert_eq!(0xd1, dc.write_mem_cell(&pidr[0]));
assert_eq!(vec![0xd1], dc.write_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.write_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0xd1, temps[0]);
assert_eq!(0x63, dc.read_data_part(&pidr[0]));
assert_eq!(vec![0x63], dc.read_data_part_all(&pidr[0]));
assert_eq!(1, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!(0x63, temps[0]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Backward, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::ProcId, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
let mut entry = pidr[0].to_vec();
dc.set_read_mem_cell_all(&mut entry, &[0xda45]);
assert_eq!(0x45, dc.read_mem_cell(&entry));
assert_eq!(0xd1, dc.write_mem_cell(&entry));
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 28,
cell_len_bits: 5,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 84,
max_mem_size: Some(20 * (1 << 40)),
};
let dh = vec![
0x5c0a14e3, 0x558a1, 0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x1a2b3c4d, 0xa0491b6, 0x2ab0c04, 0x5349c0d5, 0b1010011001 << 22, ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(0x558a15c0a14e3, dc.mem_address(&pidr[0]));
assert_eq!(vec![0x5c0a14e3, 0x558a1], dc.mem_address_all(&pidr[0]));
assert_eq!(2, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!([0x5c0a14e3, 0x558a1], temps[0..2]);
assert_eq!(
vec![0xabcdef11, 0x12bc3ac5, 0x0359a],
dc.temp_buffer(&pidr[0])
);
assert_eq!(3, dc.temp_buffer_slice(&pidr[0], &mut temps));
assert_eq!([0xabcdef11, 0x12bc3ac5, 0x0359a], temps[0..3]);
assert_eq!(0x4d, dc.mem_address_pos(&pidr[0]));
assert_eq!(0x2b3c, dc.temp_buffer_pos(&pidr[0]));
assert_eq!(0x1a, dc.proc_id_pos(&pidr[0]));
assert_eq!(0xa0491b6, dc.read_mem_cell(&pidr[0]));
assert_eq!(vec![0xa0491b6], dc.read_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.read_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0xa0491b6, temps[0]);
assert_eq!(0x2ab0c04, dc.write_mem_cell(&pidr[0]));
assert_eq!(vec![0x2ab0c04], dc.write_mem_cell_all(&pidr[0]));
assert_eq!(1, dc.write_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(0x2ab0c04, temps[0]);
assert_eq!(0x349c0d5, dc.read_data_part(&pidr[0]));
assert_eq!(vec![0x349c0d5], dc.read_data_part_all(&pidr[0]));
assert_eq!(1, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!(0x349c0d5, temps[0]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Forward, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::ProcId, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
let mut entry = pidr[0].to_vec();
dc.set_read_mem_cell_all(&mut entry, &[0x3725d023]);
assert_eq!(0x3725d023, dc.read_mem_cell(&entry));
assert_eq!(0x2ab0c04, dc.write_mem_cell(&entry));
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 90,
cell_len_bits: 7,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 140,
max_mem_size: Some(20 * (1 << 40)),
};
let dh = vec![
0x5c0a14e3, 0x558a1, 0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0x145cda46, 0x1a2b3c4d, 0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016, 0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301, 0x104ca040, 0xc0a94041, 0xf048401c, 0b1000001001 << 22, ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(0x558a15c0a14e3, dc.mem_address(&pidr[0]));
assert_eq!(vec![0x5c0a14e3, 0x558a1], dc.mem_address_all(&pidr[0]));
assert_eq!(2, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!([0x5c0a14e3, 0x558a1], temps[0..2]);
assert_eq!(
vec![0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0xa46],
dc.temp_buffer(&pidr[0])
);
assert_eq!(5, dc.temp_buffer_slice(&pidr[0], &mut temps));
assert_eq!(
[0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0xa46],
temps[0..5]
);
assert_eq!(0x4d, dc.mem_address_pos(&pidr[0]));
assert_eq!(0x2b3c, dc.temp_buffer_pos(&pidr[0]));
assert_eq!(0x1a, dc.proc_id_pos(&pidr[0]));
assert_eq!(0xc0a0494d1122bc0a, dc.read_mem_cell(&pidr[0]));
assert_eq!(
vec![0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016],
dc.read_mem_cell_all(&pidr[0])
);
assert_eq!(4, dc.read_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(
[0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016],
temps[0..4]
);
assert_eq!(0x596bc02b0a332114, dc.write_mem_cell(&pidr[0]));
assert_eq!(
vec![0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301],
dc.write_mem_cell_all(&pidr[0])
);
assert_eq!(4, dc.write_mem_cell_slice(&pidr[0], &mut temps));
assert_eq!(
[0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301],
temps[0..4]
);
assert_eq!(0xc0a94041104ca040, dc.read_data_part(&pidr[0]));
assert_eq!(
vec![0x104ca040, 0xc0a94041, 0x0048401c],
dc.read_data_part_all(&pidr[0])
);
assert_eq!(3, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!([0x104ca040, 0xc0a94041, 0x0048401c], temps[0..3]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Nothing, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::MemAddress, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
let mut entry = pidr[0].to_vec();
dc.set_read_mem_cell_all(&mut entry, &[0x1133aa, 0xfdca01, 0xa0131, 0x240abc]);
assert_eq!(
vec![0x1133aa, 0xfdca01, 0xa0131, 0x240abc],
dc.read_mem_cell_all(&entry)
);
assert_eq!(
vec![0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301],
dc.write_mem_cell_all(&entry)
);
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 96 - 10,
cell_len_bits: 7,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 140,
max_mem_size: Some(20 * (1 << 40)),
};
let dh = vec![
0x5c0a14e3, 0x558a1, 0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0x145cda46, 0x1a2b3c4d, 0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016, 0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301, 0x104ca040, 0xc0a94041, 0x0008401c | (0b1000001001 << 22), ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(0x558a15c0a14e3, dc.mem_address(&pidr[0]));
assert_eq!(vec![0x5c0a14e3, 0x558a1], dc.mem_address_all(&pidr[0]));
assert_eq!(2, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!([0x5c0a14e3, 0x558a1], temps[0..2]);
assert_eq!(
vec![0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0xa46],
dc.temp_buffer(&pidr[0])
);
assert_eq!(0xc0a94041104ca040, dc.read_data_part(&pidr[0]));
assert_eq!(
vec![0x104ca040, 0xc0a94041, 0x0008401c],
dc.read_data_part_all(&pidr[0])
);
assert_eq!(3, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!([0x104ca040, 0xc0a94041, 0x0008401c], temps[0..3]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Nothing, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::MemAddress, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 96 - 9,
cell_len_bits: 7,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 140,
max_mem_size: Some(20 * (1 << 40)),
};
let dh = vec![
0x5c0a14e3, 0x558a1, 0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0x145cda46, 0x1a2b3c4d, 0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016, 0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301, 0x104ca040, 0xc0a94041, 0x1da8401c, (0b1000001001 << 22), ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(0x558a15c0a14e3, dc.mem_address(&pidr[0]));
assert_eq!(vec![0x5c0a14e3, 0x558a1], dc.mem_address_all(&pidr[0]));
assert_eq!(2, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!([0x5c0a14e3, 0x558a1], temps[0..2]);
assert_eq!(
vec![0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0xa46],
dc.temp_buffer(&pidr[0])
);
assert_eq!(0xc0a94041104ca040, dc.read_data_part(&pidr[0]));
assert_eq!(
vec![0x104ca040, 0xc0a94041, 0x0028401c],
dc.read_data_part_all(&pidr[0])
);
assert_eq!(3, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!([0x104ca040, 0xc0a94041, 0x0028401c], temps[0..3]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Nothing, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::MemAddress, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
let config = InfParMachineConfig {
state_len: 40,
data_part_len: 96,
cell_len_bits: 7,
};
let env_config = InfParEnvConfig {
proc_num: 1 << 8,
flat_memory: true,
max_temp_buffer_len: 140,
max_mem_size: Some(20 * (1 << 40)),
};
let dh = vec![
0x5c0a14e3, 0x558a1, 0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0x145cda46, 0x1a2b3c4d, 0x1122bc0a, 0xc0a0494d, 0x05850aa0, 0xe0485016, 0x0a332114, 0x596bc02b, 0xb0c9a094, 0x958bb301, 0x104ca040, 0xc0a94041, 0xb568401c, (0b1000001001 << 22), ];
let pidr = ProcIntDataReader::new(config, env_config, dh);
let dc = pidr.data_config();
assert_eq!(0x558a15c0a14e3, dc.mem_address(&pidr[0]));
assert_eq!(vec![0x5c0a14e3, 0x558a1], dc.mem_address_all(&pidr[0]));
assert_eq!(2, dc.mem_address_slice(&pidr[0], &mut temps));
assert_eq!([0x5c0a14e3, 0x558a1], temps[0..2]);
assert_eq!(
vec![0xabcdef11, 0x12bc3ac5, 0xc0a0359a, 0x3a0c0da1, 0xa46],
dc.temp_buffer(&pidr[0])
);
assert_eq!(0xc0a94041104ca040, dc.read_data_part(&pidr[0]));
assert_eq!(
vec![0x104ca040, 0xc0a94041, 0xb568401c],
dc.read_data_part_all(&pidr[0])
);
assert_eq!(3, dc.read_data_part_slice(&pidr[0], &mut temps));
assert_eq!([0x104ca040, 0xc0a94041, 0xb568401c], temps[0..3]);
assert_eq!(DataAccess::ReadOnly, dc.mem_access(&pidr[0]));
assert_eq!(DataAccess::WriteOnly, dc.data_part_access(&pidr[0]));
assert_eq!(DataPartMove::Nothing, dc.data_move_dir(&pidr[0]));
assert_eq!(DataKind::MemAddress, dc.data_kind(&pidr[0]));
assert_eq!(true, dc.data_part_move_done(&pidr[0]));
assert_eq!(false, dc.stop_machine(&pidr[0]));
}
}