Skip to main content

vyre_runtime/megakernel/protocol/
opcode.rs

1/// Do nothing. Useful for heartbeat probes.
2pub const NOP: u32 = 0;
3/// `control[args[1]] = args[0]`.
4pub const STORE_U32: u32 = 1;
5/// `atomic_add(control[args[1]], args[0])`.
6pub const ATOMIC_ADD: u32 = 2;
7/// Read `control[args[0]]` into `control[OBSERVABLE_BASE + args[1]]`.
8pub const LOAD_U32: u32 = 3;
9/// `CAS(control[args[0]], expected=args[1], desired=args[2])`.
10pub const COMPARE_SWAP: u32 = 4;
11/// Bulk GPU-to-GPU copy within the control buffer.
12pub const MEMCPY: u32 = 5;
13/// DFA single-step: `next_state = dfa_table[args[0] * 256 + args[1]]`.
14pub const DFA_STEP: u32 = 6;
15/// Batch fence signaling that the published batch is complete.
16pub const BATCH_FENCE: u32 = 7;
17/// GPU-initiated load miss: the megakernel writes a DMA request to the IO
18/// queue and polls for completion. The argument is the consumer's
19/// resource identifier (32-bit, opaque to vyre). vyre is a generic GPU
20/// substrate; it does not know what "the resource" is  -  that is the
21/// consumer's domain. See the boundary rule in AGENTS.md.
22pub const LOAD_MISS: u32 = 0x0000_FFFD;
23/// Packed slot: one outer ring slot carries several inner ops.
24pub const PACKED_SLOT: u32 = 0x8000_0001;
25/// Write one PRINTF event to the debug log.
26pub const PRINTF: u32 = 0x0000_FFFE;
27/// Set `control[SHUTDOWN] = 1`.
28pub const SHUTDOWN: u32 = u32::MAX;
29/// High bit is reserved for system opcodes.
30pub const SYSTEM_MASK: u32 = 0x8000_0000;
31/// Lower bound for the high reserved range.
32pub const RESERVED_MAX_RANGE_MIN: u32 = 0x0000_FFF0;
33
34/// Return true if the opcode is reserved by the megakernel.
35#[must_use]
36pub const fn is_system(op: u32) -> bool {
37    (op & SYSTEM_MASK) != 0
38        || (op >= RESERVED_MAX_RANGE_MIN && op <= 0x0000_FFFF)
39        || op <= BATCH_FENCE
40}
41
42/// Return true if the opcode is one of the frozen built-in opcodes.
43#[must_use]
44pub const fn is_builtin(op: u32) -> bool {
45    op <= BATCH_FENCE || op == PACKED_SLOT || op == PRINTF || op == SHUTDOWN
46}
47
48/// Validate a user-defined opcode.
49///
50/// # Errors
51///
52/// Returns a static string when `op` overlaps a reserved system range.
53pub const fn validate_user_opcode(op: u32) -> Result<(), &'static str> {
54    if is_system(op) {
55        Err("User opcode overlaps with reserved system range or uses the high bit.")
56    } else {
57        Ok(())
58    }
59}
60
61/// Validate an opcode that is about to be written to the ring.
62pub const fn validate_publish_opcode(op: u32) -> Result<(), &'static str> {
63    if is_builtin(op) {
64        Ok(())
65    } else {
66        validate_user_opcode(op)
67    }
68}
69
70const _: () = {
71    let opcodes = [
72        NOP,
73        STORE_U32,
74        ATOMIC_ADD,
75        LOAD_U32,
76        COMPARE_SWAP,
77        MEMCPY,
78        DFA_STEP,
79        BATCH_FENCE,
80        LOAD_MISS,
81        PACKED_SLOT,
82        PRINTF,
83        SHUTDOWN,
84    ];
85    let mut i = 0;
86    while i < opcodes.len() {
87        let mut j = i + 1;
88        while j < opcodes.len() {
89            assert!(opcodes[i] != opcodes[j], "Duplicate opcode");
90            j += 1;
91        }
92        assert!(is_system(opcodes[i]), "Opcode is not system");
93        i += 1;
94    }
95};