swamp_vm_types/
opcode.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/swamp
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5
6use std::fmt::{Display, Formatter};
7
8#[repr(u8)]
9#[derive(Debug)]
10pub enum OpCode {
11    Hlt, // Return to the host
12
13    // Operators
14    // i32
15    AddI32,
16    MulI32,
17    NegI32,
18
19    // Fixed
20    AddF32,
21    MulF32,
22    NegF32,
23
24    // Comparisons
25    LtI32,
26
27    // Conditional branching
28    Bnz,
29    Bz,
30    // Unconditional branching
31    Jmp,
32
33    // Call, frame and return
34    Call, // Introduce CallLong if needed
35    Enter,
36    Ret,
37
38    // Frame copy
39    Mov,
40    MovLp,
41
42    // Load immediate into frame
43    Ld8,
44    Ld16,
45    Ld32,
46
47    LdConst, // Load from constant memory
48
49    // Indirect operations (using pointer)
50    //St32x,
51    //Stx,
52    //Ldx,
53
54    // Allocate heap
55    //Alloc,
56    //     LtU16,
57    VecFromSlice,
58    VecPush,
59    VecIterInit,
60    VecIterNext,
61    VecIterNextPair,
62    Nop,
63
64    // Intrinsic more advanced opcodes
65
66    // Collection intrinsics
67    MapNewFromPairs,
68    MapRemove,
69    MapIterInit,
70    MapIterNext,
71    MapIterNextPair,
72
73    // String
74    StringFromConstantSlice,
75    StringAppend,
76
77    // others
78    Eq8Imm,
79    Eq32,
80
81    Tst8,
82    GtI32,
83    HostCall, // calls back into host
84    StringLen,
85}
86
87impl Display for OpCode {
88    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
89        match self {
90            Self::Hlt => write!(f, "hlt"), // Halt execution
91
92            // Load
93            Self::Ld8 => write!(f, "ld8"),
94            Self::Ld16 => write!(f, "ld16"),
95            Self::Ld32 => write!(f, "ld32"),
96
97            Self::LdConst => write!(f, "ldconst"),
98
99            // Move data
100            Self::Mov => write!(f, "mov"),     // Move data
101            Self::MovLp => write!(f, "movlp"), // Move data
102
103            Self::AddI32 => write!(f, "sadd32"), // Signed Add
104            Self::MulI32 => write!(f, "smul32"), // Signed Add
105            Self::NegI32 => write!(f, "sneg32"), // Signed negate
106
107            Self::AddF32 => write!(f, "fadd"), // Signed Add
108            Self::MulF32 => write!(f, "fmul"), // Signed Add
109            Self::NegF32 => write!(f, "fneg"), // Signed negate
110
111            // Functions
112            Self::Call => write!(f, "call"),     // Call function
113            Self::Enter => write!(f, "enter"),   // Function prologue
114            Self::Ret => write!(f, "ret"),       // Return from function
115            Self::HostCall => write!(f, "host"), // Call host function
116
117            // Branches
118            Self::Jmp => write!(f, "jmp"), // Unconditional jump
119            Self::Bz => write!(f, "bz"),   // Branch if Zero (False)
120            Self::Bnz => write!(f, "bnz"), // Branch if Not Zero (True)
121
122            // Comparisons
123            Self::LtI32 => write!(f, "slt32"), // signed Less Than
124            Self::GtI32 => write!(f, "sgt32"), // Set Less Than
125            Self::Eq8Imm => write!(f, "eq8"),
126            Self::Eq32 => write!(f, "eq32"),
127            Self::Tst8 => write!(f, "tst8"),
128
129            // Vec
130            Self::VecPush => write!(f, "vec_push"),
131            Self::VecFromSlice => write!(f, "vec_from_slice"),
132            Self::VecIterInit => write!(f, "vec_iter_init"),
133            Self::VecIterNext => write!(f, "vec_iter_next"),
134            Self::VecIterNextPair => write!(f, "vec_iter_next_pair"),
135
136            // Map
137            Self::MapNewFromPairs => write!(f, "map_new_from_pairs"),
138            Self::MapRemove => write!(f, "map_remove"),
139            Self::MapIterInit => write!(f, "map_iter_init"),
140            Self::MapIterNext => write!(f, "map_iter_next"),
141            Self::MapIterNextPair => write!(f, "map_iter_next_pair"),
142
143            // Map
144            Self::StringFromConstantSlice => write!(f, "str_from_const"),
145            Self::StringAppend => write!(f, "str_append"),
146            Self::StringLen => write!(f, "str_len"),
147
148            Self::Nop => write!(f, "nop"),
149        }
150    }
151}
152
153// Add this to your OpCode implementation
154impl From<u8> for OpCode {
155    fn from(value: u8) -> Self {
156        // Safety: This assumes the u8 value corresponds to a valid OpCode variant
157        // For production code, consider using TryFrom instead to validate the value
158        unsafe { std::mem::transmute(value) }
159    }
160}