synth_core/wasm_op.rs
1//! WebAssembly operation patterns — universal input IR for all backends
2//!
3//! Every backend (ARM, aWsm, wasker, w2c2) consumes `WasmOp` sequences.
4//! This enum lives in synth-core so backends can depend on it without
5//! pulling in ARM-specific synthesis types.
6
7use serde::{Deserialize, Serialize};
8
9/// WebAssembly operation patterns
10/// Note: Cannot derive Eq because f32/f64 don't implement Eq (NaN != NaN)
11#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
12pub enum WasmOp {
13 // Arithmetic
14 I32Add,
15 I32Sub,
16 I32Mul,
17 I32DivS,
18 I32DivU,
19 I32RemS,
20 I32RemU,
21
22 // Bitwise
23 I32And,
24 I32Or,
25 I32Xor,
26 I32Shl,
27 I32ShrS,
28 I32ShrU,
29 I32Rotl, // Rotate left
30 I32Rotr, // Rotate right
31 I32Clz, // Count leading zeros
32 I32Ctz, // Count trailing zeros
33 I32Popcnt, // Population count (count 1 bits)
34
35 // Sign extension
36 I32Extend8S, // Sign-extend low 8 bits to 32 bits
37 I32Extend16S, // Sign-extend low 16 bits to 32 bits
38
39 // Comparison
40 I32Eqz, // Equal to zero (unary)
41 I32Eq,
42 I32Ne,
43 I32LtS,
44 I32LtU,
45 I32LeS,
46 I32LeU,
47 I32GtS,
48 I32GtU,
49 I32GeS,
50 I32GeU,
51
52 // Constants
53 I32Const(i32),
54
55 // Memory
56 I32Load { offset: u32, align: u32 },
57 I32Store { offset: u32, align: u32 },
58
59 // Sub-word loads (i32)
60 I32Load8S { offset: u32, align: u32 }, // byte load, sign-extend to i32
61 I32Load8U { offset: u32, align: u32 }, // byte load, zero-extend to i32
62 I32Load16S { offset: u32, align: u32 }, // halfword load, sign-extend to i32
63 I32Load16U { offset: u32, align: u32 }, // halfword load, zero-extend to i32
64
65 // Sub-word stores (i32)
66 I32Store8 { offset: u32, align: u32 }, // store low byte
67 I32Store16 { offset: u32, align: u32 }, // store low halfword
68
69 // Control flow
70 Block,
71 Loop,
72 Br(u32), // Branch to label
73 BrIf(u32), // Conditional branch
74 BrTable { targets: Vec<u32>, default: u32 },
75 Return,
76 Call(u32),
77 CallIndirect { type_index: u32, table_index: u32 },
78 LocalGet(u32),
79 LocalSet(u32),
80 LocalTee(u32),
81 GlobalGet(u32),
82 GlobalSet(u32),
83
84 // Memory management
85 MemorySize(u32), // returns current memory size in pages (memory index)
86 MemoryGrow(u32), // grow memory by N pages, returns previous size or -1 (memory index)
87
88 // More ops
89 Drop,
90 Select,
91 If,
92 Else,
93 End,
94 Unreachable,
95 Nop,
96
97 // ========================================================================
98 // i64 Operations
99 // ========================================================================
100
101 // i64 Arithmetic
102 I64Add,
103 I64Sub,
104 I64Mul,
105 I64DivS,
106 I64DivU,
107 I64RemS,
108 I64RemU,
109
110 // i64 Bitwise
111 I64And,
112 I64Or,
113 I64Xor,
114 I64Shl,
115 I64ShrS,
116 I64ShrU,
117 I64Rotl,
118 I64Rotr,
119 I64Clz,
120 I64Ctz,
121 I64Popcnt,
122
123 // i64 Comparison
124 I64Eqz,
125 I64Eq,
126 I64Ne,
127 I64LtS,
128 I64LtU,
129 I64LeS,
130 I64LeU,
131 I64GtS,
132 I64GtU,
133 I64GeS,
134 I64GeU,
135
136 // i64 Constants and Memory
137 I64Const(i64),
138 I64Load { offset: u32, align: u32 },
139 I64Store { offset: u32, align: u32 },
140
141 // Sub-word loads (i64) — load sub-word, extend to i64
142 I64Load8S { offset: u32, align: u32 },
143 I64Load8U { offset: u32, align: u32 },
144 I64Load16S { offset: u32, align: u32 },
145 I64Load16U { offset: u32, align: u32 },
146 I64Load32S { offset: u32, align: u32 },
147 I64Load32U { offset: u32, align: u32 },
148
149 // Sub-word stores (i64) — store low N bits
150 I64Store8 { offset: u32, align: u32 },
151 I64Store16 { offset: u32, align: u32 },
152 I64Store32 { offset: u32, align: u32 },
153
154 // Conversion operations
155 I64ExtendI32S, // Sign-extend i32 to i64
156 I64ExtendI32U, // Zero-extend i32 to i64
157 I32WrapI64, // Wrap i64 to i32 (truncate)
158
159 // i64 In-place sign extension
160 I64Extend8S, // Sign-extend low 8 bits to 64 bits
161 I64Extend16S, // Sign-extend low 16 bits to 64 bits
162 I64Extend32S, // Sign-extend low 32 bits to 64 bits
163
164 // ========================================================================
165 // f32 Operations
166 // ========================================================================
167
168 // f32 Arithmetic
169 F32Add,
170 F32Sub,
171 F32Mul,
172 F32Div,
173
174 // f32 Comparisons
175 F32Eq,
176 F32Ne,
177 F32Lt,
178 F32Le,
179 F32Gt,
180 F32Ge,
181
182 // f32 Math Functions
183 F32Abs,
184 F32Neg,
185 F32Ceil,
186 F32Floor,
187 F32Trunc,
188 F32Nearest,
189 F32Sqrt,
190 F32Min,
191 F32Max,
192 F32Copysign,
193
194 // f32 Constants and Memory
195 F32Const(f32),
196 F32Load { offset: u32, align: u32 },
197 F32Store { offset: u32, align: u32 },
198
199 // f32 Conversions
200 F32ConvertI32S, // Convert signed i32 to f32
201 F32ConvertI32U, // Convert unsigned i32 to f32
202 F32ConvertI64S, // Convert signed i64 to f32
203 F32ConvertI64U, // Convert unsigned i64 to f32
204 F32DemoteF64, // Convert f64 to f32
205 F32ReinterpretI32, // Reinterpret i32 bits as f32
206 I32ReinterpretF32, // Reinterpret f32 bits as i32
207 I32TruncF32S, // Truncate f32 to signed i32
208 I32TruncF32U, // Truncate f32 to unsigned i32
209
210 // ========================================================================
211 // f64 Operations
212 // ========================================================================
213
214 // f64 Arithmetic
215 F64Add,
216 F64Sub,
217 F64Mul,
218 F64Div,
219
220 // f64 Comparisons
221 F64Eq,
222 F64Ne,
223 F64Lt,
224 F64Le,
225 F64Gt,
226 F64Ge,
227
228 // f64 Math Functions
229 F64Abs,
230 F64Neg,
231 F64Ceil,
232 F64Floor,
233 F64Trunc,
234 F64Nearest,
235 F64Sqrt,
236 F64Min,
237 F64Max,
238 F64Copysign,
239
240 // f64 Constants and Memory
241 F64Const(f64),
242 F64Load { offset: u32, align: u32 },
243 F64Store { offset: u32, align: u32 },
244
245 // f64 Conversions
246 F64ConvertI32S, // Convert signed i32 to f64
247 F64ConvertI32U, // Convert unsigned i32 to f64
248 F64ConvertI64S, // Convert signed i64 to f64
249 F64ConvertI64U, // Convert unsigned i64 to f64
250 F64PromoteF32, // Convert f32 to f64
251 F64ReinterpretI64, // Reinterpret i64 bits as f64
252 I64ReinterpretF64, // Reinterpret f64 bits as i64
253 I64TruncF64S, // Truncate f64 to signed i64
254 I64TruncF64U, // Truncate f64 to unsigned i64
255 I32TruncF64S, // Truncate f64 to signed i32
256 I32TruncF64U, // Truncate f64 to unsigned i32
257
258 // ========================================================================
259 // v128 SIMD Operations (WASM SIMD proposal)
260 // ========================================================================
261 // Targets ARM Cortex-M55 Helium MVE (M-Profile Vector Extension)
262
263 // v128 Constants and Memory
264 V128Const([u8; 16]), // 128-bit constant
265 V128Load { offset: u32, align: u32 }, // v128.load
266 V128Store { offset: u32, align: u32 }, // v128.store
267
268 // v128 Bitwise operations
269 V128And, // v128.and
270 V128Or, // v128.or
271 V128Xor, // v128.xor
272 V128Not, // v128.not
273 V128AndNot, // v128.andnot
274
275 // i8x16 integer SIMD
276 I8x16Add, // i8x16.add
277 I8x16Sub, // i8x16.sub
278 I8x16Neg, // i8x16.neg
279 I8x16Eq, // i8x16.eq
280 I8x16Ne, // i8x16.ne
281 I8x16LtS, // i8x16.lt_s
282 I8x16LtU, // i8x16.lt_u
283 I8x16GtS, // i8x16.gt_s
284 I8x16GtU, // i8x16.gt_u
285 I8x16LeS, // i8x16.le_s
286 I8x16LeU, // i8x16.le_u
287 I8x16GeS, // i8x16.ge_s
288 I8x16GeU, // i8x16.ge_u
289 I8x16Splat, // i8x16.splat
290 I8x16ExtractLaneS(u8), // i8x16.extract_lane_s
291 I8x16ExtractLaneU(u8), // i8x16.extract_lane_u
292 I8x16ReplaceLane(u8), // i8x16.replace_lane
293 I8x16Shuffle([u8; 16]), // i8x16.shuffle
294 I8x16Swizzle, // i8x16.swizzle
295
296 // i16x8 integer SIMD
297 I16x8Add, // i16x8.add
298 I16x8Sub, // i16x8.sub
299 I16x8Mul, // i16x8.mul
300 I16x8Neg, // i16x8.neg
301 I16x8Eq, // i16x8.eq
302 I16x8Ne, // i16x8.ne
303 I16x8LtS, // i16x8.lt_s
304 I16x8LtU, // i16x8.lt_u
305 I16x8GtS, // i16x8.gt_s
306 I16x8GtU, // i16x8.gt_u
307 I16x8LeS, // i16x8.le_s
308 I16x8LeU, // i16x8.le_u
309 I16x8GeS, // i16x8.ge_s
310 I16x8GeU, // i16x8.ge_u
311 I16x8Splat, // i16x8.splat
312 I16x8ExtractLaneS(u8), // i16x8.extract_lane_s
313 I16x8ExtractLaneU(u8), // i16x8.extract_lane_u
314 I16x8ReplaceLane(u8), // i16x8.replace_lane
315
316 // i32x4 integer SIMD
317 I32x4Add, // i32x4.add
318 I32x4Sub, // i32x4.sub
319 I32x4Mul, // i32x4.mul
320 I32x4Neg, // i32x4.neg
321 I32x4Eq, // i32x4.eq
322 I32x4Ne, // i32x4.ne
323 I32x4LtS, // i32x4.lt_s
324 I32x4LtU, // i32x4.lt_u
325 I32x4GtS, // i32x4.gt_s
326 I32x4GtU, // i32x4.gt_u
327 I32x4LeS, // i32x4.le_s
328 I32x4LeU, // i32x4.le_u
329 I32x4GeS, // i32x4.ge_s
330 I32x4GeU, // i32x4.ge_u
331 I32x4Splat, // i32x4.splat
332 I32x4ExtractLane(u8), // i32x4.extract_lane
333 I32x4ReplaceLane(u8), // i32x4.replace_lane
334
335 // i64x2 integer SIMD
336 I64x2Add, // i64x2.add
337 I64x2Sub, // i64x2.sub
338 I64x2Mul, // i64x2.mul
339 I64x2Neg, // i64x2.neg
340 I64x2Eq, // i64x2.eq
341 I64x2Ne, // i64x2.ne
342 I64x2LtS, // i64x2.lt_s
343 I64x2GtS, // i64x2.gt_s
344 I64x2LeS, // i64x2.le_s
345 I64x2GeS, // i64x2.ge_s
346 I64x2Splat, // i64x2.splat
347 I64x2ExtractLane(u8), // i64x2.extract_lane
348 I64x2ReplaceLane(u8), // i64x2.replace_lane
349
350 // f32x4 floating-point SIMD
351 F32x4Add, // f32x4.add
352 F32x4Sub, // f32x4.sub
353 F32x4Mul, // f32x4.mul
354 F32x4Div, // f32x4.div
355 F32x4Abs, // f32x4.abs
356 F32x4Neg, // f32x4.neg
357 F32x4Sqrt, // f32x4.sqrt
358 F32x4Eq, // f32x4.eq
359 F32x4Ne, // f32x4.ne
360 F32x4Lt, // f32x4.lt
361 F32x4Le, // f32x4.le
362 F32x4Gt, // f32x4.gt
363 F32x4Ge, // f32x4.ge
364 F32x4Splat, // f32x4.splat
365 F32x4ExtractLane(u8), // f32x4.extract_lane
366 F32x4ReplaceLane(u8), // f32x4.replace_lane
367}