1use core::fmt::Display;
7
8use crate::error::AssemblerError;
9use crate::instr_def::Instr;
10use crate::operands::RawOperand;
11use crate::resolver::Resolver;
12use arrayvec::ArrayVec;
13use bytes::BufMut;
14
15pub(crate) const MAX_OPERANDS: usize = 8;
19
20#[derive(Debug, Clone, PartialEq, Eq, Hash)]
22pub(crate) struct RawInstr {
23 pub opcode: u32,
25 pub operands: ArrayVec<RawOperand, MAX_OPERANDS>,
27}
28
29macro_rules! count {
31 ($(,)*) => (0u32);
32 ($current:expr $(,)*) => (1u32);
33 ( $current:expr, $($rest:expr),* $(,)*) => (const { 1 + count!($($rest),*) });
34}
35
36macro_rules! resolve {
40 ($position:expr, $resolver:expr, $($x:expr),* $(,)*) => {
41 {
42 #[allow(unused_mut)]
43 let mut v = ArrayVec::<RawOperand, MAX_OPERANDS>::new();
44 let n_args = count!($($x),*);
45
46 let mut _position = $position.checked_add(n_args.div_ceil(2))
47 .ok_or(AssemblerError::Overflow)?;
48
49 $(
50 let operand = $x.resolve(_position, $resolver)?;
51 _position = _position.checked_add(u32::try_from(operand.len())
52 .or(Err(AssemblerError::Overflow))?)
53 .ok_or(AssemblerError::Overflow)?;
54 v.push(operand);
55 )*
56
57 v
58 }
59 };
60}
61
62macro_rules! worst_len {
65 ($($x:expr),* $(,)*) => {
66 {
67 let oplens = [$($x.worst_len()),*];
68 let oplens_slice = oplens.as_slice();
69 let modelen = oplens_slice.len().div_ceil(2);
70 let oplen_sum = oplens_slice.iter().copied().sum::<usize>();
71 modelen + oplen_sum
72 }
73 };
74}
75
76impl<L> Instr<L> {
77 pub fn map<F, M>(self, mut f: F) -> Instr<M>
79 where
80 F: FnMut(L) -> M,
81 {
82 match self {
83 Instr::Nop => Instr::Nop,
84 Instr::Add(l1, l2, s1) => Instr::Add(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
85 Instr::Sub(l1, l2, s1) => Instr::Sub(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
86 Instr::Mul(l1, l2, s1) => Instr::Mul(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
87 Instr::Div(l1, l2, s1) => Instr::Div(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
88 Instr::Mod(l1, l2, s1) => Instr::Mod(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
89 Instr::Neg(l1, s1) => Instr::Neg(l1.map(&mut f), s1.map(&mut f)),
90 Instr::Bitand(l1, l2, s1) => {
91 Instr::Bitand(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
92 }
93 Instr::Bitor(l1, l2, s1) => {
94 Instr::Bitor(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
95 }
96 Instr::Bitxor(l1, l2, s1) => {
97 Instr::Bitxor(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
98 }
99 Instr::Bitnot(l1, s1) => Instr::Bitnot(l1.map(&mut f), s1.map(&mut f)),
100 Instr::Shiftl(l1, l2, s1) => {
101 Instr::Shiftl(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
102 }
103 Instr::Ushiftr(l1, l2, s1) => {
104 Instr::Ushiftr(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
105 }
106 Instr::Sshiftr(l1, l2, s1) => {
107 Instr::Sshiftr(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
108 }
109 Instr::Jump(l1) => Instr::Jump(l1.map(&mut f)),
110 Instr::Jz(l1, l2) => Instr::Jz(l1.map(&mut f), l2.map(&mut f)),
111 Instr::Jnz(l1, l2) => Instr::Jnz(l1.map(&mut f), l2.map(&mut f)),
112 Instr::Jeq(l1, l2, l3) => Instr::Jeq(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
113 Instr::Jne(l1, l2, l3) => Instr::Jne(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
114 Instr::Jlt(l1, l2, l3) => Instr::Jlt(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
115 Instr::Jle(l1, l2, l3) => Instr::Jle(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
116 Instr::Jgt(l1, l2, l3) => Instr::Jgt(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
117 Instr::Jge(l1, l2, l3) => Instr::Jge(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
118 Instr::Jltu(l1, l2, l3) => Instr::Jltu(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
119 Instr::Jleu(l1, l2, l3) => Instr::Jleu(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
120 Instr::Jgtu(l1, l2, l3) => Instr::Jgtu(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
121 Instr::Jgeu(l1, l2, l3) => Instr::Jgeu(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
122 Instr::Jumpabs(l1) => Instr::Jumpabs(l1.map(&mut f)),
123 Instr::Copy(l1, s1) => Instr::Copy(l1.map(&mut f), s1.map(&mut f)),
124 Instr::Copys(l1, s1) => Instr::Copys(l1.map(&mut f), s1.map(&mut f)),
125 Instr::Copyb(l1, s1) => Instr::Copyb(l1.map(&mut f), s1.map(&mut f)),
126 Instr::Sexs(l1, s1) => Instr::Sexs(l1.map(&mut f), s1.map(&mut f)),
127 Instr::Sexb(l1, s1) => Instr::Sexb(l1.map(&mut f), s1.map(&mut f)),
128 Instr::Astore(l1, l2, l3) => {
129 Instr::Astore(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
130 }
131 Instr::Aload(l1, l2, s1) => {
132 Instr::Aload(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
133 }
134 Instr::Astores(l1, l2, l3) => {
135 Instr::Astores(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
136 }
137 Instr::Aloads(l1, l2, s1) => {
138 Instr::Aloads(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
139 }
140 Instr::Astoreb(l1, l2, l3) => {
141 Instr::Astoreb(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
142 }
143 Instr::Aloadb(l1, l2, s1) => {
144 Instr::Aloadb(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
145 }
146 Instr::Astorebit(l1, l2, l3) => {
147 Instr::Astorebit(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
148 }
149 Instr::Aloadbit(l1, l2, s1) => {
150 Instr::Aloadbit(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
151 }
152 Instr::Stkcount(s1) => Instr::Stkcount(s1.map(&mut f)),
153 Instr::Stkpeek(l1, s1) => Instr::Stkpeek(l1.map(&mut f), s1.map(&mut f)),
154 Instr::Stkswap => Instr::Stkswap,
155 Instr::Stkcopy(l1) => Instr::Stkcopy(l1.map(&mut f)),
156 Instr::Stkroll(l1, l2) => Instr::Stkroll(l1.map(&mut f), l2.map(&mut f)),
157 Instr::Call(l1, l2, s1) => Instr::Call(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
158 Instr::Callf(l1, s1) => Instr::Callf(l1.map(&mut f), s1.map(&mut f)),
159 Instr::Callfi(l1, l2, s1) => {
160 Instr::Callfi(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
161 }
162 Instr::Callfii(l1, l2, l3, s1) => Instr::Callfii(
163 l1.map(&mut f),
164 l2.map(&mut f),
165 l3.map(&mut f),
166 s1.map(&mut f),
167 ),
168 Instr::Callfiii(l1, l2, l3, l4, s1) => Instr::Callfiii(
169 l1.map(&mut f),
170 l2.map(&mut f),
171 l3.map(&mut f),
172 l4.map(&mut f),
173 s1.map(&mut f),
174 ),
175 Instr::Return(l1) => Instr::Return(l1.map(&mut f)),
176 Instr::Tailcall(l1, l2) => Instr::Tailcall(l1.map(&mut f), l2.map(&mut f)),
177 Instr::Catch(s1, l1) => Instr::Catch(s1.map(&mut f), l1.map(&mut f)),
178 Instr::Throw(l1, l2) => Instr::Throw(l1.map(&mut f), l2.map(&mut f)),
179 Instr::Getmemsize(s1) => Instr::Getmemsize(s1.map(&mut f)),
180 Instr::Setmemsize(l1, s1) => Instr::Setmemsize(l1.map(&mut f), s1.map(&mut f)),
181 Instr::Malloc(l1, s1) => Instr::Malloc(l1.map(&mut f), s1.map(&mut f)),
182 Instr::Mfree(l1) => Instr::Mfree(l1.map(&mut f)),
183 Instr::Quit => Instr::Quit,
184 Instr::Restart => Instr::Restart,
185 Instr::Save(l1, s1) => Instr::Save(l1.map(&mut f), s1.map(&mut f)),
186 Instr::Restore(l1, s1) => Instr::Restore(l1.map(&mut f), s1.map(&mut f)),
187 Instr::Saveundo(s1) => Instr::Saveundo(s1.map(&mut f)),
188 Instr::Restoreundo(s1) => Instr::Restoreundo(s1.map(&mut f)),
189 Instr::Hasundo(s1) => Instr::Hasundo(s1.map(&mut f)),
190 Instr::Discardundo => Instr::Discardundo,
191 Instr::Protect(l1, l2) => Instr::Protect(l1.map(&mut f), l2.map(&mut f)),
192 Instr::Verify(s1) => Instr::Verify(s1.map(&mut f)),
193 Instr::Getiosys(s1, s2) => Instr::Getiosys(s1.map(&mut f), s2.map(&mut f)),
194 Instr::Setiosys(l1, l2) => Instr::Setiosys(l1.map(&mut f), l2.map(&mut f)),
195 Instr::Streamchar(l1) => Instr::Streamchar(l1.map(&mut f)),
196 Instr::Streamunichar(l1) => Instr::Streamunichar(l1.map(&mut f)),
197 Instr::Streamnum(l1) => Instr::Streamnum(l1.map(&mut f)),
198 Instr::Streamstr(l1) => Instr::Streamstr(l1.map(&mut f)),
199 Instr::Getstringtbl(s1) => Instr::Getstringtbl(s1.map(&mut f)),
200 Instr::Setstringtbl(l1) => Instr::Setstringtbl(l1.map(&mut f)),
201 Instr::Numtof(l1, s1) => Instr::Numtof(l1.map(&mut f), s1.map(&mut f)),
202 Instr::Ftonumz(l1, s1) => Instr::Ftonumz(l1.map(&mut f), s1.map(&mut f)),
203 Instr::Ftonumn(l1, s1) => Instr::Ftonumn(l1.map(&mut f), s1.map(&mut f)),
204 Instr::Fadd(l1, l2, s1) => Instr::Fadd(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
205 Instr::Fsub(l1, l2, s1) => Instr::Fsub(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
206 Instr::Fmul(l1, l2, s1) => Instr::Fmul(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
207 Instr::Fdiv(l1, l2, s1) => Instr::Fdiv(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
208 Instr::Fmod(l1, l2, s1, s2) => Instr::Fmod(
209 l1.map(&mut f),
210 l2.map(&mut f),
211 s1.map(&mut f),
212 s2.map(&mut f),
213 ),
214 Instr::Ceil(l1, s1) => Instr::Ceil(l1.map(&mut f), s1.map(&mut f)),
215 Instr::Floor(l1, s1) => Instr::Floor(l1.map(&mut f), s1.map(&mut f)),
216 Instr::Sqrt(l1, s1) => Instr::Sqrt(l1.map(&mut f), s1.map(&mut f)),
217 Instr::Exp(l1, s1) => Instr::Exp(l1.map(&mut f), s1.map(&mut f)),
218 Instr::Log(l1, s1) => Instr::Log(l1.map(&mut f), s1.map(&mut f)),
219 Instr::Pow(l1, l2, s1) => Instr::Pow(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
220 Instr::Sin(l1, s1) => Instr::Sin(l1.map(&mut f), s1.map(&mut f)),
221 Instr::Cos(l1, s1) => Instr::Cos(l1.map(&mut f), s1.map(&mut f)),
222 Instr::Tan(l1, s1) => Instr::Tan(l1.map(&mut f), s1.map(&mut f)),
223 Instr::Asin(l1, s1) => Instr::Asin(l1.map(&mut f), s1.map(&mut f)),
224 Instr::Acos(l1, s1) => Instr::Acos(l1.map(&mut f), s1.map(&mut f)),
225 Instr::Atan(l1, s1) => Instr::Atan(l1.map(&mut f), s1.map(&mut f)),
226 Instr::Atan2(l1, s1) => Instr::Atan2(l1.map(&mut f), s1.map(&mut f)),
227 Instr::Numtod(l1, s1, s2) => {
228 Instr::Numtod(l1.map(&mut f), s1.map(&mut f), s2.map(&mut f))
229 }
230 Instr::Dtonumz(l1, l2, s1) => {
231 Instr::Dtonumz(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
232 }
233 Instr::Dtonumn(l1, l2, s1) => {
234 Instr::Dtonumn(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
235 }
236 Instr::Ftod(l1, s1, s2) => Instr::Ftod(l1.map(&mut f), s1.map(&mut f), s2.map(&mut f)),
237 Instr::Dtof(l1, l2, s1) => Instr::Dtof(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
238 Instr::Dadd(l1, l2, l3, l4, s1, s2) => Instr::Dadd(
239 l1.map(&mut f),
240 l2.map(&mut f),
241 l3.map(&mut f),
242 l4.map(&mut f),
243 s1.map(&mut f),
244 s2.map(&mut f),
245 ),
246 Instr::Dsub(l1, l2, l3, l4, s1, s2) => Instr::Dsub(
247 l1.map(&mut f),
248 l2.map(&mut f),
249 l3.map(&mut f),
250 l4.map(&mut f),
251 s1.map(&mut f),
252 s2.map(&mut f),
253 ),
254 Instr::Dmul(l1, l2, l3, l4, s1, s2) => Instr::Dmul(
255 l1.map(&mut f),
256 l2.map(&mut f),
257 l3.map(&mut f),
258 l4.map(&mut f),
259 s1.map(&mut f),
260 s2.map(&mut f),
261 ),
262 Instr::Ddiv(l1, l2, l3, l4, s1, s2) => Instr::Ddiv(
263 l1.map(&mut f),
264 l2.map(&mut f),
265 l3.map(&mut f),
266 l4.map(&mut f),
267 s1.map(&mut f),
268 s2.map(&mut f),
269 ),
270 Instr::Dmodr(l1, l2, l3, l4, s1, s2) => Instr::Dmodr(
271 l1.map(&mut f),
272 l2.map(&mut f),
273 l3.map(&mut f),
274 l4.map(&mut f),
275 s1.map(&mut f),
276 s2.map(&mut f),
277 ),
278 Instr::Dmodq(l1, l2, l3, l4, s1, s2) => Instr::Dmodq(
279 l1.map(&mut f),
280 l2.map(&mut f),
281 l3.map(&mut f),
282 l4.map(&mut f),
283 s1.map(&mut f),
284 s2.map(&mut f),
285 ),
286 Instr::Dceil(l1, l2, s1, s2) => Instr::Dceil(
287 l1.map(&mut f),
288 l2.map(&mut f),
289 s1.map(&mut f),
290 s2.map(&mut f),
291 ),
292 Instr::Dfloor(l1, l2, s1, s2) => Instr::Dfloor(
293 l1.map(&mut f),
294 l2.map(&mut f),
295 s1.map(&mut f),
296 s2.map(&mut f),
297 ),
298 Instr::Dsqrt(l1, l2, s1, s2) => Instr::Dsqrt(
299 l1.map(&mut f),
300 l2.map(&mut f),
301 s1.map(&mut f),
302 s2.map(&mut f),
303 ),
304 Instr::Dexp(l1, l2, s1, s2) => Instr::Dexp(
305 l1.map(&mut f),
306 l2.map(&mut f),
307 s1.map(&mut f),
308 s2.map(&mut f),
309 ),
310 Instr::Dlog(l1, l2, s1, s2) => Instr::Dlog(
311 l1.map(&mut f),
312 l2.map(&mut f),
313 s1.map(&mut f),
314 s2.map(&mut f),
315 ),
316 Instr::Dpow(l1, l2, l3, l4, s1, s2) => Instr::Dpow(
317 l1.map(&mut f),
318 l2.map(&mut f),
319 l3.map(&mut f),
320 l4.map(&mut f),
321 s1.map(&mut f),
322 s2.map(&mut f),
323 ),
324 Instr::Dsin(l1, l2, s1, s2) => Instr::Dsin(
325 l1.map(&mut f),
326 l2.map(&mut f),
327 s1.map(&mut f),
328 s2.map(&mut f),
329 ),
330 Instr::Dcos(l1, l2, s1, s2) => Instr::Dcos(
331 l1.map(&mut f),
332 l2.map(&mut f),
333 s1.map(&mut f),
334 s2.map(&mut f),
335 ),
336 Instr::Dtan(l1, l2, s1, s2) => Instr::Dtan(
337 l1.map(&mut f),
338 l2.map(&mut f),
339 s1.map(&mut f),
340 s2.map(&mut f),
341 ),
342 Instr::Dasin(l1, l2, s1, s2) => Instr::Dasin(
343 l1.map(&mut f),
344 l2.map(&mut f),
345 s1.map(&mut f),
346 s2.map(&mut f),
347 ),
348 Instr::Dacos(l1, l2, s1, s2) => Instr::Dacos(
349 l1.map(&mut f),
350 l2.map(&mut f),
351 s1.map(&mut f),
352 s2.map(&mut f),
353 ),
354 Instr::Datan(l1, l2, s1, s2) => Instr::Datan(
355 l1.map(&mut f),
356 l2.map(&mut f),
357 s1.map(&mut f),
358 s2.map(&mut f),
359 ),
360 Instr::Datan2(l1, l2, l3, l4, s1, s2) => Instr::Datan2(
361 l1.map(&mut f),
362 l2.map(&mut f),
363 l3.map(&mut f),
364 l4.map(&mut f),
365 s1.map(&mut f),
366 s2.map(&mut f),
367 ),
368 Instr::Jisnan(l1, l2) => Instr::Jisnan(l1.map(&mut f), l2.map(&mut f)),
369 Instr::Jisinf(l1, l2) => Instr::Jisinf(l1.map(&mut f), l2.map(&mut f)),
370 Instr::Jfeq(l1, l2, l3, l4) => Instr::Jfeq(
371 l1.map(&mut f),
372 l2.map(&mut f),
373 l3.map(&mut f),
374 l4.map(&mut f),
375 ),
376 Instr::Jfne(l1, l2, l3, l4) => Instr::Jfne(
377 l1.map(&mut f),
378 l2.map(&mut f),
379 l3.map(&mut f),
380 l4.map(&mut f),
381 ),
382 Instr::Jflt(l1, l2, l3) => Instr::Jflt(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
383 Instr::Jfle(l1, l2, l3) => Instr::Jfle(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
384 Instr::Jfgt(l1, l2, l3) => Instr::Jfgt(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
385 Instr::Jfge(l1, l2, l3) => Instr::Jfge(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f)),
386 Instr::Jdisnan(l1, l2, l3) => {
387 Instr::Jdisnan(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
388 }
389 Instr::Jdisinf(l1, l2, l3) => {
390 Instr::Jdisinf(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
391 }
392 Instr::Jdeq(l1, l2, l3, l4, l5, l6, l7) => Instr::Jdeq(
393 l1.map(&mut f),
394 l2.map(&mut f),
395 l3.map(&mut f),
396 l4.map(&mut f),
397 l5.map(&mut f),
398 l6.map(&mut f),
399 l7.map(&mut f),
400 ),
401 Instr::Jdne(l1, l2, l3, l4, l5, l6, l7) => Instr::Jdne(
402 l1.map(&mut f),
403 l2.map(&mut f),
404 l3.map(&mut f),
405 l4.map(&mut f),
406 l5.map(&mut f),
407 l6.map(&mut f),
408 l7.map(&mut f),
409 ),
410 Instr::Jdlt(l1, l2, l3, l4, l5) => Instr::Jdlt(
411 l1.map(&mut f),
412 l2.map(&mut f),
413 l3.map(&mut f),
414 l4.map(&mut f),
415 l5.map(&mut f),
416 ),
417 Instr::Jdle(l1, l2, l3, l4, l5) => Instr::Jdle(
418 l1.map(&mut f),
419 l2.map(&mut f),
420 l3.map(&mut f),
421 l4.map(&mut f),
422 l5.map(&mut f),
423 ),
424 Instr::Jdgt(l1, l2, l3, l4, l5) => Instr::Jdgt(
425 l1.map(&mut f),
426 l2.map(&mut f),
427 l3.map(&mut f),
428 l4.map(&mut f),
429 l5.map(&mut f),
430 ),
431 Instr::Jdge(l1, l2, l3, l4, l5) => Instr::Jdge(
432 l1.map(&mut f),
433 l2.map(&mut f),
434 l3.map(&mut f),
435 l4.map(&mut f),
436 l5.map(&mut f),
437 ),
438 Instr::Random(l1, s1) => Instr::Random(l1.map(&mut f), s1.map(&mut f)),
439 Instr::Setrandom(l1) => Instr::Setrandom(l1.map(&mut f)),
440 Instr::Mzero(l1, l2) => Instr::Mzero(l1.map(&mut f), l2.map(&mut f)),
441 Instr::Mcopy(l1, l2, l3) => {
442 Instr::Mcopy(l1.map(&mut f), l2.map(&mut f), l3.map(&mut f))
443 }
444 Instr::Linearsearch(l1, l2, l3, l4, l5, l6, l7, s1) => Instr::Linearsearch(
445 l1.map(&mut f),
446 l2.map(&mut f),
447 l3.map(&mut f),
448 l4.map(&mut f),
449 l5.map(&mut f),
450 l6.map(&mut f),
451 l7.map(&mut f),
452 s1.map(&mut f),
453 ),
454 Instr::Binarysearch(l1, l2, l3, l4, l5, l6, l7, s1) => Instr::Binarysearch(
455 l1.map(&mut f),
456 l2.map(&mut f),
457 l3.map(&mut f),
458 l4.map(&mut f),
459 l5.map(&mut f),
460 l6.map(&mut f),
461 l7.map(&mut f),
462 s1.map(&mut f),
463 ),
464 Instr::Linkedsearch(l1, l2, l3, l4, l5, l6, s1) => Instr::Linkedsearch(
465 l1.map(&mut f),
466 l2.map(&mut f),
467 l3.map(&mut f),
468 l4.map(&mut f),
469 l5.map(&mut f),
470 l6.map(&mut f),
471 s1.map(&mut f),
472 ),
473 Instr::Accelfunc(l1, l2) => Instr::Accelfunc(l1.map(&mut f), l2.map(&mut f)),
474 Instr::Accelparam(l1, l2) => Instr::Accelparam(l1.map(&mut f), l2.map(&mut f)),
475 Instr::Gestalt(l1, l2, s1) => {
476 Instr::Gestalt(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f))
477 }
478 Instr::Debugtrap(l1) => Instr::Debugtrap(l1.map(&mut f)),
479 Instr::Glk(l1, l2, s1) => Instr::Glk(l1.map(&mut f), l2.map(&mut f), s1.map(&mut f)),
480 }
481 }
482}
483
484impl<L> Instr<L>
485where
486 L: Clone,
487{
488 pub(crate) fn worst_len(&self) -> usize {
491 let opcode = self.opcode();
492 let opcode_length = opcode_len(opcode);
493
494 let operands_length: usize = match self {
495 Instr::Nop => 0,
496 Instr::Add(l1, l2, s1) => worst_len!(l1, l2, s1),
497 Instr::Sub(l1, l2, s1) => worst_len!(l1, l2, s1),
498 Instr::Mul(l1, l2, s1) => worst_len!(l1, l2, s1),
499 Instr::Div(l1, l2, s1) => worst_len!(l1, l2, s1),
500 Instr::Mod(l1, l2, s1) => worst_len!(l1, l2, s1),
501 Instr::Neg(l1, s1) => worst_len!(l1, s1),
502 Instr::Bitand(l1, l2, s1) => worst_len!(l1, l2, s1),
503 Instr::Bitor(l1, l2, s1) => worst_len!(l1, l2, s1),
504 Instr::Bitxor(l1, l2, s1) => worst_len!(l1, l2, s1),
505 Instr::Bitnot(l1, s1) => worst_len!(l1, s1),
506 Instr::Shiftl(l1, l2, s1) => worst_len!(l1, l2, s1),
507 Instr::Ushiftr(l1, l2, s1) => worst_len!(l1, l2, s1),
508 Instr::Sshiftr(l1, l2, s1) => worst_len!(l1, l2, s1),
509 Instr::Jump(l1) => worst_len!(l1),
510 Instr::Jz(l1, l2) => worst_len!(l1, l2),
511 Instr::Jnz(l1, l2) => worst_len!(l1, l2),
512 Instr::Jeq(l1, l2, l3) => worst_len!(l1, l2, l3),
513 Instr::Jne(l1, l2, l3) => worst_len!(l1, l2, l3),
514 Instr::Jlt(l1, l2, l3) => worst_len!(l1, l2, l3),
515 Instr::Jle(l1, l2, l3) => worst_len!(l1, l2, l3),
516 Instr::Jgt(l1, l2, l3) => worst_len!(l1, l2, l3),
517 Instr::Jge(l1, l2, l3) => worst_len!(l1, l2, l3),
518 Instr::Jltu(l1, l2, l3) => worst_len!(l1, l2, l3),
519 Instr::Jleu(l1, l2, l3) => worst_len!(l1, l2, l3),
520 Instr::Jgtu(l1, l2, l3) => worst_len!(l1, l2, l3),
521 Instr::Jgeu(l1, l2, l3) => worst_len!(l1, l2, l3),
522 Instr::Jumpabs(l1) => worst_len!(l1),
523 Instr::Copy(l1, s1) => worst_len!(l1, s1),
524 Instr::Copys(l1, s1) => worst_len!(l1, s1),
525 Instr::Copyb(l1, s1) => worst_len!(l1, s1),
526 Instr::Sexs(l1, s1) => worst_len!(l1, s1),
527 Instr::Sexb(l1, s1) => worst_len!(l1, s1),
528 Instr::Astore(l1, l2, l3) => worst_len!(l1, l2, l3),
529 Instr::Aload(l1, l2, s1) => worst_len!(l1, l2, s1),
530 Instr::Astores(l1, l2, l3) => worst_len!(l1, l2, l3),
531 Instr::Aloads(l1, l2, s1) => worst_len!(l1, l2, s1),
532 Instr::Astoreb(l1, l2, l3) => worst_len!(l1, l2, l3),
533 Instr::Aloadb(l1, l2, s1) => worst_len!(l1, l2, s1),
534 Instr::Astorebit(l1, l2, l3) => worst_len!(l1, l2, l3),
535 Instr::Aloadbit(l1, l2, s1) => worst_len!(l1, l2, s1),
536 Instr::Stkcount(s1) => worst_len!(s1),
537 Instr::Stkpeek(l1, s1) => worst_len!(l1, s1),
538 Instr::Stkswap => 0,
539 Instr::Stkcopy(l1) => worst_len!(l1),
540 Instr::Stkroll(l1, l2) => worst_len!(l1, l2),
541 Instr::Call(l1, l2, s1) => worst_len!(l1, l2, s1),
542 Instr::Callf(l1, s1) => worst_len!(l1, s1),
543 Instr::Callfi(l1, l2, s1) => worst_len!(l1, l2, s1),
544 Instr::Callfii(l1, l2, l3, s1) => worst_len!(l1, l2, l3, s1),
545 Instr::Callfiii(l1, l2, l3, l4, s1) => worst_len!(l1, l2, l3, l4, s1),
546 Instr::Return(l1) => worst_len!(l1),
547 Instr::Tailcall(l1, l2) => worst_len!(l1, l2),
548 Instr::Catch(s1, l1) => worst_len!(s1, l1),
549 Instr::Throw(l1, l2) => worst_len!(l1, l2),
550 Instr::Getmemsize(s1) => worst_len!(s1),
551 Instr::Setmemsize(l1, s1) => worst_len!(l1, s1),
552 Instr::Malloc(l1, s1) => worst_len!(l1, s1),
553 Instr::Mfree(l1) => worst_len!(l1),
554 Instr::Quit => 0,
555 Instr::Restart => 0,
556 Instr::Save(l1, s1) => worst_len!(l1, s1),
557 Instr::Restore(l1, s1) => worst_len!(l1, s1),
558 Instr::Saveundo(s1) => worst_len!(s1),
559 Instr::Restoreundo(s1) => worst_len!(s1),
560 Instr::Hasundo(s1) => worst_len!(s1),
561 Instr::Discardundo => 0,
562 Instr::Protect(l1, l2) => worst_len!(l1, l2),
563 Instr::Verify(s1) => worst_len!(s1),
564 Instr::Getiosys(s1, s2) => worst_len!(s1, s2),
565 Instr::Setiosys(l1, l2) => worst_len!(l1, l2),
566 Instr::Streamchar(l1) => worst_len!(l1),
567 Instr::Streamunichar(l1) => worst_len!(l1),
568 Instr::Streamnum(l1) => worst_len!(l1),
569 Instr::Streamstr(l1) => worst_len!(l1),
570 Instr::Getstringtbl(s1) => worst_len!(s1),
571 Instr::Setstringtbl(l1) => worst_len!(l1),
572 Instr::Numtof(l1, s1) => worst_len!(l1, s1),
573 Instr::Ftonumz(l1, s1) => worst_len!(l1, s1),
574 Instr::Ftonumn(l1, s1) => worst_len!(l1, s1),
575 Instr::Fadd(l1, l2, s1) => worst_len!(l1, l2, s1),
576 Instr::Fsub(l1, l2, s1) => worst_len!(l1, l2, s1),
577 Instr::Fmul(l1, l2, s1) => worst_len!(l1, l2, s1),
578 Instr::Fdiv(l1, l2, s1) => worst_len!(l1, l2, s1),
579 Instr::Fmod(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
580 Instr::Ceil(l1, s1) => worst_len!(l1, s1),
581 Instr::Floor(l1, s1) => worst_len!(l1, s1),
582 Instr::Sqrt(l1, s1) => worst_len!(l1, s1),
583 Instr::Exp(l1, s1) => worst_len!(l1, s1),
584 Instr::Log(l1, s1) => worst_len!(l1, s1),
585 Instr::Pow(l1, l2, s1) => worst_len!(l1, l2, s1),
586 Instr::Sin(l1, s1) => worst_len!(l1, s1),
587 Instr::Cos(l1, s1) => worst_len!(l1, s1),
588 Instr::Tan(l1, s1) => worst_len!(l1, s1),
589 Instr::Asin(l1, s1) => worst_len!(l1, s1),
590 Instr::Acos(l1, s1) => worst_len!(l1, s1),
591 Instr::Atan(l1, s1) => worst_len!(l1, s1),
592 Instr::Atan2(l1, s1) => worst_len!(l1, s1),
593 Instr::Numtod(l1, s1, s2) => worst_len!(l1, s1, s2),
594 Instr::Dtonumz(l1, l2, s1) => worst_len!(l1, l2, s1),
595 Instr::Dtonumn(l1, l2, s1) => worst_len!(l1, l2, s1),
596 Instr::Ftod(l1, s1, s2) => worst_len!(l1, s1, s2),
597 Instr::Dtof(l1, l2, s1) => worst_len!(l1, l2, s1),
598 Instr::Dadd(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
599 Instr::Dsub(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
600 Instr::Dmul(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
601 Instr::Ddiv(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
602 Instr::Dmodr(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
603 Instr::Dmodq(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
604 Instr::Dceil(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
605 Instr::Dfloor(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
606 Instr::Dsqrt(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
607 Instr::Dexp(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
608 Instr::Dlog(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
609 Instr::Dpow(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
610 Instr::Dsin(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
611 Instr::Dcos(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
612 Instr::Dtan(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
613 Instr::Dasin(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
614 Instr::Dacos(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
615 Instr::Datan(l1, l2, s1, s2) => worst_len!(l1, l2, s1, s2),
616 Instr::Datan2(l1, l2, l3, l4, s1, s2) => worst_len!(l1, l2, l3, l4, s1, s2),
617 Instr::Jisnan(l1, l2) => worst_len!(l1, l2),
618 Instr::Jisinf(l1, l2) => worst_len!(l1, l2),
619 Instr::Jfeq(l1, l2, l3, l4) => worst_len!(l1, l2, l3, l4),
620 Instr::Jfne(l1, l2, l3, l4) => worst_len!(l1, l2, l3, l4),
621 Instr::Jflt(l1, l2, l3) => worst_len!(l1, l2, l3),
622 Instr::Jfle(l1, l2, l3) => worst_len!(l1, l2, l3),
623 Instr::Jfgt(l1, l2, l3) => worst_len!(l1, l2, l3),
624 Instr::Jfge(l1, l2, l3) => worst_len!(l1, l2, l3),
625 Instr::Jdisnan(l1, l2, l3) => worst_len!(l1, l2, l3),
626 Instr::Jdisinf(l1, l2, l3) => worst_len!(l1, l2, l3),
627 Instr::Jdeq(l1, l2, l3, l4, l5, l6, l7) => worst_len!(l1, l2, l3, l4, l5, l6, l7),
628 Instr::Jdne(l1, l2, l3, l4, l5, l6, l7) => worst_len!(l1, l2, l3, l4, l5, l6, l7),
629 Instr::Jdlt(l1, l2, l3, l4, l5) => worst_len!(l1, l2, l3, l4, l5),
630 Instr::Jdle(l1, l2, l3, l4, l5) => worst_len!(l1, l2, l3, l4, l5),
631 Instr::Jdgt(l1, l2, l3, l4, l5) => worst_len!(l1, l2, l3, l4, l5),
632 Instr::Jdge(l1, l2, l3, l4, l5) => worst_len!(l1, l2, l3, l4, l5),
633 Instr::Random(l1, s1) => worst_len!(l1, s1),
634 Instr::Setrandom(l1) => worst_len!(l1),
635 Instr::Mzero(l1, l2) => worst_len!(l1, l2),
636 Instr::Mcopy(l1, l2, l3) => worst_len!(l1, l2, l3),
637 Instr::Linearsearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
638 worst_len!(l1, l2, l3, l4, l5, l6, l7, s1)
639 }
640 Instr::Binarysearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
641 worst_len!(l1, l2, l3, l4, l5, l6, l7, s1)
642 }
643 Instr::Linkedsearch(l1, l2, l3, l4, l5, l6, s1) => {
644 worst_len!(l1, l2, l3, l4, l5, l6, s1)
645 }
646 Instr::Accelfunc(l1, l2) => worst_len!(l1, l2),
647 Instr::Accelparam(l1, l2) => worst_len!(l1, l2),
648 Instr::Gestalt(l1, l2, s1) => worst_len!(l1, l2, s1),
649 Instr::Debugtrap(l1) => worst_len!(l1),
650 Instr::Glk(l1, l2, s1) => worst_len!(l1, l2, s1),
651 };
652
653 opcode_length + operands_length
654 }
655
656 pub fn opcode(&self) -> u32 {
658 match self {
659 Instr::Nop => 0x00,
660 Instr::Add(_, _, _) => 0x10,
661 Instr::Sub(_, _, _) => 0x11,
662 Instr::Mul(_, _, _) => 0x12,
663 Instr::Div(_, _, _) => 0x13,
664 Instr::Mod(_, _, _) => 0x14,
665 Instr::Neg(_, _) => 0x15,
666 Instr::Bitand(_, _, _) => 0x18,
667 Instr::Bitor(_, _, _) => 0x19,
668 Instr::Bitxor(_, _, _) => 0x1A,
669 Instr::Bitnot(_, _) => 0x1B,
670 Instr::Shiftl(_, _, _) => 0x1C,
671 Instr::Sshiftr(_, _, _) => 0x1D,
672 Instr::Ushiftr(_, _, _) => 0x1E,
673 Instr::Jump(_) => 0x20,
674 Instr::Jz(_, _) => 0x22,
675 Instr::Jnz(_, _) => 0x23,
676 Instr::Jeq(_, _, _) => 0x24,
677 Instr::Jne(_, _, _) => 0x25,
678 Instr::Jlt(_, _, _) => 0x26,
679 Instr::Jge(_, _, _) => 0x27,
680 Instr::Jgt(_, _, _) => 0x28,
681 Instr::Jle(_, _, _) => 0x29,
682 Instr::Jltu(_, _, _) => 0x2A,
683 Instr::Jgeu(_, _, _) => 0x2B,
684 Instr::Jgtu(_, _, _) => 0x2C,
685 Instr::Jleu(_, _, _) => 0x2D,
686 Instr::Call(_, _, _) => 0x30,
687 Instr::Return(_) => 0x31,
688 Instr::Catch(_, _) => 0x32,
689 Instr::Throw(_, _) => 0x33,
690 Instr::Tailcall(_, _) => 0x34,
691 Instr::Copy(_, _) => 0x40,
692 Instr::Copys(_, _) => 0x41,
693 Instr::Copyb(_, _) => 0x42,
694 Instr::Sexs(_, _) => 0x44,
695 Instr::Sexb(_, _) => 0x45,
696 Instr::Aload(_, _, _) => 0x48,
697 Instr::Aloads(_, _, _) => 0x49,
698 Instr::Aloadb(_, _, _) => 0x4A,
699 Instr::Aloadbit(_, _, _) => 0x4B,
700 Instr::Astore(_, _, _) => 0x4C,
701 Instr::Astores(_, _, _) => 0x4D,
702 Instr::Astoreb(_, _, _) => 0x4E,
703 Instr::Astorebit(_, _, _) => 0x4F,
704 Instr::Stkcount(_) => 0x50,
705 Instr::Stkpeek(_, _) => 0x51,
706 Instr::Stkswap => 0x52,
707 Instr::Stkroll(_, _) => 0x53,
708 Instr::Stkcopy(_) => 0x54,
709 Instr::Streamchar(_) => 0x70,
710 Instr::Streamnum(_) => 0x71,
711 Instr::Streamstr(_) => 0x72,
712 Instr::Streamunichar(_) => 0x73,
713 Instr::Gestalt(_, _, _) => 0x100,
714 Instr::Debugtrap(_) => 0x101,
715 Instr::Getmemsize(_) => 0x102,
716 Instr::Setmemsize(_, _) => 0x103,
717 Instr::Jumpabs(_) => 0x104,
718 Instr::Random(_, _) => 0x110,
719 Instr::Setrandom(_) => 0x111,
720 Instr::Quit => 0x120,
721 Instr::Verify(_) => 0x121,
722 Instr::Restart => 0x122,
723 Instr::Save(_, _) => 0x123,
724 Instr::Restore(_, _) => 0x124,
725 Instr::Saveundo(_) => 0x125,
726 Instr::Restoreundo(_) => 0x126,
727 Instr::Protect(_, _) => 0x127,
728 Instr::Hasundo(_) => 0x128,
729 Instr::Discardundo => 0x129,
730 Instr::Glk(_, _, _) => 0x130,
731 Instr::Getstringtbl(_) => 0x140,
732 Instr::Setstringtbl(_) => 0x141,
733 Instr::Getiosys(_, _) => 0x148,
734 Instr::Setiosys(_, _) => 0x149,
735 Instr::Linearsearch(_, _, _, _, _, _, _, _) => 0x150,
736 Instr::Binarysearch(_, _, _, _, _, _, _, _) => 0x151,
737 Instr::Linkedsearch(_, _, _, _, _, _, _) => 0x152,
738 Instr::Callf(_, _) => 0x160,
739 Instr::Callfi(_, _, _) => 0x161,
740 Instr::Callfii(_, _, _, _) => 0x162,
741 Instr::Callfiii(_, _, _, _, _) => 0x163,
742 Instr::Mzero(_, _) => 0x170,
743 Instr::Mcopy(_, _, _) => 0x171,
744 Instr::Malloc(_, _) => 0x178,
745 Instr::Mfree(_) => 0x179,
746 Instr::Accelfunc(_, _) => 0x180,
747 Instr::Accelparam(_, _) => 0x181,
748 Instr::Numtof(_, _) => 0x190,
749 Instr::Ftonumz(_, _) => 0x191,
750 Instr::Ftonumn(_, _) => 0x192,
751 Instr::Ceil(_, _) => 0x198,
752 Instr::Floor(_, _) => 0x199,
753 Instr::Fadd(_, _, _) => 0x1A0,
754 Instr::Fsub(_, _, _) => 0x1A1,
755 Instr::Fmul(_, _, _) => 0x1A2,
756 Instr::Fdiv(_, _, _) => 0x1A3,
757 Instr::Fmod(_, _, _, _) => 0x1A4,
758 Instr::Sqrt(_, _) => 0x1A8,
759 Instr::Exp(_, _) => 0x1A9,
760 Instr::Log(_, _) => 0x1AA,
761 Instr::Pow(_, _, _) => 0x1AB,
762 Instr::Sin(_, _) => 0x1B0,
763 Instr::Cos(_, _) => 0x1B1,
764 Instr::Tan(_, _) => 0x1B2,
765 Instr::Asin(_, _) => 0x1B3,
766 Instr::Acos(_, _) => 0x1B4,
767 Instr::Atan(_, _) => 0x1B5,
768 Instr::Atan2(_, _) => 0x1B6,
769 Instr::Jfeq(_, _, _, _) => 0x1C0,
770 Instr::Jfne(_, _, _, _) => 0x1C1,
771 Instr::Jflt(_, _, _) => 0x1C2,
772 Instr::Jfle(_, _, _) => 0x1C3,
773 Instr::Jfgt(_, _, _) => 0x1C4,
774 Instr::Jfge(_, _, _) => 0x1C5,
775 Instr::Jisnan(_, _) => 0x1C8,
776 Instr::Jisinf(_, _) => 0x1C9,
777 Instr::Numtod(_, _, _) => 0x200,
778 Instr::Dtonumz(_, _, _) => 0x201,
779 Instr::Dtonumn(_, _, _) => 0x202,
780 Instr::Ftod(_, _, _) => 0x203,
781 Instr::Dtof(_, _, _) => 0x204,
782 Instr::Dceil(_, _, _, _) => 0x208,
783 Instr::Dfloor(_, _, _, _) => 0x209,
784 Instr::Dadd(_, _, _, _, _, _) => 0x210,
785 Instr::Dsub(_, _, _, _, _, _) => 0x211,
786 Instr::Dmul(_, _, _, _, _, _) => 0x212,
787 Instr::Ddiv(_, _, _, _, _, _) => 0x213,
788 Instr::Dmodr(_, _, _, _, _, _) => 0x214,
789 Instr::Dmodq(_, _, _, _, _, _) => 0x215,
790 Instr::Dsqrt(_, _, _, _) => 0x218,
791 Instr::Dexp(_, _, _, _) => 0x219,
792 Instr::Dlog(_, _, _, _) => 0x21A,
793 Instr::Dpow(_, _, _, _, _, _) => 0x21B,
794 Instr::Dsin(_, _, _, _) => 0x220,
795 Instr::Dcos(_, _, _, _) => 0x221,
796 Instr::Dtan(_, _, _, _) => 0x222,
797 Instr::Dasin(_, _, _, _) => 0x223,
798 Instr::Dacos(_, _, _, _) => 0x224,
799 Instr::Datan(_, _, _, _) => 0x225,
800 Instr::Datan2(_, _, _, _, _, _) => 0x226,
801 Instr::Jdeq(_, _, _, _, _, _, _) => 0x230,
802 Instr::Jdne(_, _, _, _, _, _, _) => 0x231,
803 Instr::Jdlt(_, _, _, _, _) => 0x232,
804 Instr::Jdle(_, _, _, _, _) => 0x233,
805 Instr::Jdgt(_, _, _, _, _) => 0x234,
806 Instr::Jdge(_, _, _, _, _) => 0x235,
807 Instr::Jdisnan(_, _, _) => 0x238,
808 Instr::Jdisinf(_, _, _) => 0x239,
809 }
810 }
811
812 pub(crate) fn resolve<R>(
814 &self,
815 mut position: u32,
816 resolver: &R,
817 ) -> Result<RawInstr, AssemblerError<L>>
818 where
819 R: Resolver<Label = L>,
820 {
821 let opcode = self.opcode();
822 let opcode_length = u32::try_from(opcode_len(opcode)).unwrap();
823
824 position = position
825 .checked_add(opcode_length)
826 .ok_or(AssemblerError::Overflow)?;
827
828 let operands = match self {
829 Instr::Nop => resolve!(position, resolver,),
830 Instr::Add(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
831 Instr::Sub(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
832 Instr::Mul(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
833 Instr::Div(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
834 Instr::Mod(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
835 Instr::Neg(l1, s1) => resolve!(position, resolver, l1, s1),
836 Instr::Bitand(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
837 Instr::Bitor(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
838 Instr::Bitxor(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
839 Instr::Bitnot(l1, s1) => resolve!(position, resolver, l1, s1),
840 Instr::Shiftl(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
841 Instr::Ushiftr(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
842 Instr::Sshiftr(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
843 Instr::Jump(l1) => resolve!(position, resolver, l1),
844 Instr::Jz(l1, l2) => resolve!(position, resolver, l1, l2),
845 Instr::Jnz(l1, l2) => resolve!(position, resolver, l1, l2),
846 Instr::Jeq(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
847 Instr::Jne(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
848 Instr::Jlt(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
849 Instr::Jle(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
850 Instr::Jgt(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
851 Instr::Jge(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
852 Instr::Jltu(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
853 Instr::Jleu(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
854 Instr::Jgtu(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
855 Instr::Jgeu(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
856 Instr::Jumpabs(l1) => resolve!(position, resolver, l1),
857 Instr::Copy(l1, s1) => resolve!(position, resolver, l1, s1),
858 Instr::Copys(l1, s1) => resolve!(position, resolver, l1, s1),
859 Instr::Copyb(l1, s1) => resolve!(position, resolver, l1, s1),
860 Instr::Sexs(l1, s1) => resolve!(position, resolver, l1, s1),
861 Instr::Sexb(l1, s1) => resolve!(position, resolver, l1, s1),
862 Instr::Astore(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
863 Instr::Aload(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
864 Instr::Astores(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
865 Instr::Aloads(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
866 Instr::Astoreb(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
867 Instr::Aloadb(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
868 Instr::Astorebit(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
869 Instr::Aloadbit(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
870 Instr::Stkcount(s1) => resolve!(position, resolver, s1),
871 Instr::Stkpeek(l1, s1) => resolve!(position, resolver, l1, s1),
872 Instr::Stkswap => resolve!(position, resolver,),
873 Instr::Stkcopy(l1) => resolve!(position, resolver, l1),
874 Instr::Stkroll(l1, l2) => resolve!(position, resolver, l1, l2),
875 Instr::Call(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
876 Instr::Callf(l1, s1) => resolve!(position, resolver, l1, s1),
877 Instr::Callfi(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
878 Instr::Callfii(l1, l2, l3, s1) => {
879 resolve!(position, resolver, l1, l2, l3, s1)
880 }
881 Instr::Callfiii(l1, l2, l3, l4, s1) => {
882 resolve!(position, resolver, l1, l2, l3, l4, s1)
883 }
884 Instr::Return(l1) => resolve!(position, resolver, l1),
885 Instr::Tailcall(l1, l2) => resolve!(position, resolver, l1, l2),
886 Instr::Catch(s1, l1) => resolve!(position, resolver, s1, l1),
887 Instr::Throw(l1, l2) => resolve!(position, resolver, l1, l2),
888 Instr::Getmemsize(s1) => resolve!(position, resolver, s1),
889 Instr::Setmemsize(l1, s1) => resolve!(position, resolver, l1, s1),
890 Instr::Malloc(l1, s1) => resolve!(position, resolver, l1, s1),
891 Instr::Mfree(l1) => resolve!(position, resolver, l1),
892 Instr::Quit => resolve!(position, resolver,),
893 Instr::Restart => resolve!(position, resolver,),
894 Instr::Save(l1, s1) => resolve!(position, resolver, l1, s1),
895 Instr::Restore(l1, s1) => resolve!(position, resolver, l1, s1),
896 Instr::Saveundo(s1) => resolve!(position, resolver, s1),
897 Instr::Restoreundo(s1) => resolve!(position, resolver, s1),
898 Instr::Hasundo(s1) => resolve!(position, resolver, s1),
899 Instr::Discardundo => resolve!(position, resolver,),
900 Instr::Protect(l1, l2) => resolve!(position, resolver, l1, l2),
901 Instr::Verify(s1) => resolve!(position, resolver, s1),
902 Instr::Getiosys(s1, s2) => resolve!(position, resolver, s1, s2),
903 Instr::Setiosys(l1, l2) => resolve!(position, resolver, l1, l2),
904 Instr::Streamchar(l1) => resolve!(position, resolver, l1),
905 Instr::Streamunichar(l1) => resolve!(position, resolver, l1),
906 Instr::Streamnum(l1) => resolve!(position, resolver, l1),
907 Instr::Streamstr(l1) => resolve!(position, resolver, l1),
908 Instr::Getstringtbl(s1) => resolve!(position, resolver, s1),
909 Instr::Setstringtbl(l1) => resolve!(position, resolver, l1),
910 Instr::Numtof(l1, s1) => resolve!(position, resolver, l1, s1),
911 Instr::Ftonumz(l1, s1) => resolve!(position, resolver, l1, s1),
912 Instr::Ftonumn(l1, s1) => resolve!(position, resolver, l1, s1),
913 Instr::Fadd(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
914 Instr::Fsub(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
915 Instr::Fmul(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
916 Instr::Fdiv(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
917 Instr::Fmod(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
918 Instr::Ceil(l1, s1) => resolve!(position, resolver, l1, s1),
919 Instr::Floor(l1, s1) => resolve!(position, resolver, l1, s1),
920 Instr::Sqrt(l1, s1) => resolve!(position, resolver, l1, s1),
921 Instr::Exp(l1, s1) => resolve!(position, resolver, l1, s1),
922 Instr::Log(l1, s1) => resolve!(position, resolver, l1, s1),
923 Instr::Pow(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
924 Instr::Sin(l1, s1) => resolve!(position, resolver, l1, s1),
925 Instr::Cos(l1, s1) => resolve!(position, resolver, l1, s1),
926 Instr::Tan(l1, s1) => resolve!(position, resolver, l1, s1),
927 Instr::Asin(l1, s1) => resolve!(position, resolver, l1, s1),
928 Instr::Acos(l1, s1) => resolve!(position, resolver, l1, s1),
929 Instr::Atan(l1, s1) => resolve!(position, resolver, l1, s1),
930 Instr::Atan2(l1, s1) => resolve!(position, resolver, l1, s1),
931 Instr::Numtod(l1, s1, s2) => resolve!(position, resolver, l1, s1, s2),
932 Instr::Dtonumz(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
933 Instr::Dtonumn(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
934 Instr::Ftod(l1, s1, s2) => resolve!(position, resolver, l1, s1, s2),
935 Instr::Dtof(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
936 Instr::Dadd(l1, l2, l3, l4, s1, s2) => {
937 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
938 }
939 Instr::Dsub(l1, l2, l3, l4, s1, s2) => {
940 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
941 }
942 Instr::Dmul(l1, l2, l3, l4, s1, s2) => {
943 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
944 }
945 Instr::Ddiv(l1, l2, l3, l4, s1, s2) => {
946 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
947 }
948 Instr::Dmodr(l1, l2, l3, l4, s1, s2) => {
949 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
950 }
951 Instr::Dmodq(l1, l2, l3, l4, s1, s2) => {
952 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
953 }
954 Instr::Dceil(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
955 Instr::Dfloor(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
956 Instr::Dsqrt(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
957 Instr::Dexp(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
958 Instr::Dlog(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
959 Instr::Dpow(l1, l2, l3, l4, s1, s2) => {
960 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
961 }
962 Instr::Dsin(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
963 Instr::Dcos(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
964 Instr::Dtan(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
965 Instr::Dasin(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
966 Instr::Dacos(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
967 Instr::Datan(l1, l2, s1, s2) => resolve!(position, resolver, l1, l2, s1, s2),
968 Instr::Datan2(l1, l2, l3, l4, s1, s2) => {
969 resolve!(position, resolver, l1, l2, l3, l4, s1, s2)
970 }
971 Instr::Jisnan(l1, l2) => resolve!(position, resolver, l1, l2),
972 Instr::Jisinf(l1, l2) => resolve!(position, resolver, l1, l2),
973 Instr::Jfeq(l1, l2, l3, l4) => resolve!(position, resolver, l1, l2, l3, l4),
974 Instr::Jfne(l1, l2, l3, l4) => resolve!(position, resolver, l1, l2, l3, l4),
975 Instr::Jflt(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
976 Instr::Jfle(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
977 Instr::Jfgt(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
978 Instr::Jfge(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
979 Instr::Jdisnan(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
980 Instr::Jdisinf(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
981 Instr::Jdeq(l1, l2, l3, l4, l5, l6, l7) => {
982 resolve!(position, resolver, l1, l2, l3, l4, l5, l6, l7)
983 }
984 Instr::Jdne(l1, l2, l3, l4, l5, l6, l7) => {
985 resolve!(position, resolver, l1, l2, l3, l4, l5, l6, l7)
986 }
987 Instr::Jdlt(l1, l2, l3, l4, l5) => {
988 resolve!(position, resolver, l1, l2, l3, l4, l5)
989 }
990 Instr::Jdle(l1, l2, l3, l4, l5) => {
991 resolve!(position, resolver, l1, l2, l3, l4, l5)
992 }
993 Instr::Jdgt(l1, l2, l3, l4, l5) => {
994 resolve!(position, resolver, l1, l2, l3, l4, l5)
995 }
996 Instr::Jdge(l1, l2, l3, l4, l5) => {
997 resolve!(position, resolver, l1, l2, l3, l4, l5)
998 }
999 Instr::Random(l1, s1) => resolve!(position, resolver, l1, s1),
1000 Instr::Setrandom(l1) => resolve!(position, resolver, l1),
1001 Instr::Mzero(l1, l2) => resolve!(position, resolver, l1, l2),
1002 Instr::Mcopy(l1, l2, l3) => resolve!(position, resolver, l1, l2, l3),
1003 Instr::Linearsearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
1004 resolve!(position, resolver, l1, l2, l3, l4, l5, l6, l7, s1)
1005 }
1006 Instr::Binarysearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
1007 resolve!(position, resolver, l1, l2, l3, l4, l5, l6, l7, s1)
1008 }
1009 Instr::Linkedsearch(l1, l2, l3, l4, l5, l6, s1) => {
1010 resolve!(position, resolver, l1, l2, l3, l4, l5, l6, s1)
1011 }
1012 Instr::Accelfunc(l1, l2) => resolve!(position, resolver, l1, l2),
1013 Instr::Accelparam(l1, l2) => resolve!(position, resolver, l1, l2),
1014 Instr::Gestalt(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
1015 Instr::Debugtrap(l1) => resolve!(position, resolver, l1),
1016 Instr::Glk(l1, l2, s1) => resolve!(position, resolver, l1, l2, s1),
1017 };
1018
1019 Ok(RawInstr { opcode, operands })
1020 }
1021}
1022
1023impl<L> Display for Instr<L>
1024where
1025 L: Display,
1026{
1027 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
1028 match self {
1029 Instr::Nop => write!(f, "nop")?,
1030 Instr::Add(l1, l2, s1) => write!(f, "add {l1} {l2} {s1}")?,
1031 Instr::Sub(l1, l2, s1) => write!(f, "sub {l1} {l2} {s1}")?,
1032 Instr::Mul(l1, l2, s1) => write!(f, "mul {l1} {l2} {s1}")?,
1033 Instr::Div(l1, l2, s1) => write!(f, "div {l1} {l2} {s1}")?,
1034 Instr::Mod(l1, l2, s1) => write!(f, "mod {l1} {l2} {s1}")?,
1035 Instr::Neg(l1, s1) => write!(f, "neg {l1} {s1}")?,
1036 Instr::Bitand(l1, l2, s1) => write!(f, "bitand {l1} {l2} {s1}")?,
1037 Instr::Bitor(l1, l2, s1) => write!(f, "bitor {l1} {l2} {s1}")?,
1038 Instr::Bitxor(l1, l2, s1) => write!(f, "bitxor {l1} {l2} {s1}")?,
1039 Instr::Bitnot(l1, s1) => write!(f, "bitnot {l1} {s1}")?,
1040 Instr::Shiftl(l1, l2, s1) => write!(f, "shiftl {l1} {l2} {s1}")?,
1041 Instr::Ushiftr(l1, l2, s1) => write!(f, "ushiftr {l1} {l2} {s1}")?,
1042 Instr::Sshiftr(l1, l2, s1) => write!(f, "sshiftr {l1} {l2} {s1}")?,
1043 Instr::Jump(bt) => write!(f, "jump {bt}")?,
1044 Instr::Jz(l1, bt) => write!(f, "jz {l1} {bt}")?,
1045 Instr::Jnz(l1, bt) => write!(f, "jnz {l1} {bt}")?,
1046 Instr::Jeq(l1, l2, bt) => write!(f, "jeq {l1} {l2} {bt}")?,
1047 Instr::Jne(l1, l2, bt) => write!(f, "jne {l1} {l2} {bt}")?,
1048 Instr::Jlt(l1, l2, bt) => write!(f, "jlt {l1} {l2} {bt}")?,
1049 Instr::Jle(l1, l2, bt) => write!(f, "jle {l1} {l2} {bt}")?,
1050 Instr::Jgt(l1, l2, bt) => write!(f, "jgt {l1} {l2} {bt}")?,
1051 Instr::Jge(l1, l2, bt) => write!(f, "jge {l1} {l2} {bt}")?,
1052 Instr::Jltu(l1, l2, bt) => write!(f, "jltu {l1} {l2} {bt}")?,
1053 Instr::Jleu(l1, l2, bt) => write!(f, "jleu {l1} {l2} {bt}")?,
1054 Instr::Jgtu(l1, l2, bt) => write!(f, "jgtu {l1} {l2} {bt}")?,
1055 Instr::Jgeu(l1, l2, bt) => write!(f, "jgeu {l1} {l2} {bt}")?,
1056 Instr::Jumpabs(l1) => write!(f, "jumpabs {l1}")?,
1057 Instr::Copy(l1, s1) => write!(f, "copy {l1} {s1}")?,
1058 Instr::Copys(l1, s1) => write!(f, "copys {l1} {s1}")?,
1059 Instr::Copyb(l1, s1) => write!(f, "copyb {l1} {s1}")?,
1060 Instr::Sexs(l1, s1) => write!(f, "sexs {l1} {s1}")?,
1061 Instr::Sexb(l1, s1) => write!(f, "sexb {l1} {s1}")?,
1062 Instr::Astore(l1, l2, l3) => write!(f, "astore {l1} {l2} {l3}")?,
1063 Instr::Aload(l1, l2, s1) => write!(f, "aload {l1} {l2} {s1}")?,
1064 Instr::Astores(l1, l2, l3) => write!(f, "astores {l1} {l2} {l3}")?,
1065 Instr::Aloads(l1, l2, s1) => write!(f, "aloads {l1} {l2} {s1}")?,
1066 Instr::Astoreb(l1, l2, l3) => write!(f, "astoreb {l1} {l2} {l3}")?,
1067 Instr::Aloadb(l1, l2, s1) => write!(f, "aloadb {l1} {l2} {s1}")?,
1068 Instr::Astorebit(l1, l2, l3) => write!(f, "astorebit {l1} {l2} {l3}")?,
1069 Instr::Aloadbit(l1, l2, s1) => write!(f, "aloadbit {l1} {l2} {s1}")?,
1070 Instr::Stkcount(s1) => write!(f, "stkcount {s1}")?,
1071 Instr::Stkpeek(l1, s1) => write!(f, "stkpeek {l1} {s1}")?,
1072 Instr::Stkswap => write!(f, "stkswap")?,
1073 Instr::Stkcopy(l1) => write!(f, "stkcopy {l1}")?,
1074 Instr::Stkroll(l1, l2) => write!(f, "stkroll {l1} {l2}")?,
1075 Instr::Call(l1, l2, s1) => write!(f, "call {l1} {l2} {s1}")?,
1076 Instr::Callf(l1, s1) => write!(f, "callf {l1} {s1}")?,
1077 Instr::Callfi(l1, l2, s1) => write!(f, "callfi {l1} {l2} {s1}")?,
1078 Instr::Callfii(l1, l2, l3, s1) => write!(f, "callfii {l1} {l2} {l3} {s1}")?,
1079 Instr::Callfiii(l1, l2, l3, l4, s1) => write!(f, "callfiii {l1} {l2} {l3} {l4} {s1}")?,
1080 Instr::Return(l1) => write!(f, "return {l1}")?,
1081 Instr::Tailcall(l1, l2) => write!(f, "tailcall {l1} {l2}")?,
1082 Instr::Catch(s1, bt) => write!(f, "catch {s1} {bt}")?,
1083 Instr::Throw(l1, l2) => write!(f, "throw {l1} {l2}")?,
1084 Instr::Getmemsize(s1) => write!(f, "getmemsize {s1}")?,
1085 Instr::Setmemsize(l1, s1) => write!(f, "setmemsize {l1} {s1}")?,
1086 Instr::Malloc(l1, s1) => write!(f, "malloc {l1} {s1}")?,
1087 Instr::Mfree(l1) => write!(f, "mfree {l1}")?,
1088 Instr::Quit => write!(f, "quit")?,
1089 Instr::Restart => write!(f, "restart")?,
1090 Instr::Save(l1, s1) => write!(f, "save {l1} {s1}")?,
1091 Instr::Restore(l1, s1) => write!(f, "restore {l1} {s1}")?,
1092 Instr::Saveundo(s1) => write!(f, "saveundo {s1}")?,
1093 Instr::Restoreundo(s1) => write!(f, "restoreundo {s1}")?,
1094 Instr::Hasundo(s1) => write!(f, "hasundo {s1}")?,
1095 Instr::Discardundo => write!(f, "discardundo")?,
1096 Instr::Protect(l1, l2) => write!(f, "protect {l1} {l2}")?,
1097 Instr::Verify(s1) => write!(f, "verify {s1}")?,
1098 Instr::Getiosys(s1, s2) => write!(f, "getiosys {s1} {s2}")?,
1099 Instr::Setiosys(l1, l2) => write!(f, "setiosys {l1} {l2}")?,
1100 Instr::Streamchar(l1) => write!(f, "streamchar {l1}")?,
1101 Instr::Streamunichar(l1) => write!(f, "streamunichar {l1}")?,
1102 Instr::Streamnum(l1) => write!(f, "streamnum {l1}")?,
1103 Instr::Streamstr(l1) => write!(f, "streamstr {l1}")?,
1104 Instr::Getstringtbl(s1) => write!(f, "getstringtbl {s1}")?,
1105 Instr::Setstringtbl(l1) => write!(f, "setstringtbl {l1}")?,
1106 Instr::Numtof(l1, s1) => write!(f, "numtof {l1} {s1}")?,
1107 Instr::Ftonumz(l1, s1) => write!(f, "ftonumz {l1} {s1}")?,
1108 Instr::Ftonumn(l1, s1) => write!(f, "ftonumn {l1} {s1}")?,
1109 Instr::Fadd(l1, l2, s1) => write!(f, "fadd {l1} {l2} {s1}")?,
1110 Instr::Fsub(l1, l2, s1) => write!(f, "fsub {l1} {l2} {s1}")?,
1111 Instr::Fmul(l1, l2, s1) => write!(f, "fmul {l1} {l2} {s1}")?,
1112 Instr::Fdiv(l1, l2, s1) => write!(f, "fdiv {l1} {l2} {s1}")?,
1113 Instr::Fmod(l1, l2, s1, s2) => write!(f, "fmod {l1} {l2} {s1} {s2}")?,
1114 Instr::Ceil(l1, s1) => write!(f, "ceil {l1} {s1}")?,
1115 Instr::Floor(l1, s1) => write!(f, "floor {l1} {s1}")?,
1116 Instr::Sqrt(l1, s1) => write!(f, "sqrt {l1} {s1}")?,
1117 Instr::Exp(l1, s1) => write!(f, "exp {l1} {s1}")?,
1118 Instr::Log(l1, s1) => write!(f, "log {l1} {s1}")?,
1119 Instr::Pow(l1, l2, s1) => write!(f, "pow {l1} {l2} {s1}")?,
1120 Instr::Sin(l1, s1) => write!(f, "sin {l1} {s1}")?,
1121 Instr::Cos(l1, s1) => write!(f, "cos {l1} {s1}")?,
1122 Instr::Tan(l1, s1) => write!(f, "tan {l1} {s1}")?,
1123 Instr::Asin(l1, s1) => write!(f, "asin {l1} {s1}")?,
1124 Instr::Acos(l1, s1) => write!(f, "acos {l1} {s1}")?,
1125 Instr::Atan(l1, s1) => write!(f, "atan {l1} {s1}")?,
1126 Instr::Atan2(l1, s1) => write!(f, "atan2 {l1} {s1}")?,
1127 Instr::Numtod(l1, s1, s2) => write!(f, "numtod {l1} {s1} {s2}")?,
1128 Instr::Dtonumz(l1, l2, s1) => write!(f, "dtonumz {l1} {l2} {s1}")?,
1129 Instr::Dtonumn(l1, l2, s1) => write!(f, "dtonumn {l1} {l2} {s1}")?,
1130 Instr::Ftod(l1, s1, s2) => write!(f, "ftod {l1} {s1} {s2}")?,
1131 Instr::Dtof(l1, l2, s1) => write!(f, "dtof {l1} {l2} {s1}")?,
1132 Instr::Dadd(l1, l2, l3, l4, s1, s2) => write!(f, "dadd {l1} {l2} {l3} {l4} {s1} {s2}")?,
1133 Instr::Dsub(l1, l2, l3, l4, s1, s2) => write!(f, "dsub {l1} {l2} {l3} {l4} {s1} {s2}")?,
1134 Instr::Dmul(l1, l2, l3, l4, s1, s2) => write!(f, "dmul {l1} {l2} {l3} {l4} {s1} {s2}")?,
1135 Instr::Ddiv(l1, l2, l3, l4, s1, s2) => write!(f, "ddiv {l1} {l2} {l3} {l4} {s1} {s2}")?,
1136 Instr::Dmodr(l1, l2, l3, l4, s1, s2) => {
1137 write!(f, "dmodr {l1} {l2} {l3} {l4} {s1} {s2}")?
1138 }
1139 Instr::Dmodq(l1, l2, l3, l4, s1, s2) => {
1140 write!(f, "dmodq {l1} {l2} {l3} {l4} {s1} {s2}")?
1141 }
1142 Instr::Dceil(l1, l2, s1, s2) => write!(f, "dceil {l1} {l2} {s1} {s2}")?,
1143 Instr::Dfloor(l1, l2, s1, s2) => write!(f, "dfloor {l1} {l2} {s1} {s2}")?,
1144 Instr::Dsqrt(l1, l2, s1, s2) => write!(f, "dsqrt {l1} {l2} {s1} {s2}")?,
1145 Instr::Dexp(l1, l2, s1, s2) => write!(f, "dexp {l1} {l2} {s1} {s2}")?,
1146 Instr::Dlog(l1, l2, s1, s2) => write!(f, "dlog {l1} {l2} {s1} {s2}")?,
1147 Instr::Dpow(l1, l2, l3, l4, s1, s2) => write!(f, "dpow {l1} {l2} {l3} {l4} {s1} {s2}")?,
1148 Instr::Dsin(l1, l2, s1, s2) => write!(f, "dsin {l1} {l2} {s1} {s2}")?,
1149 Instr::Dcos(l1, l2, s1, s2) => write!(f, "dcos {l1} {l2} {s1} {s2}")?,
1150 Instr::Dtan(l1, l2, s1, s2) => write!(f, "dtan {l1} {l2} {s1} {s2}")?,
1151 Instr::Dasin(l1, l2, s1, s2) => write!(f, "dasin {l1} {l2} {s1} {s2}")?,
1152 Instr::Dacos(l1, l2, s1, s2) => write!(f, "dacos {l1} {l2} {s1} {s2}")?,
1153 Instr::Datan(l1, l2, s1, s2) => write!(f, "datan {l1} {l2} {s1} {s2}")?,
1154 Instr::Datan2(l1, l2, l3, l4, s1, s2) => {
1155 write!(f, "datan2 {l1} {l2} {l3} {l4} {s1} {s2}")?
1156 }
1157 Instr::Jisnan(l1, bt) => write!(f, "jisnan {l1} {bt}")?,
1158 Instr::Jisinf(l1, bt) => write!(f, "jisinf {l1} {bt}")?,
1159 Instr::Jfeq(l1, l2, l3, bt) => write!(f, "jfeq {l1} {l2} {l3} {bt}")?,
1160 Instr::Jfne(l1, l2, l3, bt) => write!(f, "jfne {l1} {l2} {l3} {bt}")?,
1161 Instr::Jflt(l1, l2, bt) => write!(f, "jflt {l1} {l2} {bt}")?,
1162 Instr::Jfle(l1, l2, bt) => write!(f, "jfle {l1} {l2} {bt}")?,
1163 Instr::Jfgt(l1, l2, bt) => write!(f, "jfgt {l1} {l2} {bt}")?,
1164 Instr::Jfge(l1, l2, bt) => write!(f, "jfge {l1} {l2} {bt}")?,
1165 Instr::Jdisnan(l1, l2, bt) => write!(f, "jdisnan {l1} {l2} {bt}")?,
1166 Instr::Jdisinf(l1, l2, bt) => write!(f, "jdisinf {l1} {l2} {bt}")?,
1167 Instr::Jdeq(l1, l2, l3, l4, l5, l6, bt) => {
1168 write!(f, "jdeq {l1} {l2} {l3} {l4} {l5} {l6} {bt}")?
1169 }
1170 Instr::Jdne(l1, l2, l3, l4, l5, l6, bt) => {
1171 write!(f, "jdne {l1} {l2} {l3} {l4} {l5} {l6} {bt}")?
1172 }
1173 Instr::Jdlt(l1, l2, l3, l4, bt) => write!(f, "jdlt {l1} {l2} {l3} {l4} {bt}")?,
1174 Instr::Jdle(l1, l2, l3, l4, bt) => write!(f, "jdle {l1} {l2} {l3} {l4} {bt}")?,
1175 Instr::Jdgt(l1, l2, l3, l4, bt) => write!(f, "jdgt {l1} {l2} {l3} {l4} {bt}")?,
1176 Instr::Jdge(l1, l2, l3, l4, bt) => write!(f, "jdge {l1} {l2} {l3} {l4} {bt}")?,
1177 Instr::Random(l1, s1) => write!(f, "random {l1} {s1}")?,
1178 Instr::Setrandom(l1) => write!(f, "setrandom {l1}")?,
1179 Instr::Mzero(l1, l2) => write!(f, "mzero {l1} {l2}")?,
1180 Instr::Mcopy(l1, l2, l3) => write!(f, "mcopy {l1} {l2} {l3}")?,
1181 Instr::Linearsearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
1182 write!(f, "linearsearch {l1} {l2} {l3} {l4} {l5} {l6} {l7} {s1}")?
1183 }
1184 Instr::Binarysearch(l1, l2, l3, l4, l5, l6, l7, s1) => {
1185 write!(f, "binarysearch {l1} {l2} {l3} {l4} {l5} {l6} {l7} {s1}")?
1186 }
1187 Instr::Linkedsearch(l1, l2, l3, l4, l5, l6, s1) => {
1188 write!(f, "linkedsearch {l1} {l2} {l3} {l4} {l5} {l6} {s1}")?
1189 }
1190 Instr::Accelfunc(l1, l2) => write!(f, "accelfunc {l1} {l2}")?,
1191 Instr::Accelparam(l1, l2) => write!(f, "accelparam {l1} {l2}")?,
1192 Instr::Gestalt(l1, l2, s1) => write!(f, "gestalt {l1} {l2} {s1}")?,
1193 Instr::Debugtrap(l1) => write!(f, "debugtrap {l1}")?,
1194 Instr::Glk(l1, l2, s1) => write!(f, "glk {l1} {l2} {s1}")?,
1195 }
1196 Ok(())
1197 }
1198}
1199
1200impl RawInstr {
1201 pub(crate) fn len(&self) -> usize {
1203 opcode_len(self.opcode)
1204 + self.operands.len().div_ceil(2)
1205 + self.operands.iter().map(|op| op.len()).sum::<usize>()
1206 }
1207
1208 pub(crate) fn serialize<B: BufMut>(&self, mut buf: B) {
1210 if self.opcode < 0x80 {
1211 buf.put_u8(
1212 self.opcode
1213 .try_into()
1214 .expect("opcode range should have already been checked"),
1215 )
1216 } else if self.opcode < 0x4000 {
1217 buf.put_u16(
1218 (self.opcode + 0x8000)
1219 .try_into()
1220 .expect("opcode range should have already been checked"),
1221 )
1222 } else {
1223 buf.put_u32(
1224 self.opcode
1225 .checked_add(0xC0000000)
1226 .expect("opcode should not exceed 0x0FFFFFFF"),
1227 )
1228 }
1229
1230 let mut odd = false;
1231 let mut modebyte: u8 = 0;
1232 for operand in &self.operands {
1233 if odd {
1234 modebyte += operand.mode() << 4;
1235 buf.put_u8(modebyte);
1236 odd = false;
1237 } else {
1238 modebyte = operand.mode();
1239 odd = true;
1240 }
1241 }
1242
1243 if odd {
1244 buf.put_u8(modebyte);
1245 }
1246
1247 for operand in &self.operands {
1248 operand.serialize(&mut buf)
1249 }
1250 }
1251}
1252
1253fn opcode_len(opcode: u32) -> usize {
1255 if opcode < 0x80 {
1256 1
1257 } else if opcode < 0x4000 {
1258 2
1259 } else {
1260 4
1261 }
1262}