1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
2#[repr(u8)]
3pub enum Opcode {
4 Trap = 0,
5 Fallthrough = 1,
6 Ecalli = 10,
7 LoadImm64 = 20,
8 StoreImmU8 = 30,
10 StoreImmU16 = 31,
11 StoreImmU32 = 32,
12 StoreImmU64 = 33,
13 Jump = 40,
14 JumpInd = 50,
15 LoadImm = 51,
16 LoadU8 = 52,
18 LoadI8 = 53,
19 LoadU16 = 54,
20 LoadI16 = 55,
21 LoadU32 = 56,
22 LoadI32 = 57,
23 LoadU64 = 58,
24 StoreU8 = 59,
25 StoreU16 = 60,
26 StoreU32 = 61,
27 StoreU64 = 62,
28 StoreImmIndU8 = 70,
30 StoreImmIndU16 = 71,
31 StoreImmIndU32 = 72,
32 StoreImmIndU64 = 73,
33 LoadImmJump = 80,
35 BranchEqImm = 81,
37 BranchNeImm = 82,
38 BranchLtUImm = 83,
39 BranchLeUImm = 84,
40 BranchGeUImm = 85,
41 BranchGtUImm = 86,
42 BranchLtSImm = 87,
43 BranchLeSImm = 88,
44 BranchGeSImm = 89,
45 BranchGtSImm = 90,
46 MoveReg = 100,
47 Sbrk = 101,
48 CountSetBits64 = 102,
49 CountSetBits32 = 103,
50 LeadingZeroBits64 = 104,
51 LeadingZeroBits32 = 105,
52 TrailingZeroBits64 = 106,
53 TrailingZeroBits32 = 107,
54 SignExtend8 = 108,
55 SignExtend16 = 109,
56 ZeroExtend16 = 110,
57 ReverseBytes = 111,
58 StoreIndU8 = 120,
59 StoreIndU16 = 121,
60 StoreIndU32 = 122,
61 StoreIndU64 = 123,
62 LoadIndU8 = 124,
63 LoadIndI8 = 125,
64 LoadIndU16 = 126,
65 LoadIndI16 = 127,
66 LoadIndU32 = 128,
67 LoadIndI32 = 129,
68 LoadIndU64 = 130,
69 AddImm32 = 131,
70 AndImm = 132,
71 XorImm = 133,
72 OrImm = 134,
73 MulImm32 = 135,
74 SetLtUImm = 136,
76 SetLtSImm = 137,
77 ShloLImm32 = 138,
79 ShloRImm32 = 139,
80 SharRImm32 = 140,
81 NegAddImm32 = 141,
82 SetGtUImm = 142,
83 SetGtSImm = 143,
84 ShloLImmAlt32 = 144,
86 ShloRImmAlt32 = 145,
87 SharRImmAlt32 = 146,
88 CmovIzImm = 147,
90 CmovNzImm = 148,
91 AddImm64 = 149,
92 MulImm64 = 150,
93 ShloLImm64 = 151,
94 ShloRImm64 = 152,
95 SharRImm64 = 153,
96 NegAddImm64 = 154,
97 ShloLImmAlt64 = 155,
99 ShloRImmAlt64 = 156,
100 SharRImmAlt64 = 157,
101 RotRImm64 = 158,
103 RotRImmAlt64 = 159,
104 RotRImm32 = 160,
105 RotRImmAlt32 = 161,
106 BranchEq = 170,
108 BranchNe = 171,
109 BranchLtU = 172,
110 BranchLtS = 173,
111 BranchGeU = 174,
112 BranchGeS = 175,
113 LoadImmJumpInd = 180,
115 Add32 = 190,
117 Sub32 = 191,
118 Mul32 = 192,
119 DivU32 = 193,
120 DivS32 = 194,
121 RemU32 = 195,
122 RemS32 = 196,
123 ShloL32 = 197,
125 ShloR32 = 198,
126 SharR32 = 199,
127 Add64 = 200,
129 Sub64 = 201,
130 Mul64 = 202,
131 DivU64 = 203,
132 DivS64 = 204,
133 RemU64 = 205,
134 RemS64 = 206,
135 ShloL64 = 207,
136 ShloR64 = 208,
137 SharR64 = 209,
138 And = 210,
140 Xor = 211,
141 Or = 212,
142 MulUpperSS = 213,
144 MulUpperUU = 214,
145 MulUpperSU = 215,
146 SetLtU = 216,
148 SetLtS = 217,
149 CmovIz = 218,
151 CmovNz = 219,
152 RotL64 = 220,
154 RotL32 = 221,
155 RotR64 = 222,
156 RotR32 = 223,
157 AndInv = 224,
159 OrInv = 225,
160 Xnor = 226,
161 Max = 227,
163 MaxU = 228,
164 Min = 229,
165 MinU = 230,
166}
167
168impl Opcode {
169 #[must_use]
170 pub const fn from_u8(opcode: u8) -> Option<Self> {
171 match opcode {
172 0 => Some(Self::Trap),
173 1 => Some(Self::Fallthrough),
174 10 => Some(Self::Ecalli),
175 20 => Some(Self::LoadImm64),
176 30 => Some(Self::StoreImmU8),
177 31 => Some(Self::StoreImmU16),
178 32 => Some(Self::StoreImmU32),
179 33 => Some(Self::StoreImmU64),
180 40 => Some(Self::Jump),
181 50 => Some(Self::JumpInd),
182 51 => Some(Self::LoadImm),
183 52 => Some(Self::LoadU8),
184 53 => Some(Self::LoadI8),
185 54 => Some(Self::LoadU16),
186 55 => Some(Self::LoadI16),
187 56 => Some(Self::LoadU32),
188 57 => Some(Self::LoadI32),
189 58 => Some(Self::LoadU64),
190 59 => Some(Self::StoreU8),
191 60 => Some(Self::StoreU16),
192 61 => Some(Self::StoreU32),
193 62 => Some(Self::StoreU64),
194 70 => Some(Self::StoreImmIndU8),
195 71 => Some(Self::StoreImmIndU16),
196 72 => Some(Self::StoreImmIndU32),
197 73 => Some(Self::StoreImmIndU64),
198 80 => Some(Self::LoadImmJump),
199 81 => Some(Self::BranchEqImm),
200 82 => Some(Self::BranchNeImm),
201 83 => Some(Self::BranchLtUImm),
202 84 => Some(Self::BranchLeUImm),
203 85 => Some(Self::BranchGeUImm),
204 86 => Some(Self::BranchGtUImm),
205 87 => Some(Self::BranchLtSImm),
206 88 => Some(Self::BranchLeSImm),
207 89 => Some(Self::BranchGeSImm),
208 90 => Some(Self::BranchGtSImm),
209 100 => Some(Self::MoveReg),
210 101 => Some(Self::Sbrk),
211 102 => Some(Self::CountSetBits64),
212 103 => Some(Self::CountSetBits32),
213 104 => Some(Self::LeadingZeroBits64),
214 105 => Some(Self::LeadingZeroBits32),
215 106 => Some(Self::TrailingZeroBits64),
216 107 => Some(Self::TrailingZeroBits32),
217 108 => Some(Self::SignExtend8),
218 109 => Some(Self::SignExtend16),
219 110 => Some(Self::ZeroExtend16),
220 111 => Some(Self::ReverseBytes),
221 120 => Some(Self::StoreIndU8),
222 121 => Some(Self::StoreIndU16),
223 122 => Some(Self::StoreIndU32),
224 123 => Some(Self::StoreIndU64),
225 124 => Some(Self::LoadIndU8),
226 125 => Some(Self::LoadIndI8),
227 126 => Some(Self::LoadIndU16),
228 127 => Some(Self::LoadIndI16),
229 128 => Some(Self::LoadIndU32),
230 129 => Some(Self::LoadIndI32),
231 130 => Some(Self::LoadIndU64),
232 131 => Some(Self::AddImm32),
233 132 => Some(Self::AndImm),
234 133 => Some(Self::XorImm),
235 134 => Some(Self::OrImm),
236 135 => Some(Self::MulImm32),
237 136 => Some(Self::SetLtUImm),
238 137 => Some(Self::SetLtSImm),
239 138 => Some(Self::ShloLImm32),
240 139 => Some(Self::ShloRImm32),
241 140 => Some(Self::SharRImm32),
242 141 => Some(Self::NegAddImm32),
243 142 => Some(Self::SetGtUImm),
244 143 => Some(Self::SetGtSImm),
245 144 => Some(Self::ShloLImmAlt32),
246 145 => Some(Self::ShloRImmAlt32),
247 146 => Some(Self::SharRImmAlt32),
248 147 => Some(Self::CmovIzImm),
249 148 => Some(Self::CmovNzImm),
250 149 => Some(Self::AddImm64),
251 150 => Some(Self::MulImm64),
252 151 => Some(Self::ShloLImm64),
253 152 => Some(Self::ShloRImm64),
254 153 => Some(Self::SharRImm64),
255 154 => Some(Self::NegAddImm64),
256 155 => Some(Self::ShloLImmAlt64),
257 156 => Some(Self::ShloRImmAlt64),
258 157 => Some(Self::SharRImmAlt64),
259 158 => Some(Self::RotRImm64),
260 159 => Some(Self::RotRImmAlt64),
261 160 => Some(Self::RotRImm32),
262 161 => Some(Self::RotRImmAlt32),
263 170 => Some(Self::BranchEq),
264 171 => Some(Self::BranchNe),
265 172 => Some(Self::BranchLtU),
266 173 => Some(Self::BranchLtS),
267 174 => Some(Self::BranchGeU),
268 175 => Some(Self::BranchGeS),
269 180 => Some(Self::LoadImmJumpInd),
270 190 => Some(Self::Add32),
271 191 => Some(Self::Sub32),
272 192 => Some(Self::Mul32),
273 193 => Some(Self::DivU32),
274 194 => Some(Self::DivS32),
275 195 => Some(Self::RemU32),
276 196 => Some(Self::RemS32),
277 197 => Some(Self::ShloL32),
278 198 => Some(Self::ShloR32),
279 199 => Some(Self::SharR32),
280 200 => Some(Self::Add64),
281 201 => Some(Self::Sub64),
282 202 => Some(Self::Mul64),
283 203 => Some(Self::DivU64),
284 204 => Some(Self::DivS64),
285 205 => Some(Self::RemU64),
286 206 => Some(Self::RemS64),
287 207 => Some(Self::ShloL64),
288 208 => Some(Self::ShloR64),
289 209 => Some(Self::SharR64),
290 210 => Some(Self::And),
291 211 => Some(Self::Xor),
292 212 => Some(Self::Or),
293 213 => Some(Self::MulUpperSS),
294 214 => Some(Self::MulUpperUU),
295 215 => Some(Self::MulUpperSU),
296 216 => Some(Self::SetLtU),
297 217 => Some(Self::SetLtS),
298 218 => Some(Self::CmovIz),
299 219 => Some(Self::CmovNz),
300 220 => Some(Self::RotL64),
301 221 => Some(Self::RotL32),
302 222 => Some(Self::RotR64),
303 223 => Some(Self::RotR32),
304 224 => Some(Self::AndInv),
305 225 => Some(Self::OrInv),
306 226 => Some(Self::Xnor),
307 227 => Some(Self::Max),
308 228 => Some(Self::MaxU),
309 229 => Some(Self::Min),
310 230 => Some(Self::MinU),
311 _ => None,
312 }
313 }
314
315 #[must_use]
316 pub const fn is_terminating(self) -> bool {
317 matches!(
318 self,
319 Self::Trap
320 | Self::Fallthrough
321 | Self::Jump
322 | Self::LoadImmJump
323 | Self::JumpInd
324 | Self::BranchEqImm
325 | Self::BranchNeImm
326 | Self::BranchLtUImm
327 | Self::BranchLeUImm
328 | Self::BranchGeUImm
329 | Self::BranchGtUImm
330 | Self::BranchLtSImm
331 | Self::BranchLeSImm
332 | Self::BranchGeSImm
333 | Self::BranchGtSImm
334 | Self::BranchEq
335 | Self::BranchNe
336 | Self::BranchLtU
337 | Self::BranchLtS
338 | Self::BranchGeU
339 | Self::BranchGeS
340 | Self::LoadImmJumpInd
341 )
342 }
343}
344
345impl TryFrom<u8> for Opcode {
346 type Error = ();
347
348 fn try_from(value: u8) -> std::result::Result<Self, Self::Error> {
349 Self::from_u8(value).ok_or(())
350 }
351}