Skip to main content

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}