// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: MIT

// Every architecture MUST implement this as part of the ABI.
// Additional registers can be implemented with architecture-specific traits.

pub trait RegStoreLoad
where
    Self: Sized,
    Self: Default,
{
    // Create an instance of Registers by loading values from the CPU.
    // This MUST NOT modify any CPU registers, and can only read them.
    fn load_all() -> Self;
    // Create a new instance to write to before we commit to the CPU.
    // This MUST instantiate a zeroed set of registers.
    // Do not represent unmodified registers as None variants of an Option.
    fn new_zeroed() -> Self {
        Self::default()
    }
    // Store the instance to the CPU and consume self.
    // This MUST write ALL register values to the CPU, including zero values.
    fn store_all(self);

    // All of these functions below MUST NOT write directly to the CPU.
    // The registers will be written when store_all() is called.

    // Get the six argument or return register values.
    // This MUST read registers in the same order as set_syscall_args sets them.
    fn read_syscall_args(&self) -> [u64; 6];
    // Get the syscall number or error number.
    // This MUST NOT zero or otherwise overwrite the register.
    fn read_syscall_num(&self) -> u64;
    // Set the six argument or return register values.
    // This MUST write registers in the same order as read_syscall_args reads them.
    fn set_syscall_args(&mut self, new_values: [u64; 6]);
    // Set the syscall number or error number.
    // This MUST NOT change any other registers.
    fn set_syscall_num(&mut self, new_value: u64);
}
