use vyre_foundation::ir::{Expr, Node};
use crate::megakernel::io::{
IO_DESTINATION_CAPABILITY_TABLE, IO_QUEUE_DMA_TAG, IO_SOURCE_CAPABILITY_TABLE,
};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DirectIoBindings {
pub source: &'static str,
pub destination: &'static str,
pub file_start: &'static str,
pub file_end: &'static str,
pub tag: &'static str,
}
impl Default for DirectIoBindings {
fn default() -> Self {
Self {
source: IO_SOURCE_CAPABILITY_TABLE,
destination: IO_DESTINATION_CAPABILITY_TABLE,
file_start: "file_start",
file_end: "file_end",
tag: IO_QUEUE_DMA_TAG,
}
}
}
#[must_use]
pub fn pull_file_async_direct() -> Node {
pull_file_async_direct_with(&DirectIoBindings::default())
}
#[must_use]
pub fn pull_file_async_direct_with(bindings: &DirectIoBindings) -> Node {
Node::async_load_ext(
bindings.source,
bindings.destination,
Expr::var(bindings.file_start),
Expr::sub(Expr::var(bindings.file_end), Expr::var(bindings.file_start)),
bindings.tag,
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn direct_io_uses_extended_async_load_fields() {
let node = pull_file_async_direct();
let Node::AsyncLoad {
source,
destination,
offset,
size,
tag,
} = node
else {
panic!("direct IO must emit AsyncLoad");
};
assert_eq!(source.as_str(), IO_SOURCE_CAPABILITY_TABLE);
assert_eq!(destination.as_str(), IO_DESTINATION_CAPABILITY_TABLE);
assert_eq!(tag.as_str(), IO_QUEUE_DMA_TAG);
assert!(matches!(*offset, Expr::Var(_)));
assert!(matches!(*size, Expr::BinOp { .. }));
}
}