use std::borrow::Cow;
use std::fmt::Debug;
use zisk_common::EmuTrace;
use zisk_common::EmuTraceStart;
use zisk_core::{REGS_IN_MAIN_FROM, REGS_IN_MAIN_TO, REGS_IN_MAIN_TOTAL_NUMBER};
use crate::AsmShmemHeader;
#[repr(C)]
#[derive(Debug)]
pub(crate) struct AsmMTHeader {
pub version: u64,
pub exit_code: u64,
pub shmem_allocated_size: u64,
pub shmem_used_size: u64,
pub num_chunks: u64,
}
impl AsmShmemHeader for AsmMTHeader {
fn allocated_size(&self) -> u64 {
self.shmem_allocated_size
}
}
#[repr(C)]
#[derive(Debug)]
pub(crate) struct AsmMTChunk {
pub pc: u64,
pub sp: u64,
pub c: u64,
pub step: u64,
pub registers: [u64; 33],
pub last_c: u64,
pub end: u64,
pub steps: u64,
pub mem_reads_size: u64,
}
impl AsmMTChunk {
pub fn to_emu_trace(mapped_ptr: &mut *const AsmMTChunk) -> EmuTrace {
let chunk = unsafe { std::ptr::read(*mapped_ptr) };
*mapped_ptr = unsafe { mapped_ptr.add(1) };
let mem_reads_ptr = *mapped_ptr as *const u64;
let mem_reads_len = chunk.mem_reads_size as usize;
let mem_reads: Cow<'static, [u64]> = unsafe {
Cow::Borrowed(&*std::ptr::slice_from_raw_parts(mem_reads_ptr, mem_reads_len))
};
*mapped_ptr = unsafe { (*mapped_ptr as *mut u64).add(mem_reads_len) as *const AsmMTChunk };
let mut registers = [0u64; REGS_IN_MAIN_TOTAL_NUMBER];
registers[REGS_IN_MAIN_FROM..].copy_from_slice(&chunk.registers[..REGS_IN_MAIN_TO]);
EmuTrace {
start_state: EmuTraceStart {
pc: chunk.pc,
sp: chunk.sp,
c: chunk.c,
step: chunk.step,
regs: registers,
},
last_c: chunk.last_c,
end: chunk.end == 1,
steps: chunk.steps,
mem_reads,
}
}
}