1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <math.h>
22 #include <stdlib.h>
23 #include <string.h>
24
25 #include "Opcodes.h"
26 #include "PyrInterpreter.h"
27 #include "PyrPrimitive.h"
28 #include "PyrPrimitiveProto.h"
29 #include "PyrMathPrim.h"
30 #include "PyrKernel.h"
31 #include "PyrMessage.h"
32 #include "PyrParseNode.h"
33 #include "PyrSignal.h"
34 #include "PyrSched.h"
35 #include "PyrSymbol.h"
36 #include "SC_InlineUnaryOp.h"
37 #include "SC_InlineBinaryOp.h"
38 #include "MiscInlineMath.h"
39 #include "PyrKernelProto.h"
40
41 #include <limits>
42
43 double hypotx(double x, double y);
44
45 #define IS_BINARY_BOOL_OP(op) ((op) >= opEQ && (op) <= opGE)
46
doSpecialUnaryArithMsg(VMGlobals * g,int numArgsPushed)47 int doSpecialUnaryArithMsg(VMGlobals* g, int numArgsPushed) {
48 PyrSlot* a;
49 PyrSymbol* msg;
50 int opcode = g->primitiveIndex;
51
52 a = g->sp;
53
54 switch (GetTag(a)) {
55 case tagInt:
56 switch (opcode) {
57 case opNeg:
58 SetRaw(a, -slotRawInt(a));
59 break;
60 // case opNot : goto send_normal_1;
61 case opIsNil:
62 SetFalse(a);
63 break;
64 case opNotNil:
65 SetTrue(a);
66 break;
67 case opBitNot:
68 SetRaw(a, ~slotRawInt(a));
69 break;
70 case opAbs:
71 SetRaw(a, sc_abs(slotRawInt(a)));
72 break;
73 case opAsFloat:
74 SetFloat(a, (double)slotRawInt(a));
75 break;
76 case opAsInteger:
77 SetRaw(a, (int)slotRawInt(a));
78 break;
79 case opCeil:
80 SetRaw(a, slotRawInt(a));
81 break;
82 case opFloor:
83 SetRaw(a, slotRawInt(a));
84 break;
85 case opFrac:
86 SetRaw(a, 0);
87 break;
88 case opSign:
89 SetRaw(a, slotRawInt(a) > 0 ? 1 : (slotRawInt(a) == 0 ? 0 : -1));
90 break;
91 case opSquared:
92 SetRaw(a, slotRawInt(a) * slotRawInt(a));
93 break;
94 case opCubed:
95 SetRaw(a, slotRawInt(a) * slotRawInt(a) * slotRawInt(a));
96 break;
97 case opSqrt:
98 SetFloat(a, sqrt((double)slotRawInt(a)));
99 break;
100 case opExp:
101 SetFloat(a, exp((double)slotRawInt(a)));
102 break;
103 case opRecip:
104 SetFloat(a, 1. / slotRawInt(a));
105 break;
106 case opMIDICPS:
107 SetFloat(a, sc_midicps((double)slotRawInt(a)));
108 break;
109 case opCPSMIDI:
110 SetFloat(a, sc_cpsmidi((double)slotRawInt(a)));
111 break;
112 case opMIDIRatio:
113 SetFloat(a, sc_midiratio((double)slotRawInt(a)));
114 break;
115 case opRatioMIDI:
116 SetFloat(a, sc_ratiomidi((double)slotRawInt(a)));
117 break;
118 case opAmpDb:
119 SetFloat(a, sc_ampdb((double)slotRawInt(a)));
120 break;
121 case opDbAmp:
122 SetFloat(a, sc_dbamp((double)slotRawInt(a)));
123 break;
124 case opOctCPS:
125 SetFloat(a, sc_octcps((double)slotRawInt(a)));
126 break;
127 case opCPSOct:
128 SetFloat(a, sc_cpsoct((double)slotRawInt(a)));
129 break;
130 case opLog:
131 SetFloat(a, log((double)slotRawInt(a)));
132 break;
133 case opLog2:
134 SetFloat(a, sc_log2((double)slotRawInt(a)));
135 break;
136 case opLog10:
137 SetFloat(a, log10((double)slotRawInt(a)));
138 break;
139 case opSin:
140 SetFloat(a, sin((double)slotRawInt(a)));
141 break;
142 case opCos:
143 SetFloat(a, cos((double)slotRawInt(a)));
144 break;
145 case opTan:
146 SetFloat(a, tan((double)slotRawInt(a)));
147 break;
148 case opArcSin:
149 SetFloat(a, asin((double)slotRawInt(a)));
150 break;
151 case opArcCos:
152 SetFloat(a, acos((double)slotRawInt(a)));
153 break;
154 case opArcTan:
155 SetFloat(a, atan((double)slotRawInt(a)));
156 break;
157 case opSinH:
158 SetFloat(a, sinh((double)slotRawInt(a)));
159 break;
160 case opCosH:
161 SetFloat(a, cosh((double)slotRawInt(a)));
162 break;
163 case opTanH:
164 SetFloat(a, tanh((double)slotRawInt(a)));
165 break;
166 case opRand:
167 SetRaw(a, g->rgen->irand(slotRawInt(a)));
168 break;
169 case opRand2:
170 SetRaw(a, g->rgen->irand2(slotRawInt(a)));
171 break;
172 case opLinRand:
173 SetRaw(a, g->rgen->ilinrand(slotRawInt(a)));
174 break;
175 case opBiLinRand:
176 SetRaw(a, g->rgen->ibilinrand(slotRawInt(a)));
177 break;
178
179 // case opExpRand : SetFloat(a, g->rgen->exprand(slotRawInt(a))); break;
180 // case opBiExpRand : SetFloat(a, g->rgen->biexprand(slotRawInt(a))); break;
181 case opSum3Rand:
182 SetFloat(a, g->rgen->sum3rand(slotRawInt(a)));
183 break;
184
185 // case opGammaRand : SetFloat(a, g->rgen->gammarand(slotRawInt(a))); break;
186 // case opGaussRand : SetFloat(a, g->rgen->gaussrand(slotRawInt(a))); break;
187 // case opPoiRand : SetFloat(a, g->rgen->poirand(slotRawInt(a))); break;
188
189 case opDistort:
190 SetFloat(a, sc_distort((double)slotRawInt(a)));
191 break;
192 case opSoftClip:
193 SetFloat(a, sc_softclip((double)slotRawInt(a)));
194 break;
195 case opCoin:
196 SetBool(a, (slotRawInt(a)));
197 break;
198 case opRectWindow:
199 SetFloat(a, sc_rectwindow((double)slotRawInt(a)));
200 break;
201 case opHanWindow:
202 SetFloat(a, sc_hanwindow((double)slotRawInt(a)));
203 break;
204 case opWelchWindow:
205 SetFloat(a, sc_welwindow((double)slotRawInt(a)));
206 break;
207 case opTriWindow:
208 SetFloat(a, sc_triwindow((double)slotRawInt(a)));
209 break;
210 case opSCurve:
211 SetFloat(a, sc_scurve((double)slotRawInt(a)));
212 break;
213 case opRamp:
214 SetFloat(a, sc_ramp((double)slotRawInt(a)));
215 break;
216 default:
217 goto send_normal_1;
218 }
219 break;
220 case tagChar:
221 switch (opcode) {
222 // case opNot : goto send_normal_1;
223 case opIsNil:
224 SetFalse(a);
225 break;
226 case opNotNil:
227 SetTrue(a);
228 break;
229 case opAsInteger:
230 SetTagRaw(a, tagInt);
231 break;
232 case opDigitValue:
233 if (slotRawInt(a) >= '0' && slotRawInt(a) <= '9')
234 SetInt(a, slotRawInt(a) - '0');
235 else if (slotRawInt(a) >= 'A' && slotRawInt(a) <= 'Z')
236 SetInt(a, slotRawInt(a) - 'A');
237 else if (slotRawInt(a) >= 'a' && slotRawInt(a) <= 'z')
238 SetInt(a, slotRawInt(a) - 'a');
239 else
240 SetInt(a, 0);
241 break;
242 default:
243 goto send_normal_1;
244 }
245 break;
246 case tagPtr:
247 switch (opcode) {
248 case opIsNil:
249 SetFalse(a);
250 break;
251 case opNotNil:
252 SetTrue(a);
253 break;
254 default:
255 goto send_normal_1;
256 }
257 break;
258 case tagNil:
259 switch (opcode) {
260 case opIsNil:
261 SetTrue(a);
262 break;
263 case opNotNil:
264 SetFalse(a);
265 break;
266 default:
267 goto send_normal_1;
268 }
269 break;
270 case tagFalse:
271 switch (opcode) {
272 case opNot:
273 SetTrue(a);
274 break;
275 case opIsNil: /*SetFalse(a);*/
276 break;
277 case opNotNil:
278 SetTrue(a);
279 break;
280 default:
281 goto send_normal_1;
282 }
283 break;
284 case tagTrue:
285 switch (opcode) {
286 case opNot:
287 SetFalse(a);
288 break;
289 case opIsNil:
290 SetFalse(a);
291 break;
292 case opNotNil: /*SetTrue(a);*/
293 break;
294 default:
295 goto send_normal_1;
296 }
297 break;
298 case tagSym:
299 switch (opcode) {
300 case opAsFloat:
301 case opAsInteger:
302 goto send_normal_1;
303 case opIsNil:
304 SetFalse(a);
305 break;
306 case opNotNil:
307 SetTrue(a);
308 break;
309 default: /* SetSymbol(a, slotRawSymbol(a)); */
310 break;
311 }
312 break;
313 case tagObj:
314 if (isKindOf(slotRawObject(a), class_signal)) {
315 switch (opcode) {
316 case opNeg:
317 SetRaw(a, signal_invert(g, slotRawObject(a)));
318 break;
319 case opIsNil:
320 SetFalse(a);
321 break;
322 case opNotNil:
323 SetTrue(a);
324 break;
325 case opAbs:
326 SetRaw(a, signal_abs(g, slotRawObject(a)));
327 break;
328 case opSign:
329 SetRaw(a, signal_sign(g, slotRawObject(a)));
330 break;
331 case opSquared:
332 SetRaw(a, signal_squared(g, slotRawObject(a)));
333 break;
334 case opCubed:
335 SetRaw(a, signal_cubed(g, slotRawObject(a)));
336 break;
337 case opSqrt:
338 SetRaw(a, signal_sqrt(g, slotRawObject(a)));
339 break;
340 case opExp:
341 SetRaw(a, signal_exp(g, slotRawObject(a)));
342 break;
343 case opRecip:
344 SetRaw(a, signal_recip(g, slotRawObject(a)));
345 break;
346 case opLog:
347 SetRaw(a, signal_log(g, slotRawObject(a)));
348 break;
349 case opLog2:
350 SetRaw(a, signal_log2(g, slotRawObject(a)));
351 break;
352 case opLog10:
353 SetRaw(a, signal_log10(g, slotRawObject(a)));
354 break;
355 case opSin:
356 SetRaw(a, signal_sin(g, slotRawObject(a)));
357 break;
358 // case opSin : SetRaw(a, signal_fsin(g, slotRawObject(a))); break;
359 case opCos:
360 SetRaw(a, signal_cos(g, slotRawObject(a)));
361 break;
362 case opTan:
363 SetRaw(a, signal_tan(g, slotRawObject(a)));
364 break;
365 case opArcSin:
366 SetRaw(a, signal_asin(g, slotRawObject(a)));
367 break;
368 case opArcCos:
369 SetRaw(a, signal_acos(g, slotRawObject(a)));
370 break;
371 case opArcTan:
372 SetRaw(a, signal_atan(g, slotRawObject(a)));
373 break;
374 case opSinH:
375 SetRaw(a, signal_sinh(g, slotRawObject(a)));
376 break;
377 case opCosH:
378 SetRaw(a, signal_cosh(g, slotRawObject(a)));
379 break;
380 case opTanH:
381 SetRaw(a, signal_tanh(g, slotRawObject(a)));
382 break;
383 case opDistort:
384 SetRaw(a, signal_distort(g, slotRawObject(a)));
385 break;
386 case opSoftClip:
387 SetRaw(a, signal_softclip(g, slotRawObject(a)));
388 break;
389 default:
390 goto send_normal_1;
391 }
392 } else {
393 goto send_normal_1;
394 }
395 break;
396 default: // double
397 switch (opcode) {
398 case opNeg:
399 SetRaw(a, -slotRawFloat(a));
400 break;
401 case opIsNil:
402 SetFalse(a);
403 break;
404 case opNotNil:
405 SetTrue(a);
406 break;
407 case opBitNot:
408 SetRaw(a, ~(int)slotRawFloat(a));
409 break;
410 case opAbs:
411 SetRaw(a, sc_abs(slotRawFloat(a)));
412 break;
413 case opAsFloat:
414 SetRaw(a, (double)slotRawFloat(a));
415 break;
416 case opAsInteger: {
417 double val = slotRawFloat(a);
418 if (val == std::numeric_limits<double>::infinity())
419 SetInt(a, std::numeric_limits<int>::max());
420 else
421 SetInt(a, (int)val);
422 break;
423 }
424 case opCeil:
425 SetRaw(a, ceil(slotRawFloat(a)));
426 break;
427 case opFloor:
428 SetRaw(a, floor(slotRawFloat(a)));
429 break;
430 case opFrac:
431 SetRaw(a, sc_frac(slotRawFloat(a)));
432 break;
433 case opSign:
434 SetRaw(a, slotRawFloat(a) > 0. ? 1.0 : (slotRawFloat(a) == 0 ? 0.0 : -1.0));
435 break;
436 case opSquared:
437 SetRaw(a, slotRawFloat(a) * slotRawFloat(a));
438 break;
439 case opCubed:
440 SetRaw(a, slotRawFloat(a) * slotRawFloat(a) * slotRawFloat(a));
441 break;
442 case opSqrt:
443 SetRaw(a, sqrt(slotRawFloat(a)));
444 break;
445 case opExp:
446 SetRaw(a, exp(slotRawFloat(a)));
447 break;
448 case opRecip:
449 SetRaw(a, 1. / slotRawFloat(a));
450 break;
451 case opMIDICPS:
452 SetRaw(a, sc_midicps(slotRawFloat(a)));
453 break;
454 case opCPSMIDI:
455 SetRaw(a, sc_cpsmidi(slotRawFloat(a)));
456 break;
457 case opMIDIRatio:
458 SetRaw(a, sc_midiratio((double)slotRawFloat(a)));
459 break;
460 case opRatioMIDI:
461 SetRaw(a, sc_ratiomidi((double)slotRawFloat(a)));
462 break;
463 case opAmpDb:
464 SetRaw(a, sc_ampdb(slotRawFloat(a)));
465 break;
466 case opDbAmp:
467 SetRaw(a, sc_dbamp(slotRawFloat(a)));
468 break;
469 case opOctCPS:
470 SetRaw(a, sc_octcps(slotRawFloat(a)));
471 break;
472 case opCPSOct:
473 SetRaw(a, sc_cpsoct(slotRawFloat(a)));
474 break;
475 case opLog:
476 SetRaw(a, log(slotRawFloat(a)));
477 break;
478 case opLog2:
479 SetRaw(a, sc_log2(slotRawFloat(a)));
480 break;
481 case opLog10:
482 SetRaw(a, log10(slotRawFloat(a)));
483 break;
484 case opSin:
485 SetRaw(a, sin(slotRawFloat(a)));
486 break;
487 case opCos:
488 SetRaw(a, cos(slotRawFloat(a)));
489 break;
490 case opTan:
491 SetRaw(a, tan(slotRawFloat(a)));
492 break;
493 case opArcSin:
494 SetRaw(a, asin(slotRawFloat(a)));
495 break;
496 case opArcCos:
497 SetRaw(a, acos(slotRawFloat(a)));
498 break;
499 case opArcTan:
500 SetRaw(a, atan(slotRawFloat(a)));
501 break;
502 case opSinH:
503 SetRaw(a, sinh(slotRawFloat(a)));
504 break;
505 case opCosH:
506 SetRaw(a, cosh(slotRawFloat(a)));
507 break;
508 case opTanH:
509 SetRaw(a, tanh(slotRawFloat(a)));
510 break;
511 case opRand:
512 SetRaw(a, g->rgen->frand() * slotRawFloat(a));
513 break;
514 case opRand2:
515 SetRaw(a, g->rgen->frand2() * slotRawFloat(a));
516 break;
517 case opLinRand:
518 SetRaw(a, g->rgen->linrand(slotRawFloat(a)));
519 break;
520 case opBiLinRand:
521 SetRaw(a, g->rgen->bilinrand(slotRawFloat(a)));
522 break;
523
524 // case opExpRand : SetRaw(a, g->rgen->exprand(slotRawFloat(a))); break;
525 // case opBiExpRand : SetRaw(a, g->rgen->biexprand(slotRawFloat(a))); break;
526 case opSum3Rand:
527 SetRaw(a, g->rgen->sum3rand(slotRawFloat(a)));
528 break;
529
530 // case opGammaRand : SetRaw(a, g->rgen->gammarand(slotRawFloat(a))); break;
531 // case opGaussRand : SetRaw(a, g->rgen->gaussrand(slotRawFloat(a))); break;
532 // case opPoiRand : SetRaw(a, g->rgen->poirand(slotRawFloat(a))); break;
533
534 case opDistort:
535 SetRaw(a, sc_distort(slotRawFloat(a)));
536 break;
537 case opSoftClip:
538 SetRaw(a, sc_softclip(slotRawFloat(a)));
539 break;
540 case opCoin:
541 SetBool(a, g->rgen->frand() < slotRawFloat(a));
542 break;
543 case opRectWindow:
544 SetRaw(a, sc_rectwindow(slotRawFloat(a)));
545 break;
546 case opHanWindow:
547 SetRaw(a, sc_hanwindow(slotRawFloat(a)));
548 break;
549 case opWelchWindow:
550 SetRaw(a, sc_welwindow(slotRawFloat(a)));
551 break;
552 case opTriWindow:
553 SetRaw(a, sc_triwindow(slotRawFloat(a)));
554 break;
555 case opSCurve:
556 SetRaw(a, sc_scurve(slotRawFloat(a)));
557 break;
558 case opRamp:
559 SetRaw(a, sc_ramp(slotRawFloat(a)));
560 break;
561 default:
562 goto send_normal_1;
563 }
564 break;
565 }
566
567 #if TAILCALLOPTIMIZE
568 g->tailCall = 0;
569 #endif
570 return errNone;
571
572 send_normal_1:
573 if (numArgsPushed != -1) // special case flag meaning it is a primitive
574 return errFailed;
575
576 msg = gSpecialUnarySelectors[opcode];
577 sendMessage(g, msg, 1);
578
579 return errNone;
580 }
581
prSpecialBinaryArithMsg(VMGlobals * g,int numArgsPushed)582 int prSpecialBinaryArithMsg(VMGlobals* g, int numArgsPushed) { return doSpecialBinaryArithMsg(g, numArgsPushed, true); }
583
doSpecialBinaryArithMsg(VMGlobals * g,int numArgsPushed,bool isPrimitive)584 int doSpecialBinaryArithMsg(VMGlobals* g, int numArgsPushed, bool isPrimitive) {
585 PyrSlot *a, *b;
586 PyrSymbol* msg;
587 int opcode = g->primitiveIndex;
588
589 a = g->sp - (numArgsPushed - 1);
590 b = a + 1;
591
592 switch (GetTag(a)) {
593 case tagInt: {
594 switch (GetTag(b)) {
595 case tagInt:
596 switch (opcode) {
597 case opAdd:
598 SetRaw(a, slotRawInt(a) + slotRawInt(b));
599 break;
600 case opSub:
601 SetRaw(a, slotRawInt(a) - slotRawInt(b));
602 break;
603 case opMul:
604 SetRaw(a, slotRawInt(a) * slotRawInt(b));
605 break;
606 case opIDiv:
607 SetRaw(a, sc_div(slotRawInt(a), slotRawInt(b)));
608 break;
609 case opFDiv:
610 SetFloat(a, (double)slotRawInt(a) / (double)slotRawInt(b));
611 break;
612 case opMod:
613 SetRaw(a, sc_mod((int)slotRawInt(a), (int)slotRawInt(b)));
614 break;
615 case opEQ:
616 SetBool(a, slotRawInt(a) == slotRawInt(b));
617 break;
618 case opNE:
619 SetBool(a, slotRawInt(a) != slotRawInt(b));
620 break;
621 case opLT:
622 SetBool(a, slotRawInt(a) < slotRawInt(b));
623 break;
624 case opGT:
625 SetBool(a, slotRawInt(a) > slotRawInt(b));
626 break;
627 case opLE:
628 SetBool(a, slotRawInt(a) <= slotRawInt(b));
629 break;
630 case opGE:
631 SetBool(a, slotRawInt(a) >= slotRawInt(b));
632 break;
633 // case opIdentical : SetBool(a, slotRawInt(a) == slotRawInt(b)); break;
634 // case opNotIdentical : SetBool(a, slotRawInt(a) != slotRawInt(b)); break;
635 case opMin:
636 SetRaw(a, sc_min(slotRawInt(a), slotRawInt(b)));
637 break;
638 case opMax:
639 SetRaw(a, sc_max(slotRawInt(a), slotRawInt(b)));
640 break;
641 case opBitAnd:
642 SetRaw(a, slotRawInt(a) & slotRawInt(b));
643 break;
644 case opBitOr:
645 SetRaw(a, slotRawInt(a) | slotRawInt(b));
646 break;
647 case opBitXor:
648 SetRaw(a, slotRawInt(a) ^ slotRawInt(b));
649 break;
650 case opLCM:
651 SetRaw(a, sc_lcm((long)slotRawInt(a), (long)slotRawInt(b)));
652 break;
653 case opGCD:
654 SetRaw(a, sc_gcd((long)slotRawInt(a), (long)slotRawInt(b)));
655 break;
656 case opRound:
657 SetRaw(a, sc_round((int)slotRawInt(a), (int)slotRawInt(b)));
658 break;
659 case opRoundUp:
660 SetRaw(a, sc_roundUp((int)slotRawInt(a), (int)slotRawInt(b)));
661 break;
662 case opTrunc:
663 SetRaw(a, sc_trunc((int)slotRawInt(a), (int)slotRawInt(b)));
664 break;
665 case opAtan2:
666 SetFloat(a, atan2((double)slotRawInt(a), (double)slotRawInt(b)));
667 break;
668 case opHypot:
669 SetFloat(a, hypot((double)slotRawInt(a), (double)slotRawInt(b)));
670 break;
671 case opHypotx:
672 SetFloat(a, hypotx((double)slotRawInt(a), (double)slotRawInt(b)));
673 break;
674 case opPow:
675 SetFloat(a, pow((double)slotRawInt(a), (double)slotRawInt(b)));
676 break;
677 case opShiftLeft: {
678 long ia = slotRawInt(a);
679 long ib = slotRawInt(b);
680 if (ib > 0)
681 ia <<= ib;
682 else if (ib < 0)
683 ia >>= -ib;
684 SetRaw(a, ia);
685 } break;
686 case opShiftRight: {
687 long ia = slotRawInt(a);
688 long ib = slotRawInt(b);
689 if (ib > 0)
690 ia >>= ib;
691 else if (ib < 0)
692 ia <<= -ib;
693 SetRaw(a, ia);
694 } break;
695 case opUnsignedShift: {
696 unsigned long ia = slotRawInt(a);
697 long ib = slotRawInt(b);
698 if (ib > 0)
699 ia >>= ib;
700 else if (ib < 0)
701 ia <<= -ib;
702 SetRaw(a, (long)ia);
703 } break;
704 case opRing1:
705 SetRaw(a, sc_ring1(slotRawInt(a), slotRawInt(b)));
706 break;
707 case opRing2:
708 SetRaw(a, sc_ring2(slotRawInt(a), slotRawInt(b)));
709 break;
710 case opRing3:
711 SetRaw(a, sc_ring3(slotRawInt(a), slotRawInt(b)));
712 break;
713 case opRing4:
714 SetRaw(a, sc_ring4(slotRawInt(a), slotRawInt(b)));
715 break;
716 case opDifSqr:
717 SetRaw(a, sc_difsqr(slotRawInt(a), slotRawInt(b)));
718 break;
719 case opSumSqr:
720 SetRaw(a, sc_sumsqr(slotRawInt(a), slotRawInt(b)));
721 break;
722 case opSqrSum:
723 SetRaw(a, sc_sqrsum(slotRawInt(a), slotRawInt(b)));
724 break;
725 case opSqrDif:
726 SetRaw(a, sc_sqrdif(slotRawInt(a), slotRawInt(b)));
727 break;
728 case opAbsDif:
729 SetRaw(a, sc_abs(slotRawInt(a) - slotRawInt(b)));
730 break;
731 case opThresh:
732 SetRaw(a, sc_thresh(slotRawInt(a), slotRawInt(b)));
733 break;
734 case opAMClip:
735 SetRaw(a, sc_amclip(slotRawInt(a), slotRawInt(b)));
736 break;
737 case opScaleNeg:
738 SetRaw(a, sc_scaleneg(slotRawInt(a), slotRawInt(b)));
739 break;
740 case opClip2:
741 SetRaw(a, sc_clip2(slotRawInt(a), slotRawInt(b)));
742 break;
743 case opFold2:
744 SetRaw(a, sc_fold2(slotRawInt(a), slotRawInt(b)));
745 break;
746 case opWrap2:
747 SetRaw(a, sc_wrap2(slotRawInt(a), slotRawInt(b)));
748 break;
749 case opExcess:
750 SetRaw(a, sc_excess(slotRawInt(a), slotRawInt(b)));
751 break;
752 case opFirstArg:
753 SetRaw(a, slotRawInt(a));
754 break;
755 case opRandRange:
756 SetRaw(a,
757 slotRawInt(b) > slotRawInt(a)
758 ? slotRawInt(a) + g->rgen->irand(slotRawInt(b) - slotRawInt(a) + 1)
759 : slotRawInt(b) + g->rgen->irand(slotRawInt(a) - slotRawInt(b) + 1));
760 break;
761 case opExpRandRange:
762 SetFloat(a, g->rgen->exprandrng(slotRawInt(a), slotRawInt(b)));
763 break;
764 default:
765 goto send_normal_2;
766 }
767 break;
768 case tagChar:
769 case tagPtr:
770 case tagNil:
771 case tagFalse:
772 case tagTrue:
773 goto send_normal_2;
774 case tagSym:
775 if (IS_BINARY_BOOL_OP(opcode))
776 SetBool(a, opcode == opNE);
777 else
778 SetSymbol(a, slotRawSymbol(b));
779 break;
780 case tagObj:
781 if (isKindOf(slotRawObject(b), class_signal)) {
782 switch (opcode) {
783 case opAdd:
784 SetObject(a, signal_add_xf(g, slotRawObject(b), slotRawInt(a)));
785 break;
786 case opSub:
787 SetObject(a, signal_sub_fx(g, slotRawInt(a), slotRawObject(b)));
788 break;
789 case opMul:
790 SetObject(a, signal_mul_xf(g, slotRawObject(b), slotRawInt(a)));
791 break;
792 case opIDiv:
793 SetObject(a, signal_div_fx(g, slotRawInt(a), slotRawObject(b)));
794 break;
795 case opFDiv:
796 SetObject(a, signal_div_fx(g, slotRawInt(a), slotRawObject(b)));
797 break;
798 case opEQ:
799 SetFalse(a);
800 break;
801 case opNE:
802 SetTrue(a);
803 break;
804 case opMin:
805 SetObject(a, signal_min_xf(g, slotRawObject(b), slotRawInt(a)));
806 break;
807 case opMax:
808 SetObject(a, signal_max_xf(g, slotRawObject(b), slotRawInt(a)));
809 break;
810 case opRing1:
811 SetObject(a, signal_ring1_fx(g, slotRawInt(a), slotRawObject(b)));
812 break;
813 case opRing2:
814 SetObject(a, signal_ring2_fx(g, slotRawInt(a), slotRawObject(b)));
815 break;
816 case opRing3:
817 SetObject(a, signal_ring3_fx(g, slotRawInt(a), slotRawObject(b)));
818 break;
819 case opRing4:
820 SetObject(a, signal_ring4_fx(g, slotRawInt(a), slotRawObject(b)));
821 break;
822 case opDifSqr:
823 SetObject(a, signal_difsqr_fx(g, slotRawInt(a), slotRawObject(b)));
824 break;
825 case opSumSqr:
826 SetObject(a, signal_sumsqr_fx(g, slotRawInt(a), slotRawObject(b)));
827 break;
828 case opSqrSum:
829 SetObject(a, signal_sqrsum_fx(g, slotRawInt(a), slotRawObject(b)));
830 break;
831 case opSqrDif:
832 SetObject(a, signal_sqrdif_fx(g, slotRawInt(a), slotRawObject(b)));
833 break;
834 case opAbsDif:
835 SetObject(a, signal_absdif_fx(g, slotRawInt(a), slotRawObject(b)));
836 break;
837 case opThresh:
838 SetObject(a, signal_thresh_fx(g, slotRawInt(a), slotRawObject(b)));
839 break;
840 case opAMClip:
841 SetObject(a, signal_amclip_fx(g, slotRawInt(a), slotRawObject(b)));
842 break;
843 case opScaleNeg:
844 SetObject(a, signal_scaleneg_fx(g, slotRawInt(a), slotRawObject(b)));
845 break;
846 case opClip2:
847 SetObject(a, signal_clip2_fx(g, slotRawInt(a), slotRawObject(b)));
848 break;
849 case opFold2:
850 SetObject(a, signal_fold2_fx(g, slotRawInt(a), slotRawObject(b)));
851 break;
852 case opWrap2:
853 SetObject(a, signal_wrap2_fx(g, slotRawInt(a), slotRawObject(b)));
854 break;
855 case opExcess:
856 SetObject(a, signal_excess_fx(g, slotRawInt(a), slotRawObject(b)));
857 break;
858 case opFirstArg:
859 SetObject(a, slotRawObject(a));
860 break;
861 default:
862 goto send_normal_2;
863 }
864 } else {
865 goto send_normal_2;
866 }
867 break;
868 default:
869 switch (opcode) {
870 case opAdd:
871 SetFloat(a, slotRawInt(a) + slotRawFloat(b));
872 break;
873 case opSub:
874 SetFloat(a, slotRawInt(a) - slotRawFloat(b));
875 break;
876 case opMul:
877 SetFloat(a, slotRawInt(a) * slotRawFloat(b));
878 break;
879 case opIDiv:
880 SetRaw(a, (long)floor(slotRawInt(a) / slotRawFloat(b)));
881 break;
882 case opFDiv:
883 SetFloat(a, slotRawInt(a) / slotRawFloat(b));
884 break;
885 case opMod:
886 SetFloat(a, sc_mod((double)slotRawInt(a), slotRawFloat(b)));
887 break;
888 case opEQ:
889 SetBool(a, slotRawInt(a) == slotRawFloat(b));
890 break;
891 case opNE:
892 SetBool(a, slotRawInt(a) != slotRawFloat(b));
893 break;
894 case opLT:
895 SetBool(a, slotRawInt(a) < slotRawFloat(b));
896 break;
897 case opGT:
898 SetBool(a, slotRawInt(a) > slotRawFloat(b));
899 break;
900 case opLE:
901 SetBool(a, slotRawInt(a) <= slotRawFloat(b));
902 break;
903 case opGE:
904 SetBool(a, slotRawInt(a) >= slotRawFloat(b));
905 break;
906 // case opIdentical : SetFalse(a); break;
907 // case opNotIdentical : SetTrue(a); break;
908 case opMin:
909 SetFloat(a, sc_min((double)slotRawInt(a), slotRawFloat(b)));
910 break;
911 case opMax:
912 SetFloat(a, sc_max((double)slotRawInt(a), slotRawFloat(b)));
913 break;
914 case opRound:
915 SetFloat(a, sc_round((double)slotRawInt(a), slotRawFloat(b)));
916 break;
917 case opRoundUp:
918 SetFloat(a, sc_roundUp((double)slotRawInt(a), slotRawFloat(b)));
919 break;
920 case opTrunc:
921 SetFloat(a, sc_trunc((double)slotRawInt(a), slotRawFloat(b)));
922 break;
923 case opAtan2:
924 SetFloat(a, atan2(slotRawInt(a), slotRawFloat(b)));
925 break;
926 case opHypot:
927 SetFloat(a, hypot(slotRawInt(a), slotRawFloat(b)));
928 break;
929 case opHypotx:
930 SetFloat(a, hypotx(slotRawInt(a), slotRawFloat(b)));
931 break;
932 case opPow:
933 SetFloat(a, pow((double)slotRawInt(a), slotRawFloat(b)));
934 break;
935 case opRing1:
936 SetFloat(a, sc_ring1((double)slotRawInt(a), slotRawFloat(b)));
937 break;
938 case opRing2:
939 SetFloat(a, sc_ring2((double)slotRawInt(a), slotRawFloat(b)));
940 break;
941 case opRing3:
942 SetFloat(a, sc_ring3((double)slotRawInt(a), slotRawFloat(b)));
943 break;
944 case opRing4:
945 SetFloat(a, sc_ring4((double)slotRawInt(a), slotRawFloat(b)));
946 break;
947 case opDifSqr:
948 SetFloat(a, sc_difsqr((double)slotRawInt(a), slotRawFloat(b)));
949 break;
950 case opSumSqr:
951 SetFloat(a, sc_sumsqr((double)slotRawInt(a), slotRawFloat(b)));
952 break;
953 case opSqrSum:
954 SetFloat(a, sc_sqrsum((double)slotRawInt(a), slotRawFloat(b)));
955 break;
956 case opSqrDif:
957 SetFloat(a, sc_sqrdif((double)slotRawInt(a), slotRawFloat(b)));
958 break;
959 case opAbsDif:
960 SetFloat(a, sc_abs(slotRawInt(a) - slotRawFloat(b)));
961 break;
962 case opThresh:
963 SetRaw(a, sc_thresh(slotRawInt(a), slotRawFloat(b)));
964 break;
965 case opAMClip:
966 SetFloat(a, sc_amclip((double)slotRawInt(a), slotRawFloat(b)));
967 break;
968 case opScaleNeg:
969 SetFloat(a, sc_scaleneg((double)slotRawInt(a), slotRawFloat(b)));
970 break;
971 case opClip2:
972 SetFloat(a, sc_clip2((double)slotRawInt(a), slotRawFloat(b)));
973 break;
974 case opFold2:
975 SetFloat(a, sc_fold2((double)slotRawInt(a), slotRawFloat(b)));
976 break;
977 case opWrap2:
978 SetFloat(a, sc_wrap2((double)slotRawInt(a), -slotRawFloat(b)));
979 break;
980 case opExcess:
981 SetFloat(a, sc_excess((double)slotRawInt(a), slotRawFloat(b)));
982 break;
983 case opFirstArg:
984 SetInt(a, slotRawInt(a));
985 break;
986 case opRandRange:
987 SetFloat(a, slotRawInt(a) + g->rgen->frand() * (slotRawFloat(b) - slotRawInt(a)));
988 break;
989 case opExpRandRange:
990 SetFloat(a, g->rgen->exprandrng(slotRawInt(a), slotRawFloat(b)));
991 break;
992 default:
993 goto send_normal_2;
994 }
995 break;
996 }
997 } break;
998 case tagChar: {
999 if (IsChar(b)) {
1000 switch (opcode) {
1001 case opEQ:
1002 SetBool(a, slotRawChar(a) == slotRawChar(b));
1003 break;
1004 case opNE:
1005 SetBool(a, slotRawChar(a) != slotRawChar(b));
1006 break;
1007 case opLT:
1008 SetBool(a, slotRawChar(a) < slotRawChar(b));
1009 break;
1010 case opGT:
1011 SetBool(a, slotRawChar(a) > slotRawChar(b));
1012 break;
1013 case opLE:
1014 SetBool(a, slotRawChar(a) <= slotRawChar(b));
1015 break;
1016 case opGE:
1017 SetBool(a, slotRawChar(a) >= slotRawChar(b));
1018 break;
1019 // case opIdentical : SetBool(a, slotRawChar(a) == slotRawChar(b)); break;
1020 // case opNotIdentical : SetBool(a, slotRawChar(a) != slotRawChar(b)); break;
1021 case opMin:
1022 SetRawChar(a, sc_min(slotRawChar(a), slotRawChar(b)));
1023 break;
1024 case opMax:
1025 SetRawChar(a, sc_max(slotRawChar(a), slotRawChar(b)));
1026 break;
1027 default:
1028 goto send_normal_2;
1029 }
1030 } else {
1031 goto send_normal_2;
1032 }
1033 } break;
1034 case tagPtr:
1035 case tagNil:
1036 case tagFalse:
1037 case tagTrue:
1038 goto send_normal_2;
1039 case tagSym:
1040 if (IsSym(b)) {
1041 switch (opcode) {
1042 case opEQ:
1043 SetBool(a, slotRawSymbol(a) == slotRawSymbol(b));
1044 break;
1045 case opNE:
1046 SetBool(a, slotRawSymbol(a) != slotRawSymbol(b));
1047 break;
1048 case opLT:
1049 SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) < 0);
1050 break;
1051 case opGT:
1052 SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) > 0);
1053 break;
1054 case opLE:
1055 SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) <= 0);
1056 break;
1057 case opGE:
1058 SetBool(a, strcmp(slotRawSymbol(a)->name, slotRawSymbol(b)->name) >= 0);
1059 break;
1060 // default : leave first operand on stack
1061 }
1062 } else {
1063 if (IS_BINARY_BOOL_OP(opcode))
1064 SetBool(a, opcode == opNE);
1065 }
1066 break;
1067 case tagObj: {
1068 if (isKindOf(slotRawObject(a), class_signal)) {
1069 switch (GetTag(b)) {
1070 case tagInt:
1071 switch (opcode) {
1072 case opAdd:
1073 SetRaw(a, signal_add_xf(g, slotRawObject(a), slotRawInt(b)));
1074 break;
1075 case opSub:
1076 SetRaw(a, signal_sub_xf(g, slotRawObject(a), slotRawInt(b)));
1077 break;
1078 case opMul:
1079 SetRaw(a, signal_mul_xf(g, slotRawObject(a), slotRawInt(b)));
1080 break;
1081 case opIDiv:
1082 SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawInt(b)));
1083 break;
1084 case opFDiv:
1085 SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawInt(b)));
1086 break;
1087 case opEQ:
1088 SetFalse(a);
1089 break;
1090 case opNE:
1091 SetTrue(a);
1092 break;
1093 case opMin:
1094 SetRaw(a, signal_min_xf(g, slotRawObject(a), slotRawInt(b)));
1095 break;
1096 case opMax:
1097 SetRaw(a, signal_max_xf(g, slotRawObject(a), slotRawInt(b)));
1098 break;
1099 case opFill:
1100 SetRaw(a, signal_fill(slotRawObject(a), slotRawInt(b)));
1101 break;
1102 case opRing1:
1103 SetRaw(a, signal_ring1_xf(g, slotRawObject(a), slotRawInt(b)));
1104 break;
1105 case opRing2:
1106 SetRaw(a, signal_ring2_xf(g, slotRawObject(a), slotRawInt(b)));
1107 break;
1108 case opRing3:
1109 SetRaw(a, signal_ring3_xf(g, slotRawObject(a), slotRawInt(b)));
1110 break;
1111 case opRing4:
1112 SetRaw(a, signal_ring4_xf(g, slotRawObject(a), slotRawInt(b)));
1113 break;
1114 case opDifSqr:
1115 SetRaw(a, signal_difsqr_xf(g, slotRawObject(a), slotRawInt(b)));
1116 break;
1117 case opSumSqr:
1118 SetRaw(a, signal_sumsqr_xf(g, slotRawObject(a), slotRawInt(b)));
1119 break;
1120 case opSqrSum:
1121 SetRaw(a, signal_sqrsum_xf(g, slotRawObject(a), slotRawInt(b)));
1122 break;
1123 case opSqrDif:
1124 SetRaw(a, signal_sqrdif_xf(g, slotRawObject(a), slotRawInt(b)));
1125 break;
1126 case opAbsDif:
1127 SetRaw(a, signal_absdif_xf(g, slotRawObject(a), slotRawInt(b)));
1128 break;
1129 case opThresh:
1130 SetRaw(a, signal_thresh_xf(g, slotRawObject(a), slotRawInt(b)));
1131 break;
1132 case opAMClip:
1133 SetRaw(a, signal_amclip_xf(g, slotRawObject(a), slotRawInt(b)));
1134 break;
1135 case opScaleNeg:
1136 SetRaw(a, signal_scaleneg_xf(g, slotRawObject(a), slotRawInt(b)));
1137 break;
1138 case opClip2:
1139 SetRaw(a, signal_clip2_xf(g, slotRawObject(a), slotRawInt(b)));
1140 break;
1141 case opFold2:
1142 SetRaw(a, signal_fold2_xf(g, slotRawObject(a), slotRawInt(b)));
1143 break;
1144 case opWrap2:
1145 SetRaw(a, signal_wrap2_xf(g, slotRawObject(a), slotRawInt(b)));
1146 break;
1147 case opExcess:
1148 SetRaw(a, signal_excess_xf(g, slotRawObject(a), slotRawInt(b)));
1149 break;
1150 case opFirstArg:
1151 SetRaw(a, slotRawObject(a));
1152 break;
1153 default:
1154 goto send_normal_2;
1155 }
1156 break;
1157 case tagChar:
1158 case tagPtr:
1159 case tagNil:
1160 case tagFalse:
1161 case tagTrue:
1162 goto send_normal_2;
1163 case tagSym:
1164 if (IS_BINARY_BOOL_OP(opcode))
1165 SetBool(a, opcode == opNE);
1166 else
1167 SetSymbol(a, slotRawSymbol(b));
1168 break;
1169 case tagObj:
1170 if (isKindOf(slotRawObject(b), class_signal)) {
1171 switch (opcode) {
1172 case opAdd:
1173 SetRaw(a, signal_add_xx(g, slotRawObject(a), slotRawObject(b)));
1174 break;
1175 case opSub:
1176 SetRaw(a, signal_sub_xx(g, slotRawObject(a), slotRawObject(b)));
1177 break;
1178 case opMul:
1179 SetRaw(a, signal_mul_xx(g, slotRawObject(a), slotRawObject(b)));
1180 break;
1181 case opIDiv:
1182 SetRaw(a, signal_div_xx(g, slotRawObject(a), slotRawObject(b)));
1183 break;
1184 case opFDiv:
1185 SetRaw(a, signal_div_xx(g, slotRawObject(a), slotRawObject(b)));
1186 break;
1187 case opEQ:
1188 SetBool(a, signal_equal_xx(g, slotRawObject(a), slotRawObject(b)));
1189 break;
1190 case opNE:
1191 SetBool(a, !signal_equal_xx(g, slotRawObject(a), slotRawObject(b)));
1192 break;
1193 case opMin:
1194 SetRaw(a, signal_min_xx(g, slotRawObject(a), slotRawObject(b)));
1195 break;
1196 case opMax:
1197 SetRaw(a, signal_max_xx(g, slotRawObject(a), slotRawObject(b)));
1198 break;
1199 case opRing1:
1200 SetRaw(a, signal_ring1_xx(g, slotRawObject(a), slotRawObject(b)));
1201 break;
1202 case opRing2:
1203 SetRaw(a, signal_ring2_xx(g, slotRawObject(a), slotRawObject(b)));
1204 break;
1205 case opRing3:
1206 SetRaw(a, signal_ring3_xx(g, slotRawObject(a), slotRawObject(b)));
1207 break;
1208 case opRing4:
1209 SetRaw(a, signal_ring4_xx(g, slotRawObject(a), slotRawObject(b)));
1210 break;
1211 case opDifSqr:
1212 SetRaw(a, signal_difsqr_xx(g, slotRawObject(a), slotRawObject(b)));
1213 break;
1214 case opSumSqr:
1215 SetRaw(a, signal_sumsqr_xx(g, slotRawObject(a), slotRawObject(b)));
1216 break;
1217 case opSqrSum:
1218 SetRaw(a, signal_sqrsum_xx(g, slotRawObject(a), slotRawObject(b)));
1219 break;
1220 case opSqrDif:
1221 SetRaw(a, signal_sqrdif_xx(g, slotRawObject(a), slotRawObject(b)));
1222 break;
1223 case opAbsDif:
1224 SetRaw(a, signal_absdif_xx(g, slotRawObject(a), slotRawObject(b)));
1225 break;
1226 case opThresh:
1227 SetRaw(a, signal_thresh_xx(g, slotRawObject(a), slotRawObject(b)));
1228 break;
1229 case opAMClip:
1230 SetRaw(a, signal_amclip_xx(g, slotRawObject(a), slotRawObject(b)));
1231 break;
1232 case opScaleNeg:
1233 SetRaw(a, signal_scaleneg_xx(g, slotRawObject(a), slotRawObject(b)));
1234 break;
1235 case opClip2:
1236 SetRaw(a, signal_clip2_xx(g, slotRawObject(a), slotRawObject(b)));
1237 break;
1238 case opFold2:
1239 SetRaw(a, signal_fold2_xx(g, slotRawObject(a), slotRawObject(b)));
1240 break;
1241 case opWrap2:
1242 SetRaw(a, signal_wrap2_xx(g, slotRawObject(a), slotRawObject(b)));
1243 break;
1244 case opExcess:
1245 SetRaw(a, signal_excess_xx(g, slotRawObject(a), slotRawObject(b)));
1246 break;
1247 case opFirstArg:
1248 SetRaw(a, slotRawObject(a));
1249 break;
1250 default:
1251 goto send_normal_2;
1252 }
1253 } else
1254 goto send_normal_2;
1255 break;
1256 default: // double
1257 switch (opcode) {
1258 case opAdd:
1259 SetRaw(a, signal_add_xf(g, slotRawObject(a), slotRawFloat(b)));
1260 break;
1261 case opSub:
1262 SetRaw(a, signal_sub_xf(g, slotRawObject(a), slotRawFloat(b)));
1263 break;
1264 case opMul:
1265 SetRaw(a, signal_mul_xf(g, slotRawObject(a), slotRawFloat(b)));
1266 break;
1267 case opIDiv:
1268 SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawFloat(b)));
1269 break;
1270 case opFDiv:
1271 SetRaw(a, signal_div_xf(g, slotRawObject(a), slotRawFloat(b)));
1272 break;
1273 case opEQ:
1274 SetFalse(a);
1275 break;
1276 case opNE:
1277 SetTrue(a);
1278 break;
1279 case opMin:
1280 SetRaw(a, signal_min_xf(g, slotRawObject(a), slotRawFloat(b)));
1281 break;
1282 case opMax:
1283 SetRaw(a, signal_max_xf(g, slotRawObject(a), slotRawFloat(b)));
1284 break;
1285 case opFill:
1286 SetRaw(a, signal_fill(slotRawObject(a), slotRawFloat(b)));
1287 break;
1288 case opRing1:
1289 SetRaw(a, signal_ring1_xf(g, slotRawObject(a), slotRawFloat(b)));
1290 break;
1291 case opRing2:
1292 SetRaw(a, signal_ring2_xf(g, slotRawObject(a), slotRawFloat(b)));
1293 break;
1294 case opRing3:
1295 SetRaw(a, signal_ring3_xf(g, slotRawObject(a), slotRawFloat(b)));
1296 break;
1297 case opRing4:
1298 SetRaw(a, signal_ring4_xf(g, slotRawObject(a), slotRawFloat(b)));
1299 break;
1300 case opDifSqr:
1301 SetRaw(a, signal_difsqr_xf(g, slotRawObject(a), slotRawFloat(b)));
1302 break;
1303 case opSumSqr:
1304 SetRaw(a, signal_sumsqr_xf(g, slotRawObject(a), slotRawFloat(b)));
1305 break;
1306 case opSqrSum:
1307 SetRaw(a, signal_sqrsum_xf(g, slotRawObject(a), slotRawFloat(b)));
1308 break;
1309 case opSqrDif:
1310 SetRaw(a, signal_sqrdif_xf(g, slotRawObject(a), slotRawFloat(b)));
1311 break;
1312 case opAbsDif:
1313 SetRaw(a, signal_absdif_xf(g, slotRawObject(a), slotRawFloat(b)));
1314 break;
1315 case opThresh:
1316 SetRaw(a, signal_thresh_xf(g, slotRawObject(a), slotRawFloat(b)));
1317 break;
1318 case opAMClip:
1319 SetRaw(a, signal_amclip_xf(g, slotRawObject(a), slotRawFloat(b)));
1320 break;
1321 case opScaleNeg:
1322 SetRaw(a, signal_scaleneg_xf(g, slotRawObject(a), slotRawFloat(b)));
1323 break;
1324 case opClip2:
1325 SetRaw(a, signal_clip2_xf(g, slotRawObject(a), slotRawFloat(b)));
1326 break;
1327 case opFold2:
1328 SetRaw(a, signal_fold2_xf(g, slotRawObject(a), slotRawFloat(b)));
1329 break;
1330 case opWrap2:
1331 SetRaw(a, signal_wrap2_xf(g, slotRawObject(a), slotRawFloat(b)));
1332 break;
1333 case opExcess:
1334 SetRaw(a, signal_excess_xf(g, slotRawObject(a), slotRawFloat(b)));
1335 break;
1336 case opFirstArg:
1337 SetRaw(a, slotRawObject(a));
1338 break;
1339 default:
1340 goto send_normal_2;
1341 }
1342 break;
1343 }
1344 } else {
1345 goto send_normal_2;
1346 }
1347 } break;
1348 default: { // double
1349 switch (GetTag(b)) {
1350 case tagInt:
1351 switch (opcode) {
1352 case opAdd:
1353 SetRaw(a, slotRawFloat(a) + slotRawInt(b));
1354 break;
1355 case opSub:
1356 SetRaw(a, slotRawFloat(a) - slotRawInt(b));
1357 break;
1358 case opMul:
1359 SetRaw(a, slotRawFloat(a) * slotRawInt(b));
1360 break;
1361 case opIDiv:
1362 SetInt(a, (long)floor(slotRawFloat(a) / slotRawInt(b)));
1363 break;
1364 case opFDiv:
1365 SetRaw(a, slotRawFloat(a) / slotRawInt(b));
1366 break;
1367 case opMod:
1368 SetRaw(a, sc_mod(slotRawFloat(a), (double)slotRawInt(b)));
1369 break;
1370 case opEQ:
1371 SetBool(a, slotRawFloat(a) == slotRawInt(b));
1372 break;
1373 case opNE:
1374 SetBool(a, slotRawFloat(a) != slotRawInt(b));
1375 break;
1376 case opLT:
1377 SetBool(a, slotRawFloat(a) < slotRawInt(b));
1378 break;
1379 case opGT:
1380 SetBool(a, slotRawFloat(a) > slotRawInt(b));
1381 break;
1382 case opLE:
1383 SetBool(a, slotRawFloat(a) <= slotRawInt(b));
1384 break;
1385 case opGE:
1386 SetBool(a, slotRawFloat(a) >= slotRawInt(b));
1387 break;
1388 // case opIdentical : SetFalse(a); break;
1389 // case opNotIdentical : SetTrue(a); break;
1390 case opMin:
1391 SetRaw(a, sc_min(slotRawFloat(a), (double)slotRawInt(b)));
1392 break;
1393 case opMax:
1394 SetRaw(a, sc_max(slotRawFloat(a), (double)slotRawInt(b)));
1395 break;
1396 case opRound:
1397 SetRaw(a, sc_round(slotRawFloat(a), (double)slotRawInt(b)));
1398 break;
1399 case opRoundUp:
1400 SetRaw(a, sc_roundUp(slotRawFloat(a), (double)slotRawInt(b)));
1401 break;
1402 case opTrunc:
1403 SetRaw(a, sc_trunc(slotRawFloat(a), (double)slotRawInt(b)));
1404 break;
1405 case opAtan2:
1406 SetRaw(a, atan2(slotRawFloat(a), slotRawInt(b)));
1407 break;
1408 case opHypot:
1409 SetRaw(a, hypot(slotRawFloat(a), slotRawInt(b)));
1410 break;
1411 case opHypotx:
1412 SetRaw(a, hypotx(slotRawFloat(a), slotRawInt(b)));
1413 break;
1414 case opPow:
1415 SetRaw(a, pow(slotRawFloat(a), (double)slotRawInt(b)));
1416 break;
1417 case opRing1:
1418 SetRaw(a, sc_ring1(slotRawFloat(a), (double)slotRawInt(b)));
1419 break;
1420 case opRing2:
1421 SetRaw(a, sc_ring2(slotRawFloat(a), (double)slotRawInt(b)));
1422 break;
1423 case opRing3:
1424 SetRaw(a, sc_ring3(slotRawFloat(a), (double)slotRawInt(b)));
1425 break;
1426 case opRing4:
1427 SetRaw(a, sc_ring4(slotRawFloat(a), (double)slotRawInt(b)));
1428 break;
1429 case opDifSqr:
1430 SetRaw(a, sc_difsqr(slotRawFloat(a), (double)slotRawInt(b)));
1431 break;
1432 case opSumSqr:
1433 SetRaw(a, sc_sumsqr(slotRawFloat(a), (double)slotRawInt(b)));
1434 break;
1435 case opSqrSum:
1436 SetRaw(a, sc_sqrsum(slotRawFloat(a), (double)slotRawInt(b)));
1437 break;
1438 case opSqrDif:
1439 SetRaw(a, sc_sqrdif(slotRawFloat(a), (double)slotRawInt(b)));
1440 break;
1441 case opAbsDif:
1442 SetRaw(a, sc_abs(slotRawFloat(a) - slotRawInt(b)));
1443 break;
1444 case opThresh:
1445 SetRaw(a, sc_thresh(slotRawFloat(a), slotRawInt(b)));
1446 break;
1447 case opAMClip:
1448 SetRaw(a, sc_amclip(slotRawFloat(a), (double)slotRawInt(b)));
1449 break;
1450 case opScaleNeg:
1451 SetRaw(a, sc_scaleneg(slotRawFloat(a), (double)slotRawInt(b)));
1452 break;
1453 case opClip2:
1454 SetRaw(a, sc_clip2(slotRawFloat(a), (double)slotRawInt(b)));
1455 break;
1456 case opFold2:
1457 SetRaw(a, sc_fold2(slotRawFloat(a), (double)slotRawInt(b)));
1458 break;
1459 case opWrap2:
1460 SetRaw(a, sc_wrap2(slotRawFloat(a), (double)slotRawInt(b)));
1461 break;
1462 case opExcess:
1463 SetRaw(a, sc_excess(slotRawFloat(a), (double)slotRawInt(b)));
1464 break;
1465 case opFirstArg:
1466 SetRaw(a, slotRawFloat(a));
1467 break;
1468 case opRandRange:
1469 SetRaw(a, slotRawFloat(a) + g->rgen->frand() * (slotRawInt(b) - slotRawFloat(a)));
1470 break;
1471 case opExpRandRange:
1472 SetRaw(a, g->rgen->exprandrng(slotRawFloat(a), slotRawInt(b)));
1473 break;
1474 default:
1475 goto send_normal_2;
1476 }
1477 break;
1478 case tagChar:
1479 case tagPtr:
1480 case tagNil:
1481 case tagFalse:
1482 case tagTrue:
1483 goto send_normal_2;
1484 case tagSym:
1485 if (IS_BINARY_BOOL_OP(opcode))
1486 SetBool(a, opcode == opNE);
1487 else
1488 SetSymbol(a, slotRawSymbol(b));
1489 break;
1490 case tagObj:
1491 if (isKindOf(slotRawObject(b), class_signal)) {
1492 switch (opcode) {
1493 case opAdd:
1494 SetObject(a, signal_add_xf(g, slotRawObject(b), slotRawFloat(a)));
1495 break;
1496 case opSub:
1497 SetObject(a, signal_sub_fx(g, slotRawFloat(a), slotRawObject(b)));
1498 break;
1499 case opMul:
1500 SetObject(a, signal_mul_xf(g, slotRawObject(b), slotRawFloat(a)));
1501 break;
1502 case opIDiv:
1503 SetObject(a, signal_div_fx(g, slotRawFloat(a), slotRawObject(b)));
1504 break;
1505 case opFDiv:
1506 SetObject(a, signal_div_fx(g, slotRawFloat(a), slotRawObject(b)));
1507 break;
1508 case opEQ:
1509 SetFalse(a);
1510 break;
1511 case opNE:
1512 SetTrue(a);
1513 break;
1514 case opMin:
1515 SetObject(a, signal_min_xf(g, slotRawObject(b), slotRawFloat(a)));
1516 break;
1517 case opMax:
1518 SetObject(a, signal_max_xf(g, slotRawObject(b), slotRawFloat(a)));
1519 break;
1520 case opRing1:
1521 SetObject(a, signal_ring1_fx(g, slotRawFloat(a), slotRawObject(b)));
1522 break;
1523 case opRing2:
1524 SetObject(a, signal_ring2_fx(g, slotRawFloat(a), slotRawObject(b)));
1525 break;
1526 case opRing3:
1527 SetObject(a, signal_ring3_fx(g, slotRawFloat(a), slotRawObject(b)));
1528 break;
1529 case opRing4:
1530 SetObject(a, signal_ring4_fx(g, slotRawFloat(a), slotRawObject(b)));
1531 break;
1532 case opDifSqr:
1533 SetObject(a, signal_difsqr_fx(g, slotRawFloat(a), slotRawObject(b)));
1534 break;
1535 case opSumSqr:
1536 SetObject(a, signal_sumsqr_fx(g, slotRawFloat(a), slotRawObject(b)));
1537 break;
1538 case opSqrSum:
1539 SetObject(a, signal_sqrsum_fx(g, slotRawFloat(a), slotRawObject(b)));
1540 break;
1541 case opSqrDif:
1542 SetObject(a, signal_sqrdif_fx(g, slotRawFloat(a), slotRawObject(b)));
1543 break;
1544 case opAbsDif:
1545 SetObject(a, signal_absdif_fx(g, slotRawFloat(a), slotRawObject(b)));
1546 break;
1547 case opThresh:
1548 SetObject(a, signal_thresh_fx(g, slotRawFloat(a), slotRawObject(b)));
1549 break;
1550 case opAMClip:
1551 SetObject(a, signal_amclip_fx(g, slotRawFloat(a), slotRawObject(b)));
1552 break;
1553 case opScaleNeg:
1554 SetObject(a, signal_scaleneg_fx(g, slotRawFloat(a), slotRawObject(b)));
1555 break;
1556 case opClip2:
1557 SetObject(a, signal_clip2_fx(g, slotRawFloat(a), slotRawObject(b)));
1558 break;
1559 case opFold2:
1560 SetObject(a, signal_fold2_fx(g, slotRawFloat(a), slotRawObject(b)));
1561 break;
1562 case opWrap2:
1563 SetObject(a, signal_wrap2_fx(g, slotRawFloat(a), slotRawObject(b)));
1564 break;
1565 case opExcess:
1566 SetObject(a, signal_excess_fx(g, slotRawFloat(a), slotRawObject(b)));
1567 break;
1568 case opFirstArg:
1569 SetObject(a, slotRawObject(a));
1570 break;
1571 default:
1572 goto send_normal_2;
1573 }
1574 } else
1575 goto send_normal_2;
1576 break;
1577 default: // double
1578 switch (opcode) {
1579 case opAdd:
1580 SetRaw(a, slotRawFloat(a) + slotRawFloat(b));
1581 break;
1582 case opSub:
1583 SetRaw(a, slotRawFloat(a) - slotRawFloat(b));
1584 break;
1585 case opMul:
1586 SetRaw(a, slotRawFloat(a) * slotRawFloat(b));
1587 break;
1588 case opIDiv:
1589 SetInt(a, (long)floor(slotRawFloat(a) / slotRawFloat(b)));
1590 break;
1591 case opFDiv:
1592 SetRaw(a, slotRawFloat(a) / slotRawFloat(b));
1593 break;
1594 case opMod:
1595 SetRaw(a, sc_mod(slotRawFloat(a), slotRawFloat(b)));
1596 break;
1597 case opEQ:
1598 SetBool(a, slotRawFloat(a) == slotRawFloat(b));
1599 break;
1600 case opNE:
1601 SetBool(a, slotRawFloat(a) != slotRawFloat(b));
1602 break;
1603 case opLT:
1604 SetBool(a, slotRawFloat(a) < slotRawFloat(b));
1605 break;
1606 case opGT:
1607 SetBool(a, slotRawFloat(a) > slotRawFloat(b));
1608 break;
1609 case opLE:
1610 SetBool(a, slotRawFloat(a) <= slotRawFloat(b));
1611 break;
1612 case opGE:
1613 SetBool(a, slotRawFloat(a) >= slotRawFloat(b));
1614 break;
1615 // case opIdentical : SetBool(a, slotRawFloat(a) == slotRawFloat(b)); break;
1616 // case opNotIdentical : SetBool(a, slotRawFloat(a) != slotRawFloat(b)); break;
1617 case opMin:
1618 SetRaw(a, sc_min(slotRawFloat(a), slotRawFloat(b)));
1619 break;
1620 case opMax:
1621 SetRaw(a, sc_max(slotRawFloat(a), slotRawFloat(b)));
1622 break;
1623 case opRound:
1624 SetRaw(a, sc_round(slotRawFloat(a), slotRawFloat(b)));
1625 break;
1626 case opRoundUp:
1627 SetRaw(a, sc_roundUp(slotRawFloat(a), slotRawFloat(b)));
1628 break;
1629 case opTrunc:
1630 SetRaw(a, sc_trunc(slotRawFloat(a), slotRawFloat(b)));
1631 break;
1632 case opAtan2:
1633 SetRaw(a, atan2(slotRawFloat(a), slotRawFloat(b)));
1634 break;
1635 case opHypot:
1636 SetRaw(a, hypot(slotRawFloat(a), slotRawFloat(b)));
1637 break;
1638 case opHypotx:
1639 SetRaw(a, hypotx(slotRawFloat(a), slotRawFloat(b)));
1640 break;
1641 case opPow:
1642 SetRaw(a, pow(slotRawFloat(a), slotRawFloat(b)));
1643 break;
1644 case opRing1:
1645 SetRaw(a, sc_ring1(slotRawFloat(a), slotRawFloat(b)));
1646 break;
1647 case opRing2:
1648 SetRaw(a, sc_ring2(slotRawFloat(a), slotRawFloat(b)));
1649 break;
1650 case opRing3:
1651 SetRaw(a, sc_ring3(slotRawFloat(a), slotRawFloat(b)));
1652 break;
1653 case opRing4:
1654 SetRaw(a, sc_ring4(slotRawFloat(a), slotRawFloat(b)));
1655 break;
1656 case opDifSqr:
1657 SetRaw(a, sc_difsqr(slotRawFloat(a), slotRawFloat(b)));
1658 break;
1659 case opSumSqr:
1660 SetRaw(a, sc_sumsqr(slotRawFloat(a), slotRawFloat(b)));
1661 break;
1662 case opSqrSum:
1663 SetRaw(a, sc_sqrsum(slotRawFloat(a), slotRawFloat(b)));
1664 break;
1665 case opSqrDif:
1666 SetRaw(a, sc_sqrdif(slotRawFloat(a), slotRawFloat(b)));
1667 break;
1668 case opAbsDif:
1669 SetRaw(a, sc_abs(slotRawFloat(a) - slotRawFloat(b)));
1670 break;
1671 case opThresh:
1672 SetRaw(a, sc_thresh(slotRawFloat(a), slotRawFloat(b)));
1673 break;
1674 case opAMClip:
1675 SetRaw(a, sc_amclip(slotRawFloat(a), slotRawFloat(b)));
1676 break;
1677 case opScaleNeg:
1678 SetRaw(a, sc_scaleneg(slotRawFloat(a), slotRawFloat(b)));
1679 break;
1680 case opClip2:
1681 SetRaw(a, sc_clip2(slotRawFloat(a), slotRawFloat(b)));
1682 break;
1683 case opFold2:
1684 SetRaw(a, sc_fold2(slotRawFloat(a), slotRawFloat(b)));
1685 break;
1686 case opWrap2:
1687 SetRaw(a, sc_wrap2(slotRawFloat(a), slotRawFloat(b)));
1688 break;
1689 case opExcess:
1690 SetRaw(a, sc_excess(slotRawFloat(a), slotRawFloat(b)));
1691 break;
1692 case opFirstArg:
1693 SetRaw(a, slotRawFloat(a));
1694 break;
1695 case opRandRange:
1696 SetRaw(a, slotRawFloat(a) + g->rgen->frand() * (slotRawFloat(b) - slotRawFloat(a)));
1697 break;
1698 case opExpRandRange:
1699 SetRaw(a, g->rgen->exprandrng(slotRawFloat(a), slotRawFloat(b)));
1700 break;
1701 default:
1702 goto send_normal_2;
1703 }
1704 break;
1705 }
1706 } break;
1707 }
1708 g->sp = a; // drop
1709 g->numpop = 0;
1710 #if TAILCALLOPTIMIZE
1711 g->tailCall = 0;
1712 #endif
1713 return errNone;
1714
1715 send_normal_2:
1716 if (isPrimitive) // special case flag meaning it is a primitive
1717 return errFailed; // arguments remain on the stack
1718
1719 msg = gSpecialBinarySelectors[opcode];
1720 sendMessage(g, msg, numArgsPushed);
1721 return errNone;
1722 }
1723