use crate::{
instructions::Instruction, RISCV_GENERAL_REGISTER_NUMBER, RISCV_MAX_MEMORY, RISCV_PAGES,
};
use std::alloc::{alloc_zeroed, Layout};
pub const TRACE_SIZE: usize = 8192;
pub const TRACE_ITEM_LENGTH: usize = 16;
pub const RET_DECODE_TRACE: u8 = 1;
pub const RET_ECALL: u8 = 2;
pub const RET_EBREAK: u8 = 3;
pub const RET_DYNAMIC_JUMP: u8 = 4;
pub const RET_MAX_CYCLES_EXCEEDED: u8 = 5;
pub const RET_OUT_OF_BOUND: u8 = 6;
pub const RET_INVALID_PERMISSION: u8 = 7;
#[inline(always)]
pub fn calculate_slot(addr: u64) -> usize {
(addr as usize >> 5) & (TRACE_SIZE - 1)
}
#[derive(Default)]
#[repr(C)]
pub struct Trace {
pub address: u64,
pub length: u8,
pub cycles: u64,
pub instructions: [Instruction; TRACE_ITEM_LENGTH + 1],
pub thread: [u64; TRACE_ITEM_LENGTH + 1],
}
#[repr(C)]
pub struct AsmCoreMachine {
pub registers: [u64; RISCV_GENERAL_REGISTER_NUMBER],
pub pc: u64,
pub running: u8,
pub cycles: u64,
pub max_cycles: u64,
pub flags: [u8; RISCV_PAGES],
pub memory: [u8; RISCV_MAX_MEMORY],
pub traces: [Trace; TRACE_SIZE],
}
impl Default for Box<AsmCoreMachine> {
fn default() -> Self {
AsmCoreMachine::new_with_max_cycles(u64::max_value())
}
}
impl AsmCoreMachine {
pub fn new_with_max_cycles(max_cycles: u64) -> Box<AsmCoreMachine> {
let mut machine = unsafe {
let layout = Layout::new::<AsmCoreMachine>();
#[allow(clippy::cast_ptr_alignment)]
let raw_allocation = alloc_zeroed(layout) as *mut AsmCoreMachine;
Box::from_raw(raw_allocation)
};
machine.max_cycles = max_cycles;
machine
}
}