Enable HAVE_AVFOUNDATION_VIDEO_OUTPUT on PLATFORM(IOSMAC)
[WebKit-https.git] / PerformanceTests / testmem / air.js
1 /*
2  * Copyright (C) 2016-2018 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25 "use strict";
26
27 // This file is for misc symbols.
28
29 // B3 types
30 const Void = Symbol("Void");
31 const Int32 = Symbol("Int32");
32 const Int64 = Symbol("Int64");
33 const Float = Symbol("Float");
34 const Double = Symbol("Double");
35
36 // Arg type
37 const GP = Symbol("GP");
38 const FP = Symbol("FP");
39
40 // Stack slot kind
41 const Locked = Symbol("Locked");
42 const Spill = Symbol("Spill");
43
44 // Frequency class
45 const Normal = Symbol("Normal");
46 const Rare = Symbol("Rare");
47
48 // Relational conditions
49 const Equal = Symbol("Equal");
50 const NotEqual = Symbol("NotEqual");
51 const Above = Symbol("Above");
52 const AboveOrEqual = Symbol("AboveOrEqual");
53 const Below = Symbol("Below");
54 const BelowOrEqual = Symbol("BelowOrEqual");
55 const GreaterThan = Symbol("GreaterThan");
56 const GreaterThanOrEqual = Symbol("GreaterThanOrEqual");
57 const LessThan = Symbol("LessThan");
58 const LessThanOrEqual = Symbol("LessThanOrEqual");
59
60 function relCondCode(cond)
61 {
62     switch (cond) {
63     case Equal:
64         return 4;
65     case NotEqual:
66         return 5;
67     case Above:
68         return 7;
69     case AboveOrEqual:
70         return 3;
71     case Below:
72         return 2;
73     case BelowOrEqual:
74         return 6;
75     case GreaterThan:
76         return 15;
77     case GreaterThanOrEqual:
78         return 13;
79     case LessThan:
80         return 12;
81     case LessThanOrEqual:
82         return 14;
83     default:
84         throw new Error("Bad rel cond");
85     }
86 }
87
88 // Result conditions
89 const Overflow = Symbol("Overflow");
90 const Signed = Symbol("Signed");
91 const PositiveOrZero = Symbol("PositiveOrZero");
92 const Zero = Symbol("Zero");
93 const NonZero = Symbol("NonZero");
94
95 function resCondCode(cond)
96 {
97     switch (cond) {
98     case Overflow:
99         return 0;
100     case Signed:
101         return 8;
102     case PositiveOrZero:
103         return 9;
104     case Zero:
105         return 4;
106     case NonZero:
107         return 5;
108     default:
109         throw new Error("Bad res cond: " + cond.toString());
110     }
111 }
112
113 // Double conditions
114 const DoubleEqual = Symbol("DoubleEqual");
115 const DoubleNotEqual = Symbol("DoubleNotEqual");
116 const DoubleGreaterThan = Symbol("DoubleGreaterThan");
117 const DoubleGreaterThanOrEqual = Symbol("DoubleGreaterThanOrEqual");
118 const DoubleLessThan = Symbol("DoubleLessThan");
119 const DoubleLessThanOrEqual = Symbol("DoubleLessThanOrEqual");
120 const DoubleEqualOrUnordered = Symbol("DoubleEqualOrUnordered");
121 const DoubleNotEqualOrUnordered = Symbol("DoubleNotEqualOrUnordered");
122 const DoubleGreaterThanOrUnordered = Symbol("DoubleGreaterThanOrUnordered");
123 const DoubleGreaterThanOrEqualOrUnordered = Symbol("DoubleGreaterThanOrEqualOrUnordered");
124 const DoubleLessThanOrUnordered = Symbol("DoubleLessThanOrUnordered");
125 const DoubleLessThanOrEqualOrUnordered = Symbol("DoubleLessThanOrEqualOrUnordered");
126
127 function doubleCondCode(cond)
128 {
129     const bitInvert = 0x10;
130     const bitSpecial = 0x20;
131     switch (cond) {
132     case DoubleEqual:
133         return 4 | bitSpecial;
134     case DoubleNotEqual:
135         return 5;
136     case DoubleGreaterThan:
137         return 7;
138     case DoubleGreaterThanOrEqual:
139         return 3;
140     case DoubleLessThan:
141         return 7 | bitInvert;
142     case DoubleLessThanOrEqual:
143         return 3 | bitInvert;
144     case DoubleEqualOrUnordered:
145         return 4;
146     case DoubleNotEqualOrUnordered:
147         return 5 | bitSpecial;
148     case DoubleGreaterThanOrUnordered:
149         return 2 | bitInvert;
150     case DoubleGreaterThanOrEqualOrUnordered:
151         return 6 | bitInvert;
152     case DoubleLessThanOrUnordered:
153         return 2;
154     case DoubleLessThanOrEqualOrUnordered:
155         return 6;
156     default:
157         throw new Error("Bad cond");
158     }
159 }
160
161 // Define pointerType()
162 const Ptr = 64;
163
164 class TmpBase {
165     get isGP() { return this.type == GP; }
166     get isFP() { return this.type == FP; }
167     
168     get isGPR() { return this.isReg && this.isGP; }
169     get isFPR() { return this.isReg && this.isFP; }
170     
171     get reg()
172     {
173         if (!this.isReg)
174             throw new Error("Called .reg on non-Reg");
175         return this;
176     }
177
178     get gpr()
179     {
180         if (!this.isGPR)
181             throw new Error("Called .gpr on non-GPR");
182         return this;
183     }
184     
185     get fpr()
186     {
187         if (!this.isFPR)
188             throw new Error("Called .fpr on non-FPR");
189         return this;
190     }
191 }
192
193 class Arg {
194     constructor()
195     {
196         this._kind = Arg.Invalid;
197     }
198     
199     static isAnyUse(role)
200     {
201         switch (role) {
202         case Arg.Use:
203         case Arg.ColdUse:
204         case Arg.UseDef:
205         case Arg.UseZDef:
206         case Arg.LateUse:
207         case Arg.LateColdUse:
208         case Arg.Scratch:
209             return true;
210         case Arg.Def:
211         case Arg.ZDef:
212         case Arg.UseAddr:
213         case Arg.EarlyDef:
214             return false;
215         default:
216             throw new Error("Bad role");
217         }
218     }
219     
220     static isColdUse(role)
221     {
222         switch (role) {
223         case Arg.ColdUse:
224         case Arg.LateColdUse:
225             return true;
226         case Arg.Use:
227         case Arg.UseDef:
228         case Arg.UseZDef:
229         case Arg.LateUse:
230         case Arg.Def:
231         case Arg.ZDef:
232         case Arg.UseAddr:
233         case Arg.Scratch:
234         case Arg.EarlyDef:
235             return false;
236         default:
237             throw new Error("Bad role");
238         }
239     }
240     
241     static isWarmUse(role)
242     {
243         return Arg.isAnyUse(role) && !Arg.isColdUse(role);
244     }
245     
246     static cooled(role)
247     {
248         switch (role) {
249         case Arg.ColdUse:
250         case Arg.LateColdUse:
251         case Arg.UseDef:
252         case Arg.UseZDef:
253         case Arg.Def:
254         case Arg.ZDef:
255         case Arg.UseAddr:
256         case Arg.Scratch:
257         case Arg.EarlyDef:
258             return role;
259         case Arg.Use:
260             return Arg.ColdUse;
261         case Arg.LateUse:
262             return Arg.LateColdUse;
263         default:
264             throw new Error("Bad role");
265         }
266     }
267
268     static isEarlyUse(role)
269     {
270         switch (role) {
271         case Arg.Use:
272         case Arg.ColdUse:
273         case Arg.UseDef:
274         case Arg.UseZDef:
275             return true;
276         case Arg.Def:
277         case Arg.ZDef:
278         case Arg.UseAddr:
279         case Arg.LateUse:
280         case Arg.LateColdUse:
281         case Arg.Scratch:
282         case Arg.EarlyDef:
283             return false;
284         default:
285             throw new Error("Bad role");
286         }
287     }
288     
289     static isLateUse(role)
290     {
291         switch (role) {
292         case Arg.LateUse:
293         case Arg.LateColdUse:
294         case Arg.Scratch:
295             return true;
296         case Arg.ColdUse:
297         case Arg.Use:
298         case Arg.UseDef:
299         case Arg.UseZDef:
300         case Arg.Def:
301         case Arg.ZDef:
302         case Arg.UseAddr:
303         case Arg.EarlyDef:
304             return false;
305         default:
306             throw new Error("Bad role");
307         }
308     }
309     
310     static isAnyDef(role)
311     {
312         switch (role) {
313         case Arg.Use:
314         case Arg.ColdUse:
315         case Arg.UseAddr:
316         case Arg.LateUse:
317         case Arg.LateColdUse:
318             return false;
319         case Arg.Def:
320         case Arg.UseDef:
321         case Arg.ZDef:
322         case Arg.UseZDef:
323         case Arg.EarlyDef:
324         case Arg.Scratch:
325             return true;
326         default:
327             throw new Error("Bad role");
328         }
329     }
330     
331     static isEarlyDef(role)
332     {
333         switch (role) {
334         case Arg.Use:
335         case Arg.ColdUse:
336         case Arg.UseAddr:
337         case Arg.LateUse:
338         case Arg.Def:
339         case Arg.UseDef:
340         case Arg.ZDef:
341         case Arg.UseZDef:
342         case Arg.LateColdUse:
343             return false;
344         case Arg.EarlyDef:
345         case Arg.Scratch:
346             return true;
347         default:
348             throw new Error("Bad role");
349         }
350     }
351     
352     static isLateDef(role)
353     {
354         switch (role) {
355         case Arg.Use:
356         case Arg.ColdUse:
357         case Arg.UseAddr:
358         case Arg.LateUse:
359         case Arg.EarlyDef:
360         case Arg.Scratch:
361         case Arg.LateColdUse:
362             return false;
363         case Arg.Def:
364         case Arg.UseDef:
365         case Arg.ZDef:
366         case Arg.UseZDef:
367             return true;
368         default:
369             throw new Error("Bad role");
370         }
371     }
372     
373     static isZDef(role)
374     {
375         switch (role) {
376         case Arg.Use:
377         case Arg.ColdUse:
378         case Arg.UseAddr:
379         case Arg.LateUse:
380         case Arg.Def:
381         case Arg.UseDef:
382         case Arg.EarlyDef:
383         case Arg.Scratch:
384         case Arg.LateColdUse:
385             return false;
386         case Arg.ZDef:
387         case Arg.UseZDef:
388             return true;
389         default:
390             throw new Error("Bad role");
391         }
392     }
393     
394     static typeForB3Type(type)
395     {
396         switch (type) {
397         case Int32:
398         case Int64:
399             return GP;
400         case Float:
401         case Double:
402             return FP;
403         default:
404             throw new Error("Bad B3 type");
405         }
406     }
407     
408     static widthForB3Type(type)
409     {
410         switch (type) {
411         case Int32:
412         case Float:
413             return 32;
414         case Int64:
415         case Double:
416             return 64;
417         default:
418             throw new Error("Bad B3 type");
419         }
420     }
421     
422     static conservativeWidth(type)
423     {
424         return type == GP ? Ptr : 64;
425     }
426     
427     static minimumWidth(type)
428     {
429         return type == GP ? 8 : 32;
430     }
431     
432     static bytes(width)
433     {
434         return width / 8;
435     }
436     
437     static widthForBytes(bytes)
438     {
439         switch (bytes) {
440         case 0:
441         case 1:
442             return 8;
443         case 2:
444             return 16;
445         case 3:
446         case 4:
447             return 32;
448         default:
449             if (bytes > 8)
450                 throw new Error("Bad number of bytes");
451             return 64;
452         }
453     }
454     
455     static createTmp(tmp)
456     {
457         let result = new Arg();
458         result._kind = Arg.Tmp;
459         result._tmp = tmp;
460         return result;
461     }
462     
463     static fromReg(reg)
464     {
465         return Arg.createTmp(reg);
466     }
467     
468     static createImm(value)
469     {
470         let result = new Arg();
471         result._kind = Arg.Imm;
472         result._value = value;
473         return result;
474     }
475     
476     static createBigImm(lowValue, highValue = 0)
477     {
478         let result = new Arg();
479         result._kind = Arg.BigImm;
480         result._lowValue = lowValue;
481         result._highValue = highValue;
482         return result;
483     }
484     
485     static createBitImm(value)
486     {
487         let result = new Arg();
488         result._kind = Arg.BitImm;
489         result._value = value;
490         return result;
491     }
492     
493     static createBitImm64(lowValue, highValue = 0)
494     {
495         let result = new Arg();
496         result._kind = Arg.BitImm64;
497         result._lowValue = lowValue;
498         result._highValue = highValue;
499         return result;
500     }
501     
502     static createAddr(base, offset = 0)
503     {
504         let result = new Arg();
505         result._kind = Arg.Addr;
506         result._base = base;
507         result._offset = offset;
508         return result;
509     }
510     
511     static createStack(slot, offset = 0)
512     {
513         let result = new Arg();
514         result._kind = Arg.Stack;
515         result._slot = slot;
516         result._offset = offset;
517         return result;
518     }
519     
520     static createCallArg(offset)
521     {
522         let result = new Arg();
523         result._kind = Arg.CallArg;
524         result._offset = offset;
525         return result;
526     }
527     
528     static createStackAddr(offsetFromFP, frameSize, width)
529     {
530         let result = Arg.createAddr(Reg.callFrameRegister, offsetFromFP);
531         if (!result.isValidForm(width))
532             result = Arg.createAddr(Reg.stackPointerRegister, offsetFromFP + frameSize);
533         return result;
534     }
535     
536     static isValidScale(scale, width)
537     {
538         switch (scale) {
539         case 1:
540         case 2:
541         case 4:
542         case 8:
543             return true;
544         default:
545             return false;
546         }
547     }
548     
549     static logScale(scale)
550     {
551         switch (scale) {
552         case 1:
553             return 0;
554         case 2:
555             return 1;
556         case 4:
557             return 2;
558         case 8:
559             return 3;
560         default:
561             throw new Error("Bad scale");
562         }
563     }
564     
565     static createIndex(base, index, scale = 1, offset = 0)
566     {
567         let result = new Arg();
568         result._kind = Arg.Index;
569         result._base = base;
570         result._index = index;
571         result._scale = scale;
572         result._offset = offset;
573         return result;
574     }
575     
576     static createRelCond(condition)
577     {
578         let result = new Arg();
579         result._kind = Arg.RelCond;
580         result._condition = condition;
581         return result;
582     }
583     
584     static createResCond(condition)
585     {
586         let result = new Arg();
587         result._kind = Arg.ResCond;
588         result._condition = condition;
589         return result;
590     }
591     
592     static createDoubleCond(condition)
593     {
594         let result = new Arg();
595         result._kind = Arg.DoubleCond;
596         result._condition = condition;
597         return result;
598     }
599     
600     static createWidth(width)
601     {
602         let result = new Arg();
603         result._kind = Arg.Width;
604         result._width = width;
605         return result;
606     }
607     
608     static createSpecial()
609     {
610         let result = new Arg();
611         result._kind = Arg.Special;
612         return result;
613     }
614     
615     get kind() { return this._kind; }
616     get isTmp() { return this._kind == Arg.Tmp; }
617     get isImm() { return this._kind == Arg.Imm; }
618     get isBigImm() { return this._kind == Arg.BigImm; }
619     get isBitImm() { return this._kind == Arg.BitImm; }
620     get isBitImm64() { return this._kind == Arg.BitImm64; }
621     get isSomeImm()
622     {
623         switch (this._kind) {
624         case Arg.Imm:
625         case Arg.BitImm:
626             return true;
627         default:
628             return false;
629         }
630     }
631     get isSomeBigImm()
632     {
633         switch (this._kind) {
634         case Arg.BigImm:
635         case Arg.BitImm64:
636             return true;
637         default:
638             return false;
639         }
640     }
641     get isAddr() { return this._kind == Arg.Addr; }
642     get isStack() { return this._kind == Arg.Stack; }
643     get isCallArg() { return this._kind == Arg.CallArg; }
644     get isIndex() { return this._kind == Arg.Index; }
645     get isMemory()
646     {
647         switch (this._kind) {
648         case Arg.Addr:
649         case Arg.Stack:
650         case Arg.CallArg:
651         case Arg.Index:
652             return true;
653         default:
654             return false;
655         }
656     }
657     get isStackMemory()
658     {
659         switch (this._kind) {
660         case Arg.Addr:
661             return this._base == Reg.callFrameRegister
662                 || this._base == Reg.stackPointerRegister;
663         case Arg.Stack:
664         case Arg.CallArg:
665             return true;
666         default:
667             return false;
668         }
669     }
670     get isRelCond() { return this._kind == Arg.RelCond; }
671     get isResCond() { return this._kind == Arg.ResCond; }
672     get isDoubleCond() { return this._kind == Arg.DoubleCond; }
673     get isCondition()
674     {
675         switch (this._kind) {
676         case Arg.RelCond:
677         case Arg.ResCond:
678         case Arg.DoubleCond:
679             return true;
680         default:
681             return false;
682         }
683     }
684     get isWidth() { return this._kind == Arg.Width; }
685     get isSpecial() { return this._kind == Arg.Special; }
686     get isAlive() { return this.isTmp || this.isStack; }
687     
688     get tmp()
689     {
690         if (this._kind != Arg.Tmp)
691             throw new Error("Called .tmp for non-tmp");
692         return this._tmp;
693     }
694     
695     get value()
696     {
697         if (!this.isSomeImm)
698             throw new Error("Called .value for non-imm");
699         return this._value;
700     }
701     
702     get lowValue()
703     {
704         if (!this.isSomeBigImm)
705             throw new Error("Called .lowValue for non-big-imm");
706         return this._lowValue;
707     }
708     
709     get highValue()
710     {
711         if (!this.isSomeBigImm)
712             throw new Error("Called .highValue for non-big-imm");
713         return this._highValue;
714     }
715     
716     get base()
717     {
718         switch (this._kind) {
719         case Arg.Addr:
720         case Arg.Index:
721             return this._base;
722         default:
723             throw new Error("Called .base for non-address");
724         }
725     }
726     
727     get hasOffset() { return this.isMemory; }
728     
729     get offset()
730     {
731         switch (this._kind) {
732         case Arg.Addr:
733         case Arg.Index:
734         case Arg.Stack:
735         case Arg.CallArg:
736             return this._offset;
737         default:
738             throw new Error("Called .offset for non-address");
739         }
740     }
741     
742     get stackSlot()
743     {
744         if (this._kind != Arg.Stack)
745             throw new Error("Called .stackSlot for non-address");
746         return this._slot;
747     }
748     
749     get index()
750     {
751         if (this._kind != Arg.Index)
752             throw new Error("Called .index for non-Index");
753         return this._index;
754     }
755     
756     get scale()
757     {
758         if (this._kind != Arg.Index)
759             throw new Error("Called .scale for non-Index");
760         return this._scale;
761     }
762     
763     get logScale()
764     {
765         return Arg.logScale(this.scale);
766     }
767     
768     get width()
769     {
770         if (this._kind != Arg.Width)
771             throw new Error("Called .width for non-Width");
772         return this._width;
773     }
774     
775     get isGPTmp() { return this.isTmp && this.tmp.isGP; }
776     get isFPTmp() { return this.isTmp && this.tmp.isFP; }
777     
778     get isGP()
779     {
780         switch (this._kind) {
781         case Arg.Imm:
782         case Arg.BigImm:
783         case Arg.BitImm:
784         case Arg.BitImm64:
785         case Arg.Addr:
786         case Arg.Index:
787         case Arg.Stack:
788         case Arg.CallArg:
789         case Arg.RelCond:
790         case Arg.ResCond:
791         case Arg.DoubleCond:
792         case Arg.Width:
793         case Arg.Special:
794             return true;
795         case Arg.Tmp:
796             return this.isGPTmp;
797         case Arg.Invalid:
798             return false;
799         default:
800             throw new Error("Bad kind");
801         }
802     }
803     
804     get isFP()
805     {
806         switch (this._kind) {
807         case Arg.Imm:
808         case Arg.BitImm:
809         case Arg.BitImm64:
810         case Arg.RelCond:
811         case Arg.ResCond:
812         case Arg.DoubleCond:
813         case Arg.Width:
814         case Arg.Special:
815         case Arg.Invalid:
816             return false;
817         case Arg.Addr:
818         case Arg.Index:
819         case Arg.Stack:
820         case Arg.CallArg:
821         case Arg.BigImm:
822             return true;
823         case Arg.Tmp:
824             return this.isFPTmp;
825         default:
826             throw new Error("Bad kind");
827         }
828     }
829     
830     get hasType()
831     {
832         switch (this._kind) {
833         case Arg.Imm:
834         case Arg.BitImm:
835         case Arg.BitImm64:
836         case Arg.Tmp:
837             return true;
838         default:
839             return false;
840         }
841     }
842     
843     get type()
844     {
845         return this.isGP ? GP : FP;
846     }
847     
848     isType(type)
849     {
850         switch (type) {
851         case Arg.GP:
852             return this.isGP;
853         case Arg.FP:
854             return this.isFP;
855         default:
856             throw new Error("Bad type");
857         }
858     }
859     
860     isCompatibleType(other)
861     {
862         if (this.hasType)
863             return other.isType(this.type);
864         if (other.hasType)
865             return this.isType(other.type);
866         return true;
867     }
868     
869     get isGPR() { return this.isTmp && this.tmp.isGPR; }
870     get gpr() { return this.tmp.gpr; }
871     get isFPR() { return this.isTmp && this.tmp.isFPR; }
872     get fpr() { return this.tmp.fpr; }
873     get isReg() { return this.isTmp && this.tmp.isReg; }
874     get reg() { return this.tmp.reg; }
875     
876     static isValidImmForm(value)
877     {
878         return isRepresentableAsInt32(value);
879     }
880     static isValidBitImmForm(value)
881     {
882         return isRepresentableAsInt32(value);
883     }
884     static isValidBitImm64Form(value)
885     {
886         return isRepresentableAsInt32(value);
887     }
888     
889     static isValidAddrForm(offset, width)
890     {
891         return true;
892     }
893     
894     static isValidIndexForm(scale, offset, width)
895     {
896         if (!isValidScale(scale, width))
897             return false;
898         return true;
899     }
900     
901     isValidForm(width)
902     {
903         switch (this._kind) {
904         case Arg.Invalid:
905             return false;
906         case Arg.Tmp:
907             return true;
908         case Arg.Imm:
909             return Arg.isValidImmForm(this.value);
910         case Arg.BigImm:
911             return true;
912         case Arg.BitImm:
913             return Arg.isValidBitImmForm(this.value);
914         case Arg.BitImm64:
915             return Arg.isValidBitImm64Form(this.value);
916         case Arg.Addr:
917         case Arg.Stack:
918         case Arg.CallArg:
919             return Arg.isValidAddrForm(this.offset, width);
920         case Arg.Index:
921             return Arg.isValidIndexForm(this.scale, this.offset, width);
922         case Arg.RelCond:
923         case Arg.ResCond:
924         case Arg.DoubleCond:
925         case Arg.Width:
926         case Arg.Special:
927             return true;
928         default:
929             throw new Error("Bad kind");
930         }
931     }
932     
933     forEachTmpFast(func)
934     {
935         switch (this._kind) {
936         case Arg.Tmp: {
937             let replacement;
938             if (replacement = func(this._tmp))
939                 return Arg.createTmp(replacement);
940             break;
941         }
942         case Arg.Addr: {
943             let replacement;
944             if (replacement = func(this._base))
945                 return Arg.createAddr(replacement, this._offset);
946             break;
947         }
948         case Arg.Index: {
949             let baseReplacement = func(this._base);
950             let indexReplacement = func(this._index);
951             if (baseReplacement || indexReplacement) {
952                 return Arg.createIndex(
953                     baseReplacement ? baseReplacement : this._base,
954                     indexReplacement ? indexReplacement : this._index,
955                     this._scale, this._offset);
956             }
957             break;
958         }
959         default:
960             break;
961         }
962     }
963     
964     usesTmp(expectedTmp)
965     {
966         let usesTmp = false;
967         forEachTmpFast(tmp => {
968             usesTmp |= tmp == expectedTmp;
969         });
970         return usesTmp;
971     }
972     
973     forEachTmp(role, type, width, func)
974     {
975         switch (this._kind) {
976         case Arg.Tmp: {
977             let replacement;
978             if (replacement = func(this._tmp, role, type, width))
979                 return Arg.createTmp(replacement);
980             break;
981         }
982         case Arg.Addr: {
983             let replacement;
984             if (replacement = func(this._base, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr))
985                 return Arg.createAddr(replacement, this._offset);
986             break;
987         }
988         case Arg.Index: {
989             let baseReplacement = func(this._base, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr);
990             let indexReplacement = func(this._index, Arg.Use, GP, role == Arg.UseAddr ? width : Ptr);
991             if (baseReplacement || indexReplacement) {
992                 return Arg.createIndex(
993                     baseReplacement ? baseReplacement : this._base,
994                     indexReplacement ? indexReplacement : this._index,
995                     this._scale, this._offset);
996             }
997             break;
998         }
999         default:
1000             break;
1001         }
1002     }
1003     
1004     is(thing) { return !!thing.extract(this); }
1005     as(thing) { return thing.extract(this); }
1006     
1007     // This lets you say things like:
1008     // arg.forEach(Tmp | Reg | Arg | StackSlot, ...)
1009     //
1010     // It's used for abstract liveness analysis.
1011     forEachFast(thing, func)
1012     {
1013         return thing.forEachFast(this, func);
1014     }
1015     forEach(thing, role, type, width, func)
1016     {
1017         return thing.forEach(this, role, type, width, func);
1018     }
1019     
1020     static extract(arg) { return arg; }
1021     static forEachFast(arg, func) { return func(arg); }
1022     static forEach(arg, role, type, width, func) { return func(arg, role, type, width); }
1023
1024     get condition()
1025     {
1026         switch (this._kind) {
1027         case Arg.RelCond:
1028         case Arg.ResCond:
1029         case Arg.DoubleCond:
1030             return this._condition;
1031         default:
1032             throw new Error("Called .condition for non-condition");
1033         }
1034     }
1035     
1036     get isInvertible()
1037     {
1038         switch (this._kind) {
1039         case Arg.RelCond:
1040         case Arg.DoubleCold:
1041             return true;
1042         case Arg.ResCond:
1043             switch (this._condition) {
1044             case Zero:
1045             case NonZero:
1046             case Signed:
1047             case PositiveOrZero:
1048                 return true;
1049             default:
1050                 return false;
1051             }
1052         default:
1053             return false;
1054         }
1055     }
1056     
1057     static kindCode(kind)
1058     {
1059         switch (kind) {
1060         case Arg.Invalid:
1061             return 0;
1062         case Arg.Tmp:
1063             return 1;
1064         case Arg.Imm:
1065             return 2;
1066         case Arg.BigImm:
1067             return 3;
1068         case Arg.BitImm:
1069             return 4;
1070         case Arg.BitImm64:
1071             return 5;
1072         case Arg.Addr:
1073             return 6;
1074         case Arg.Stack:
1075             return 7;
1076         case Arg.CallArg:
1077             return 8;
1078         case Arg.Index:
1079             return 9;
1080         case Arg.RelCond:
1081             return 10;
1082         case Arg.ResCond:
1083             return 11;
1084         case Arg.DoubleCond:
1085             return 12;
1086         case Arg.Special:
1087             return 13;
1088         case Arg.WidthArg:
1089             return 14;
1090         default:
1091             throw new Error("Bad kind");
1092         }
1093     }
1094     
1095     hash()
1096     {
1097         let result = Arg.kindCode(this._kind);
1098         
1099         switch (this._kind) {
1100         case Arg.Invalid:
1101         case Arg.Special:
1102             break;
1103         case Arg.Tmp:
1104             result += this._tmp.hash();
1105             result |= 0;
1106             break;
1107         case Arg.Imm:
1108         case Arg.BitImm:
1109             result += this._value;
1110             result |= 0;
1111             break;
1112         case Arg.BigImm:
1113         case Arg.BitImm64:
1114             result += this._lowValue;
1115             result |= 0;
1116             result += this._highValue;
1117             result |= 0;
1118             break;
1119         case Arg.CallArg:
1120             result += this._offset;
1121             result |= 0;
1122             break;
1123         case Arg.RelCond:
1124             result += relCondCode(this._condition);
1125             result |= 0;
1126             break;
1127         case Arg.ResCond:
1128             result += resCondCode(this._condition);
1129             result |= 0;
1130             break;
1131         case Arg.DoubleCond:
1132             result += doubleCondCode(this._condition);
1133             result |= 0;
1134             break;
1135         case Arg.WidthArg:
1136             result += this._width;
1137             result |= 0;
1138             break;
1139         case Arg.Addr:
1140             result += this._offset;
1141             result |= 0;
1142             result += this._base.hash();
1143             result |= 0;
1144             break;
1145         case Arg.Index:
1146             result += this._offset;
1147             result |= 0;
1148             result += this._scale;
1149             result |= 0;
1150             result += this._base.hash();
1151             result |= 0;
1152             result += this._index.hash();
1153             result |= 0;
1154             break;
1155         case Arg.Stack:
1156             result += this._offset;
1157             result |= 0;
1158             result += this.stackSlot.index;
1159             result |= 0;
1160             break;
1161         }
1162         
1163         return result >>> 0;
1164     }
1165     
1166     toString()
1167     {
1168         switch (this._kind) {
1169         case Arg.Invalid:
1170             return "<invalid>";
1171         case Arg.Tmp:
1172             return this._tmp.toString();
1173         case Arg.Imm:
1174             return "$" + this._value;
1175         case Arg.BigImm:
1176         case Arg.BitImm64:
1177             return "$0x" + this._highValue.toString(16) + ":" + this._lowValue.toString(16);
1178         case Arg.Addr:
1179             return "" + (this._offset ? this._offset : "") + "(" + this._base + ")";
1180         case Arg.Index:
1181             return "" + (this._offset ? this._offset : "") + "(" + this._base +
1182                 "," + this._index + (this._scale == 1 ? "" : "," + this._scale) + ")";
1183         case Arg.Stack:
1184             return "" + (this._offset ? this._offset : "") + "(" + this._slot + ")";
1185         case Arg.CallArg:
1186             return "" + (this._offset ? this._offset : "") + "(callArg)";
1187         case Arg.RelCond:
1188         case Arg.ResCond:
1189         case Arg.DoubleCond:
1190             return symbolName(this._condition);
1191         case Arg.Special:
1192             return "special";
1193         case Arg.Width:
1194             return "" + this._value;
1195         default:
1196             throw new Error("Bad kind");
1197         }
1198     }
1199 }
1200
1201 // Arg kinds
1202 Arg.Invalid = Symbol("Invalid");
1203 Arg.Tmp = Symbol("Tmp");
1204 Arg.Imm = Symbol("Imm");
1205 Arg.BigImm = Symbol("BigImm");
1206 Arg.BitImm = Symbol("BitImm");
1207 Arg.BitImm64 = Symbol("BitImm64");
1208 Arg.Addr = Symbol("Addr");
1209 Arg.Stack = Symbol("Stack");
1210 Arg.CallArg = Symbol("CallArg");
1211 Arg.Index = Symbol("Index");
1212 Arg.RelCond = Symbol("RelCond");
1213 Arg.ResCond = Symbol("ResCond");
1214 Arg.DoubleCond = Symbol("DoubleCond");
1215 Arg.Special = Symbol("Special");
1216 Arg.Width = Symbol("Width");
1217
1218 // Arg roles
1219 Arg.Use = Symbol("Use");
1220 Arg.ColdUse = Symbol("ColdUse");
1221 Arg.LateUse = Symbol("LateUse");
1222 Arg.LateColdUse = Symbol("LateColdUse");
1223 Arg.Def = Symbol("Def");
1224 Arg.ZDef = Symbol("ZDef");
1225 Arg.UseDef = Symbol("UseDef");
1226 Arg.UseZDef = Symbol("UseZDef");
1227 Arg.EarlyDef = Symbol("EarlyDef");
1228 Arg.Scratch = Symbol("Scratch");
1229 Arg.UseAddr = Symbol("UseAddr");
1230
1231 class BasicBlock {
1232     constructor(index, frequency)
1233     {
1234         this._index = index;
1235         this._frequency = frequency;
1236         this._insts = [];
1237         this._successors = [];
1238         this._predecessors = [];
1239     }
1240     
1241     get index() { return this._index; }
1242     get size() { return this._insts.length; }
1243     
1244     [Symbol.iterator]()
1245     {
1246         return this._insts[Symbol.iterator]();
1247     }
1248     
1249     at(index)
1250     {
1251         if (index >= this._insts.length)
1252             throw new Error("Out of bounds access");
1253         return this._insts[index];
1254     }
1255     
1256     get(index)
1257     {
1258         if (index < 0 || index >= this._insts.length)
1259             return null;
1260         return this._insts[index];
1261     }
1262     
1263     get last()
1264     {
1265         return this._insts[this._insts.length - 1];
1266     }
1267     
1268     get insts() { return this._insts; }
1269     
1270     append(inst) { this._insts.push(inst); }
1271     
1272     get numSuccessors() { return this._successors.length; }
1273     successor(index) { return this._successors[index]; }
1274     get successors() { return this._successors; }
1275     
1276     successorBlock(index) { return this._successors[index].block; }
1277     get successorBlocks()
1278     {
1279         return new Proxy(this._successors, {
1280             get(target, property) {
1281                 if (typeof property == "string"
1282                     && (property | 0) == property)
1283                     return target[property].block;
1284                 return target[property];
1285             },
1286             
1287             set(target, property, value) {
1288                 if (typeof property == "string"
1289                     && (property | 0) == property) {
1290                     var oldValue = target[property];
1291                     target[property] = new FrequentedBlock(
1292                         value, oldValue ? oldValue.frequency : Normal);
1293                     return;
1294                 }
1295                 
1296                 target[property] = value;
1297             }
1298         });
1299     }
1300     
1301     get numPredecessors() { return this._predecessors.length; }
1302     predecessor(index) { return this._predecessors[index]; }
1303     get predecessors() { return this._predecessors; }
1304     
1305     get frequency() { return this._frequency; }
1306
1307     toString()
1308     {
1309         return "#" + this._index;
1310     }
1311     
1312     get headerString()
1313     {
1314         let result = "";
1315         result += `BB${this}: ; frequency = ${this._frequency}\n`;
1316         if (this._predecessors.length)
1317             result += "  Predecessors: " + this._predecessors.join(", ") + "\n";
1318         return result;
1319     }
1320     
1321     get footerString()
1322     {
1323         let result = "";
1324         if (this._successors.length)
1325             result += "  Successors: " + this._successors.join(", ") + "\n";
1326         return result;
1327     }
1328     
1329     toStringDeep()
1330     {
1331         let result = "";
1332         result += this.headerString;
1333         for (let inst of this)
1334             result += `    ${inst}\n`;
1335         result += this.footerString;
1336         return result;
1337     }
1338 }
1339
1340
1341 class Code {
1342     constructor()
1343     {
1344         this._blocks = [];
1345         this._stackSlots = [];
1346         this._gpTmps = [];
1347         this._fpTmps = [];
1348         this._callArgAreaSize = 0;
1349         this._frameSize = 0;
1350     }
1351     
1352     addBlock(frequency = 1)
1353     {
1354         return addIndexed(this._blocks, BasicBlock, frequency);
1355     }
1356     
1357     addStackSlot(byteSize, kind)
1358     {
1359         return addIndexed(this._stackSlots, StackSlot, byteSize, kind);
1360     }
1361     
1362     newTmp(type)
1363     {
1364         return addIndexed(this[`_${lowerSymbolName(type)}Tmps`], Tmp, type);
1365     }
1366     
1367     get size() { return this._blocks.length; }
1368     at(index) { return this._blocks[index]; }
1369     
1370     [Symbol.iterator]()
1371     {
1372         return this._blocks[Symbol.iterator]();
1373     }
1374     
1375     get blocks() { return this._blocks; }
1376     get stackSlots() { return this._stackSlots; }
1377     
1378     tmps(type) { return this[`_${lowerSymbolName(type)}Tmps`]; }
1379     
1380     get callArgAreaSize() { return this._callArgAreaSize; }
1381     
1382     requestCallArgAreaSize(size)
1383     {
1384         this._callArgAreaSize = Math.max(this._callArgAreaSize, roundUpToMultipleOf(stackAlignmentBytes, size));
1385     }
1386     
1387     get frameSize() { return this._frameSize; }
1388     
1389     setFrameSize(frameSize) { this._frameSize = frameSize; }
1390     
1391     hash()
1392     {
1393         let result = 0;
1394         for (let block of this) {
1395             result *= 1000001;
1396             result |= 0;
1397             for (let inst of block) {
1398                 result *= 97;
1399                 result |= 0;
1400                 result += inst.hash();
1401                 result |= 0;
1402             }
1403             for (let successor of block.successorBlocks) {
1404                 result *= 7;
1405                 result |= 0;
1406                 result += successor.index;
1407                 result |= 0;
1408             }
1409         }
1410         for (let slot of this.stackSlots) {
1411             result *= 101;
1412             result |= 0;
1413             result += slot.hash();
1414             result |= 0;
1415         }
1416         return result >>> 0;
1417     }
1418     
1419     toString()
1420     {
1421         let result = "";
1422         for (let block of this) {
1423             result += block.toStringDeep();
1424         }
1425         if (this.stackSlots.length) {
1426             result += "Stack slots:\n";
1427             for (let slot of this.stackSlots)
1428                 result += `    ${slot}\n`;
1429         }
1430         if (this._frameSize)
1431             result += `Frame size: ${this._frameSize}\n`;
1432         if (this._callArgAreaSize)
1433             result += `Call arg area size: ${this._callArgAreaSize}\n`;
1434         return result;
1435     }
1436 }
1437
1438 class FrequentedBlock {
1439     constructor(block, frequency)
1440     {
1441         this.block = block;
1442         this.frequency = frequency;
1443     }
1444     
1445     toString()
1446     {
1447         return (this.frequency == Normal ? "" : "Rare:") + this.block;
1448     }
1449 }
1450
1451 class Inst {
1452     constructor(opcode, args = [])
1453     {
1454         this._opcode = opcode;
1455         this._args = args;
1456     }
1457     
1458     append(...args)
1459     {
1460         this._args.push(...args);
1461     }
1462     
1463     clear()
1464     {
1465         this._opcode = Nop;
1466         this._args = [];
1467     }
1468     
1469     get opcode() { return this._opcode; }
1470     get args() { return this._args; }
1471     
1472     visitArg(index, func, ...args)
1473     {
1474         let replacement = func(this._args[index], ...args);
1475         if (replacement)
1476             this._args[index] = replacement;
1477     }
1478     
1479     forEachTmpFast(func)
1480     {
1481         for (let i = 0; i < this._args.length; ++i) {
1482             let replacement;
1483             if (replacement = this._args[i].forEachTmpFast(func))
1484                 this._args[i] = replacement;
1485         }
1486     }
1487     
1488     forEachArg(func)
1489     {
1490         Inst_forEachArg(this, func);
1491     }
1492     
1493     forEachTmp(func)
1494     {
1495         this.forEachArg((arg, role, type, width) => {
1496             return arg.forEachTmp(role, type, width, func);
1497         });
1498     }
1499     
1500     forEach(thing, func)
1501     {
1502         this.forEachArg((arg, role, type, width) => {
1503             return arg.forEach(thing, role, type, width, func);
1504         });
1505     }
1506     
1507     static forEachDef(thing, prevInst, nextInst, func)
1508     {
1509         if (prevInst) {
1510             prevInst.forEach(
1511                 thing,
1512                 (value, role, type, width) => {
1513                     if (Arg.isLateDef(role))
1514                         return func(value, role, type, width);
1515                 });
1516         }
1517         
1518         if (nextInst) {
1519             nextInst.forEach(
1520                 thing,
1521                 (value, role, type, width) => {
1522                     if (Arg.isEarlyDef(role))
1523                         return func(value, role, type, width);
1524                 });
1525         }
1526     }
1527     
1528     static forEachDefWithExtraClobberedRegs(thing, prevInst, nextInst, func)
1529     {
1530         forEachDef(thing, prevInst, nextInst, func);
1531         
1532         let regDefRole;
1533         
1534         let reportReg = reg => {
1535             let type = reg.isGPR ? GP : FP;
1536             func(thing.fromReg(reg), regDefRole, type, Arg.conservativeWidth(type));
1537         };
1538         
1539         if (prevInst && prevInst.opcode == Patch) {
1540             regDefRole = Arg.Def;
1541             prevInst.extraClobberedRegs.forEach(reportReg);
1542         }
1543         
1544         if (nextInst && nextInst.opcode == Patch) {
1545             regDefRole = Arg.EarlyDef;
1546             nextInst.extraEarlyClobberedRegs.forEach(reportReg);
1547         }
1548     }
1549     
1550     get hasNonArgEffects() { return Inst_hasNonArgEffects(this); }
1551     
1552     hash()
1553     {
1554         let result = opcodeCode(this.opcode);
1555         for (let arg of this.args) {
1556             result += arg.hash();
1557             result |= 0;
1558         }
1559         return result >>> 0;
1560     }
1561     
1562     toString()
1563     {
1564         return "" + symbolName(this._opcode) + " " + this._args.join(", ");
1565     }
1566 }
1567
1568 "use strict";
1569 // Generated by opcode_generator.rb from JavaScriptCore/b3/air/AirOpcode.opcodes -- do not edit!
1570 const Nop = Symbol("Nop");
1571 const Add32 = Symbol("Add32");
1572 const Add8 = Symbol("Add8");
1573 const Add16 = Symbol("Add16");
1574 const Add64 = Symbol("Add64");
1575 const AddDouble = Symbol("AddDouble");
1576 const AddFloat = Symbol("AddFloat");
1577 const Sub32 = Symbol("Sub32");
1578 const Sub64 = Symbol("Sub64");
1579 const SubDouble = Symbol("SubDouble");
1580 const SubFloat = Symbol("SubFloat");
1581 const Neg32 = Symbol("Neg32");
1582 const Neg64 = Symbol("Neg64");
1583 const NegateDouble = Symbol("NegateDouble");
1584 const Mul32 = Symbol("Mul32");
1585 const Mul64 = Symbol("Mul64");
1586 const MultiplyAdd32 = Symbol("MultiplyAdd32");
1587 const MultiplyAdd64 = Symbol("MultiplyAdd64");
1588 const MultiplySub32 = Symbol("MultiplySub32");
1589 const MultiplySub64 = Symbol("MultiplySub64");
1590 const MultiplyNeg32 = Symbol("MultiplyNeg32");
1591 const MultiplyNeg64 = Symbol("MultiplyNeg64");
1592 const Div32 = Symbol("Div32");
1593 const Div64 = Symbol("Div64");
1594 const MulDouble = Symbol("MulDouble");
1595 const MulFloat = Symbol("MulFloat");
1596 const DivDouble = Symbol("DivDouble");
1597 const DivFloat = Symbol("DivFloat");
1598 const X86ConvertToDoubleWord32 = Symbol("X86ConvertToDoubleWord32");
1599 const X86ConvertToQuadWord64 = Symbol("X86ConvertToQuadWord64");
1600 const X86Div32 = Symbol("X86Div32");
1601 const X86Div64 = Symbol("X86Div64");
1602 const Lea = Symbol("Lea");
1603 const And32 = Symbol("And32");
1604 const And64 = Symbol("And64");
1605 const AndDouble = Symbol("AndDouble");
1606 const AndFloat = Symbol("AndFloat");
1607 const XorDouble = Symbol("XorDouble");
1608 const XorFloat = Symbol("XorFloat");
1609 const Lshift32 = Symbol("Lshift32");
1610 const Lshift64 = Symbol("Lshift64");
1611 const Rshift32 = Symbol("Rshift32");
1612 const Rshift64 = Symbol("Rshift64");
1613 const Urshift32 = Symbol("Urshift32");
1614 const Urshift64 = Symbol("Urshift64");
1615 const Or32 = Symbol("Or32");
1616 const Or64 = Symbol("Or64");
1617 const Xor32 = Symbol("Xor32");
1618 const Xor64 = Symbol("Xor64");
1619 const Not32 = Symbol("Not32");
1620 const Not64 = Symbol("Not64");
1621 const AbsDouble = Symbol("AbsDouble");
1622 const AbsFloat = Symbol("AbsFloat");
1623 const CeilDouble = Symbol("CeilDouble");
1624 const CeilFloat = Symbol("CeilFloat");
1625 const FloorDouble = Symbol("FloorDouble");
1626 const FloorFloat = Symbol("FloorFloat");
1627 const SqrtDouble = Symbol("SqrtDouble");
1628 const SqrtFloat = Symbol("SqrtFloat");
1629 const ConvertInt32ToDouble = Symbol("ConvertInt32ToDouble");
1630 const ConvertInt64ToDouble = Symbol("ConvertInt64ToDouble");
1631 const ConvertInt32ToFloat = Symbol("ConvertInt32ToFloat");
1632 const ConvertInt64ToFloat = Symbol("ConvertInt64ToFloat");
1633 const CountLeadingZeros32 = Symbol("CountLeadingZeros32");
1634 const CountLeadingZeros64 = Symbol("CountLeadingZeros64");
1635 const ConvertDoubleToFloat = Symbol("ConvertDoubleToFloat");
1636 const ConvertFloatToDouble = Symbol("ConvertFloatToDouble");
1637 const Move = Symbol("Move");
1638 const Swap32 = Symbol("Swap32");
1639 const Swap64 = Symbol("Swap64");
1640 const Move32 = Symbol("Move32");
1641 const StoreZero32 = Symbol("StoreZero32");
1642 const SignExtend32ToPtr = Symbol("SignExtend32ToPtr");
1643 const ZeroExtend8To32 = Symbol("ZeroExtend8To32");
1644 const SignExtend8To32 = Symbol("SignExtend8To32");
1645 const ZeroExtend16To32 = Symbol("ZeroExtend16To32");
1646 const SignExtend16To32 = Symbol("SignExtend16To32");
1647 const MoveFloat = Symbol("MoveFloat");
1648 const MoveDouble = Symbol("MoveDouble");
1649 const MoveZeroToDouble = Symbol("MoveZeroToDouble");
1650 const Move64ToDouble = Symbol("Move64ToDouble");
1651 const Move32ToFloat = Symbol("Move32ToFloat");
1652 const MoveDoubleTo64 = Symbol("MoveDoubleTo64");
1653 const MoveFloatTo32 = Symbol("MoveFloatTo32");
1654 const Load8 = Symbol("Load8");
1655 const Store8 = Symbol("Store8");
1656 const Load8SignedExtendTo32 = Symbol("Load8SignedExtendTo32");
1657 const Load16 = Symbol("Load16");
1658 const Load16SignedExtendTo32 = Symbol("Load16SignedExtendTo32");
1659 const Store16 = Symbol("Store16");
1660 const Compare32 = Symbol("Compare32");
1661 const Compare64 = Symbol("Compare64");
1662 const Test32 = Symbol("Test32");
1663 const Test64 = Symbol("Test64");
1664 const CompareDouble = Symbol("CompareDouble");
1665 const CompareFloat = Symbol("CompareFloat");
1666 const Branch8 = Symbol("Branch8");
1667 const Branch32 = Symbol("Branch32");
1668 const Branch64 = Symbol("Branch64");
1669 const BranchTest8 = Symbol("BranchTest8");
1670 const BranchTest32 = Symbol("BranchTest32");
1671 const BranchTest64 = Symbol("BranchTest64");
1672 const BranchDouble = Symbol("BranchDouble");
1673 const BranchFloat = Symbol("BranchFloat");
1674 const BranchAdd32 = Symbol("BranchAdd32");
1675 const BranchAdd64 = Symbol("BranchAdd64");
1676 const BranchMul32 = Symbol("BranchMul32");
1677 const BranchMul64 = Symbol("BranchMul64");
1678 const BranchSub32 = Symbol("BranchSub32");
1679 const BranchSub64 = Symbol("BranchSub64");
1680 const BranchNeg32 = Symbol("BranchNeg32");
1681 const BranchNeg64 = Symbol("BranchNeg64");
1682 const MoveConditionally32 = Symbol("MoveConditionally32");
1683 const MoveConditionally64 = Symbol("MoveConditionally64");
1684 const MoveConditionallyTest32 = Symbol("MoveConditionallyTest32");
1685 const MoveConditionallyTest64 = Symbol("MoveConditionallyTest64");
1686 const MoveConditionallyDouble = Symbol("MoveConditionallyDouble");
1687 const MoveConditionallyFloat = Symbol("MoveConditionallyFloat");
1688 const MoveDoubleConditionally32 = Symbol("MoveDoubleConditionally32");
1689 const MoveDoubleConditionally64 = Symbol("MoveDoubleConditionally64");
1690 const MoveDoubleConditionallyTest32 = Symbol("MoveDoubleConditionallyTest32");
1691 const MoveDoubleConditionallyTest64 = Symbol("MoveDoubleConditionallyTest64");
1692 const MoveDoubleConditionallyDouble = Symbol("MoveDoubleConditionallyDouble");
1693 const MoveDoubleConditionallyFloat = Symbol("MoveDoubleConditionallyFloat");
1694 const Jump = Symbol("Jump");
1695 const Ret32 = Symbol("Ret32");
1696 const Ret64 = Symbol("Ret64");
1697 const RetFloat = Symbol("RetFloat");
1698 const RetDouble = Symbol("RetDouble");
1699 const Oops = Symbol("Oops");
1700 const Shuffle = Symbol("Shuffle");
1701 const Patch = Symbol("Patch");
1702 const CCall = Symbol("CCall");
1703 const ColdCCall = Symbol("ColdCCall");
1704 function Inst_forEachArg(inst, func)
1705 {
1706     let replacement;
1707     switch (inst.opcode) {
1708     case Nop:
1709         break;
1710         break;
1711     case Add32:
1712         switch (inst.args.length) {
1713         case 3:
1714             inst.visitArg(0, func, Arg.Use, GP, 32);
1715             inst.visitArg(1, func, Arg.Use, GP, 32);
1716             inst.visitArg(2, func, Arg.ZDef, GP, 32);
1717             break;
1718         case 2:
1719             inst.visitArg(0, func, Arg.Use, GP, 32);
1720             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
1721             break;
1722         default:
1723             throw new Error("Bad overload");
1724             break;
1725         }
1726         break;
1727     case Add8:
1728         inst.visitArg(0, func, Arg.Use, GP, 8);
1729         inst.visitArg(1, func, Arg.UseDef, GP, 8);
1730         break;
1731         break;
1732     case Add16:
1733         inst.visitArg(0, func, Arg.Use, GP, 16);
1734         inst.visitArg(1, func, Arg.UseDef, GP, 16);
1735         break;
1736         break;
1737     case Add64:
1738         switch (inst.args.length) {
1739         case 2:
1740             inst.visitArg(0, func, Arg.Use, GP, 64);
1741             inst.visitArg(1, func, Arg.UseDef, GP, 64);
1742             break;
1743         case 3:
1744             inst.visitArg(0, func, Arg.Use, GP, 64);
1745             inst.visitArg(1, func, Arg.Use, GP, 64);
1746             inst.visitArg(2, func, Arg.Def, GP, 64);
1747             break;
1748         default:
1749             throw new Error("Bad overload");
1750             break;
1751         }
1752         break;
1753     case AddDouble:
1754         switch (inst.args.length) {
1755         case 3:
1756             inst.visitArg(0, func, Arg.Use, FP, 64);
1757             inst.visitArg(1, func, Arg.Use, FP, 64);
1758             inst.visitArg(2, func, Arg.Def, FP, 64);
1759             break;
1760         case 2:
1761             inst.visitArg(0, func, Arg.Use, FP, 64);
1762             inst.visitArg(1, func, Arg.UseDef, FP, 64);
1763             break;
1764         default:
1765             throw new Error("Bad overload");
1766             break;
1767         }
1768         break;
1769     case AddFloat:
1770         switch (inst.args.length) {
1771         case 3:
1772             inst.visitArg(0, func, Arg.Use, FP, 32);
1773             inst.visitArg(1, func, Arg.Use, FP, 32);
1774             inst.visitArg(2, func, Arg.Def, FP, 32);
1775             break;
1776         case 2:
1777             inst.visitArg(0, func, Arg.Use, FP, 32);
1778             inst.visitArg(1, func, Arg.UseDef, FP, 32);
1779             break;
1780         default:
1781             throw new Error("Bad overload");
1782             break;
1783         }
1784         break;
1785     case Sub32:
1786         inst.visitArg(0, func, Arg.Use, GP, 32);
1787         inst.visitArg(1, func, Arg.UseZDef, GP, 32);
1788         break;
1789         break;
1790     case Sub64:
1791         inst.visitArg(0, func, Arg.Use, GP, 64);
1792         inst.visitArg(1, func, Arg.UseDef, GP, 64);
1793         break;
1794         break;
1795     case SubDouble:
1796         switch (inst.args.length) {
1797         case 3:
1798             inst.visitArg(0, func, Arg.Use, FP, 64);
1799             inst.visitArg(1, func, Arg.Use, FP, 64);
1800             inst.visitArg(2, func, Arg.Def, FP, 64);
1801             break;
1802         case 2:
1803             inst.visitArg(0, func, Arg.Use, FP, 64);
1804             inst.visitArg(1, func, Arg.UseDef, FP, 64);
1805             break;
1806         default:
1807             throw new Error("Bad overload");
1808             break;
1809         }
1810         break;
1811     case SubFloat:
1812         switch (inst.args.length) {
1813         case 3:
1814             inst.visitArg(0, func, Arg.Use, FP, 32);
1815             inst.visitArg(1, func, Arg.Use, FP, 32);
1816             inst.visitArg(2, func, Arg.Def, FP, 32);
1817             break;
1818         case 2:
1819             inst.visitArg(0, func, Arg.Use, FP, 32);
1820             inst.visitArg(1, func, Arg.UseDef, FP, 32);
1821             break;
1822         default:
1823             throw new Error("Bad overload");
1824             break;
1825         }
1826         break;
1827     case Neg32:
1828         inst.visitArg(0, func, Arg.UseZDef, GP, 32);
1829         break;
1830         break;
1831     case Neg64:
1832         inst.visitArg(0, func, Arg.UseDef, GP, 64);
1833         break;
1834         break;
1835     case NegateDouble:
1836         inst.visitArg(0, func, Arg.Use, FP, 64);
1837         inst.visitArg(1, func, Arg.Def, FP, 64);
1838         break;
1839         break;
1840     case Mul32:
1841         switch (inst.args.length) {
1842         case 2:
1843             inst.visitArg(0, func, Arg.Use, GP, 32);
1844             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
1845             break;
1846         case 3:
1847             inst.visitArg(0, func, Arg.Use, GP, 32);
1848             inst.visitArg(1, func, Arg.Use, GP, 32);
1849             inst.visitArg(2, func, Arg.ZDef, GP, 32);
1850             break;
1851         default:
1852             throw new Error("Bad overload");
1853             break;
1854         }
1855         break;
1856     case Mul64:
1857         switch (inst.args.length) {
1858         case 2:
1859             inst.visitArg(0, func, Arg.Use, GP, 64);
1860             inst.visitArg(1, func, Arg.UseDef, GP, 64);
1861             break;
1862         case 3:
1863             inst.visitArg(0, func, Arg.Use, GP, 64);
1864             inst.visitArg(1, func, Arg.Use, GP, 64);
1865             inst.visitArg(2, func, Arg.Def, GP, 64);
1866             break;
1867         default:
1868             throw new Error("Bad overload");
1869             break;
1870         }
1871         break;
1872     case MultiplyAdd32:
1873         inst.visitArg(0, func, Arg.Use, GP, 32);
1874         inst.visitArg(1, func, Arg.Use, GP, 32);
1875         inst.visitArg(2, func, Arg.Use, GP, 32);
1876         inst.visitArg(3, func, Arg.ZDef, GP, 32);
1877         break;
1878         break;
1879     case MultiplyAdd64:
1880         inst.visitArg(0, func, Arg.Use, GP, 64);
1881         inst.visitArg(1, func, Arg.Use, GP, 64);
1882         inst.visitArg(2, func, Arg.Use, GP, 64);
1883         inst.visitArg(3, func, Arg.Def, GP, 64);
1884         break;
1885         break;
1886     case MultiplySub32:
1887         inst.visitArg(0, func, Arg.Use, GP, 32);
1888         inst.visitArg(1, func, Arg.Use, GP, 32);
1889         inst.visitArg(2, func, Arg.Use, GP, 32);
1890         inst.visitArg(3, func, Arg.ZDef, GP, 32);
1891         break;
1892         break;
1893     case MultiplySub64:
1894         inst.visitArg(0, func, Arg.Use, GP, 64);
1895         inst.visitArg(1, func, Arg.Use, GP, 64);
1896         inst.visitArg(2, func, Arg.Use, GP, 64);
1897         inst.visitArg(3, func, Arg.Def, GP, 64);
1898         break;
1899         break;
1900     case MultiplyNeg32:
1901         inst.visitArg(0, func, Arg.Use, GP, 32);
1902         inst.visitArg(1, func, Arg.Use, GP, 32);
1903         inst.visitArg(2, func, Arg.ZDef, GP, 32);
1904         break;
1905         break;
1906     case MultiplyNeg64:
1907         inst.visitArg(0, func, Arg.Use, GP, 64);
1908         inst.visitArg(1, func, Arg.Use, GP, 64);
1909         inst.visitArg(2, func, Arg.ZDef, GP, 64);
1910         break;
1911         break;
1912     case Div32:
1913         inst.visitArg(0, func, Arg.Use, GP, 32);
1914         inst.visitArg(1, func, Arg.Use, GP, 32);
1915         inst.visitArg(2, func, Arg.ZDef, GP, 32);
1916         break;
1917         break;
1918     case Div64:
1919         inst.visitArg(0, func, Arg.Use, GP, 64);
1920         inst.visitArg(1, func, Arg.Use, GP, 64);
1921         inst.visitArg(2, func, Arg.Def, GP, 64);
1922         break;
1923         break;
1924     case MulDouble:
1925         switch (inst.args.length) {
1926         case 3:
1927             inst.visitArg(0, func, Arg.Use, FP, 64);
1928             inst.visitArg(1, func, Arg.Use, FP, 64);
1929             inst.visitArg(2, func, Arg.Def, FP, 64);
1930             break;
1931         case 2:
1932             inst.visitArg(0, func, Arg.Use, FP, 64);
1933             inst.visitArg(1, func, Arg.UseDef, FP, 64);
1934             break;
1935         default:
1936             throw new Error("Bad overload");
1937             break;
1938         }
1939         break;
1940     case MulFloat:
1941         switch (inst.args.length) {
1942         case 3:
1943             inst.visitArg(0, func, Arg.Use, FP, 32);
1944             inst.visitArg(1, func, Arg.Use, FP, 32);
1945             inst.visitArg(2, func, Arg.Def, FP, 32);
1946             break;
1947         case 2:
1948             inst.visitArg(0, func, Arg.Use, FP, 32);
1949             inst.visitArg(1, func, Arg.UseDef, FP, 32);
1950             break;
1951         default:
1952             throw new Error("Bad overload");
1953             break;
1954         }
1955         break;
1956     case DivDouble:
1957         switch (inst.args.length) {
1958         case 3:
1959             inst.visitArg(0, func, Arg.Use, FP, 64);
1960             inst.visitArg(1, func, Arg.Use, FP, 32);
1961             inst.visitArg(2, func, Arg.Def, FP, 64);
1962             break;
1963         case 2:
1964             inst.visitArg(0, func, Arg.Use, FP, 64);
1965             inst.visitArg(1, func, Arg.UseDef, FP, 64);
1966             break;
1967         default:
1968             throw new Error("Bad overload");
1969             break;
1970         }
1971         break;
1972     case DivFloat:
1973         switch (inst.args.length) {
1974         case 3:
1975             inst.visitArg(0, func, Arg.Use, FP, 32);
1976             inst.visitArg(1, func, Arg.Use, FP, 32);
1977             inst.visitArg(2, func, Arg.Def, FP, 32);
1978             break;
1979         case 2:
1980             inst.visitArg(0, func, Arg.Use, FP, 32);
1981             inst.visitArg(1, func, Arg.UseDef, FP, 32);
1982             break;
1983         default:
1984             throw new Error("Bad overload");
1985             break;
1986         }
1987         break;
1988     case X86ConvertToDoubleWord32:
1989         inst.visitArg(0, func, Arg.Use, GP, 32);
1990         inst.visitArg(1, func, Arg.ZDef, GP, 32);
1991         break;
1992         break;
1993     case X86ConvertToQuadWord64:
1994         inst.visitArg(0, func, Arg.Use, GP, 64);
1995         inst.visitArg(1, func, Arg.Def, GP, 64);
1996         break;
1997         break;
1998     case X86Div32:
1999         inst.visitArg(0, func, Arg.UseZDef, GP, 32);
2000         inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2001         inst.visitArg(2, func, Arg.Use, GP, 32);
2002         break;
2003         break;
2004     case X86Div64:
2005         inst.visitArg(0, func, Arg.UseZDef, GP, 64);
2006         inst.visitArg(1, func, Arg.UseZDef, GP, 64);
2007         inst.visitArg(2, func, Arg.Use, GP, 64);
2008         break;
2009         break;
2010     case Lea:
2011         inst.visitArg(0, func, Arg.UseAddr, GP, Ptr);
2012         inst.visitArg(1, func, Arg.Def, GP, Ptr);
2013         break;
2014         break;
2015     case And32:
2016         switch (inst.args.length) {
2017         case 3:
2018             inst.visitArg(0, func, Arg.Use, GP, 32);
2019             inst.visitArg(1, func, Arg.Use, GP, 32);
2020             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2021             break;
2022         case 2:
2023             inst.visitArg(0, func, Arg.Use, GP, 32);
2024             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2025             break;
2026         default:
2027             throw new Error("Bad overload");
2028             break;
2029         }
2030         break;
2031     case And64:
2032         switch (inst.args.length) {
2033         case 3:
2034             inst.visitArg(0, func, Arg.Use, GP, 64);
2035             inst.visitArg(1, func, Arg.Use, GP, 64);
2036             inst.visitArg(2, func, Arg.Def, GP, 64);
2037             break;
2038         case 2:
2039             inst.visitArg(0, func, Arg.Use, GP, 64);
2040             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2041             break;
2042         default:
2043             throw new Error("Bad overload");
2044             break;
2045         }
2046         break;
2047     case AndDouble:
2048         switch (inst.args.length) {
2049         case 3:
2050             inst.visitArg(0, func, Arg.Use, FP, 64);
2051             inst.visitArg(1, func, Arg.Use, FP, 64);
2052             inst.visitArg(2, func, Arg.Def, FP, 64);
2053             break;
2054         case 2:
2055             inst.visitArg(0, func, Arg.Use, FP, 64);
2056             inst.visitArg(1, func, Arg.UseDef, FP, 64);
2057             break;
2058         default:
2059             throw new Error("Bad overload");
2060             break;
2061         }
2062         break;
2063     case AndFloat:
2064         switch (inst.args.length) {
2065         case 3:
2066             inst.visitArg(0, func, Arg.Use, FP, 32);
2067             inst.visitArg(1, func, Arg.Use, FP, 32);
2068             inst.visitArg(2, func, Arg.Def, FP, 32);
2069             break;
2070         case 2:
2071             inst.visitArg(0, func, Arg.Use, FP, 32);
2072             inst.visitArg(1, func, Arg.UseDef, FP, 32);
2073             break;
2074         default:
2075             throw new Error("Bad overload");
2076             break;
2077         }
2078         break;
2079     case XorDouble:
2080         switch (inst.args.length) {
2081         case 3:
2082             inst.visitArg(0, func, Arg.Use, FP, 64);
2083             inst.visitArg(1, func, Arg.Use, FP, 64);
2084             inst.visitArg(2, func, Arg.Def, FP, 64);
2085             break;
2086         case 2:
2087             inst.visitArg(0, func, Arg.Use, FP, 64);
2088             inst.visitArg(1, func, Arg.UseDef, FP, 64);
2089             break;
2090         default:
2091             throw new Error("Bad overload");
2092             break;
2093         }
2094         break;
2095     case XorFloat:
2096         switch (inst.args.length) {
2097         case 3:
2098             inst.visitArg(0, func, Arg.Use, FP, 32);
2099             inst.visitArg(1, func, Arg.Use, FP, 32);
2100             inst.visitArg(2, func, Arg.Def, FP, 32);
2101             break;
2102         case 2:
2103             inst.visitArg(0, func, Arg.Use, FP, 32);
2104             inst.visitArg(1, func, Arg.UseDef, FP, 32);
2105             break;
2106         default:
2107             throw new Error("Bad overload");
2108             break;
2109         }
2110         break;
2111     case Lshift32:
2112         switch (inst.args.length) {
2113         case 3:
2114             inst.visitArg(0, func, Arg.Use, GP, 32);
2115             inst.visitArg(1, func, Arg.Use, GP, 32);
2116             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2117             break;
2118         case 2:
2119             inst.visitArg(0, func, Arg.Use, GP, 32);
2120             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2121             break;
2122         default:
2123             throw new Error("Bad overload");
2124             break;
2125         }
2126         break;
2127     case Lshift64:
2128         switch (inst.args.length) {
2129         case 3:
2130             inst.visitArg(0, func, Arg.Use, GP, 64);
2131             inst.visitArg(1, func, Arg.Use, GP, 64);
2132             inst.visitArg(2, func, Arg.ZDef, GP, 64);
2133             break;
2134         case 2:
2135             inst.visitArg(0, func, Arg.Use, GP, 64);
2136             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2137             break;
2138         default:
2139             throw new Error("Bad overload");
2140             break;
2141         }
2142         break;
2143     case Rshift32:
2144         switch (inst.args.length) {
2145         case 3:
2146             inst.visitArg(0, func, Arg.Use, GP, 32);
2147             inst.visitArg(1, func, Arg.Use, GP, 32);
2148             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2149             break;
2150         case 2:
2151             inst.visitArg(0, func, Arg.Use, GP, 32);
2152             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2153             break;
2154         default:
2155             throw new Error("Bad overload");
2156             break;
2157         }
2158         break;
2159     case Rshift64:
2160         switch (inst.args.length) {
2161         case 3:
2162             inst.visitArg(0, func, Arg.Use, GP, 64);
2163             inst.visitArg(1, func, Arg.Use, GP, 64);
2164             inst.visitArg(2, func, Arg.ZDef, GP, 64);
2165             break;
2166         case 2:
2167             inst.visitArg(0, func, Arg.Use, GP, 64);
2168             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2169             break;
2170         default:
2171             throw new Error("Bad overload");
2172             break;
2173         }
2174         break;
2175     case Urshift32:
2176         switch (inst.args.length) {
2177         case 3:
2178             inst.visitArg(0, func, Arg.Use, GP, 32);
2179             inst.visitArg(1, func, Arg.Use, GP, 32);
2180             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2181             break;
2182         case 2:
2183             inst.visitArg(0, func, Arg.Use, GP, 32);
2184             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2185             break;
2186         default:
2187             throw new Error("Bad overload");
2188             break;
2189         }
2190         break;
2191     case Urshift64:
2192         switch (inst.args.length) {
2193         case 3:
2194             inst.visitArg(0, func, Arg.Use, GP, 64);
2195             inst.visitArg(1, func, Arg.Use, GP, 64);
2196             inst.visitArg(2, func, Arg.ZDef, GP, 64);
2197             break;
2198         case 2:
2199             inst.visitArg(0, func, Arg.Use, GP, 64);
2200             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2201             break;
2202         default:
2203             throw new Error("Bad overload");
2204             break;
2205         }
2206         break;
2207     case Or32:
2208         switch (inst.args.length) {
2209         case 3:
2210             inst.visitArg(0, func, Arg.Use, GP, 32);
2211             inst.visitArg(1, func, Arg.Use, GP, 32);
2212             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2213             break;
2214         case 2:
2215             inst.visitArg(0, func, Arg.Use, GP, 32);
2216             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2217             break;
2218         default:
2219             throw new Error("Bad overload");
2220             break;
2221         }
2222         break;
2223     case Or64:
2224         switch (inst.args.length) {
2225         case 3:
2226             inst.visitArg(0, func, Arg.Use, GP, 64);
2227             inst.visitArg(1, func, Arg.Use, GP, 64);
2228             inst.visitArg(2, func, Arg.Def, GP, 64);
2229             break;
2230         case 2:
2231             inst.visitArg(0, func, Arg.Use, GP, 64);
2232             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2233             break;
2234         default:
2235             throw new Error("Bad overload");
2236             break;
2237         }
2238         break;
2239     case Xor32:
2240         switch (inst.args.length) {
2241         case 3:
2242             inst.visitArg(0, func, Arg.Use, GP, 32);
2243             inst.visitArg(1, func, Arg.Use, GP, 32);
2244             inst.visitArg(2, func, Arg.ZDef, GP, 32);
2245             break;
2246         case 2:
2247             inst.visitArg(0, func, Arg.Use, GP, 32);
2248             inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2249             break;
2250         default:
2251             throw new Error("Bad overload");
2252             break;
2253         }
2254         break;
2255     case Xor64:
2256         switch (inst.args.length) {
2257         case 3:
2258             inst.visitArg(0, func, Arg.Use, GP, 64);
2259             inst.visitArg(1, func, Arg.Use, GP, 64);
2260             inst.visitArg(2, func, Arg.Def, GP, 64);
2261             break;
2262         case 2:
2263             inst.visitArg(0, func, Arg.Use, GP, 64);
2264             inst.visitArg(1, func, Arg.UseDef, GP, 64);
2265             break;
2266         default:
2267             throw new Error("Bad overload");
2268             break;
2269         }
2270         break;
2271     case Not32:
2272         switch (inst.args.length) {
2273         case 2:
2274             inst.visitArg(0, func, Arg.Use, GP, 32);
2275             inst.visitArg(1, func, Arg.ZDef, GP, 32);
2276             break;
2277         case 1:
2278             inst.visitArg(0, func, Arg.UseZDef, GP, 32);
2279             break;
2280         default:
2281             throw new Error("Bad overload");
2282             break;
2283         }
2284         break;
2285     case Not64:
2286         switch (inst.args.length) {
2287         case 2:
2288             inst.visitArg(0, func, Arg.Use, GP, 64);
2289             inst.visitArg(1, func, Arg.Def, GP, 64);
2290             break;
2291         case 1:
2292             inst.visitArg(0, func, Arg.UseDef, GP, 64);
2293             break;
2294         default:
2295             throw new Error("Bad overload");
2296             break;
2297         }
2298         break;
2299     case AbsDouble:
2300         inst.visitArg(0, func, Arg.Use, FP, 64);
2301         inst.visitArg(1, func, Arg.Def, FP, 64);
2302         break;
2303         break;
2304     case AbsFloat:
2305         inst.visitArg(0, func, Arg.Use, FP, 32);
2306         inst.visitArg(1, func, Arg.Def, FP, 32);
2307         break;
2308         break;
2309     case CeilDouble:
2310         inst.visitArg(0, func, Arg.Use, FP, 64);
2311         inst.visitArg(1, func, Arg.Def, FP, 64);
2312         break;
2313         break;
2314     case CeilFloat:
2315         inst.visitArg(0, func, Arg.Use, FP, 32);
2316         inst.visitArg(1, func, Arg.Def, FP, 32);
2317         break;
2318         break;
2319     case FloorDouble:
2320         inst.visitArg(0, func, Arg.Use, FP, 64);
2321         inst.visitArg(1, func, Arg.Def, FP, 64);
2322         break;
2323         break;
2324     case FloorFloat:
2325         inst.visitArg(0, func, Arg.Use, FP, 32);
2326         inst.visitArg(1, func, Arg.Def, FP, 32);
2327         break;
2328         break;
2329     case SqrtDouble:
2330         inst.visitArg(0, func, Arg.Use, FP, 64);
2331         inst.visitArg(1, func, Arg.Def, FP, 64);
2332         break;
2333         break;
2334     case SqrtFloat:
2335         inst.visitArg(0, func, Arg.Use, FP, 32);
2336         inst.visitArg(1, func, Arg.Def, FP, 32);
2337         break;
2338         break;
2339     case ConvertInt32ToDouble:
2340         inst.visitArg(0, func, Arg.Use, GP, 32);
2341         inst.visitArg(1, func, Arg.Def, FP, 64);
2342         break;
2343         break;
2344     case ConvertInt64ToDouble:
2345         inst.visitArg(0, func, Arg.Use, GP, 64);
2346         inst.visitArg(1, func, Arg.Def, FP, 64);
2347         break;
2348         break;
2349     case ConvertInt32ToFloat:
2350         inst.visitArg(0, func, Arg.Use, GP, 32);
2351         inst.visitArg(1, func, Arg.Def, FP, 32);
2352         break;
2353         break;
2354     case ConvertInt64ToFloat:
2355         inst.visitArg(0, func, Arg.Use, GP, 64);
2356         inst.visitArg(1, func, Arg.Def, FP, 32);
2357         break;
2358         break;
2359     case CountLeadingZeros32:
2360         inst.visitArg(0, func, Arg.Use, GP, 32);
2361         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2362         break;
2363         break;
2364     case CountLeadingZeros64:
2365         inst.visitArg(0, func, Arg.Use, GP, 64);
2366         inst.visitArg(1, func, Arg.Def, GP, 64);
2367         break;
2368         break;
2369     case ConvertDoubleToFloat:
2370         inst.visitArg(0, func, Arg.Use, FP, 64);
2371         inst.visitArg(1, func, Arg.Def, FP, 32);
2372         break;
2373         break;
2374     case ConvertFloatToDouble:
2375         inst.visitArg(0, func, Arg.Use, FP, 32);
2376         inst.visitArg(1, func, Arg.Def, FP, 64);
2377         break;
2378         break;
2379     case Move:
2380         inst.visitArg(0, func, Arg.Use, GP, Ptr);
2381         inst.visitArg(1, func, Arg.Def, GP, Ptr);
2382         break;
2383         break;
2384     case Swap32:
2385         inst.visitArg(0, func, Arg.UseDef, GP, 32);
2386         inst.visitArg(1, func, Arg.UseDef, GP, 32);
2387         break;
2388         break;
2389     case Swap64:
2390         inst.visitArg(0, func, Arg.UseDef, GP, 64);
2391         inst.visitArg(1, func, Arg.UseDef, GP, 64);
2392         break;
2393         break;
2394     case Move32:
2395         inst.visitArg(0, func, Arg.Use, GP, 32);
2396         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2397         break;
2398         break;
2399     case StoreZero32:
2400         inst.visitArg(0, func, Arg.Use, GP, 32);
2401         break;
2402         break;
2403     case SignExtend32ToPtr:
2404         inst.visitArg(0, func, Arg.Use, GP, 32);
2405         inst.visitArg(1, func, Arg.Def, GP, Ptr);
2406         break;
2407         break;
2408     case ZeroExtend8To32:
2409         inst.visitArg(0, func, Arg.Use, GP, 8);
2410         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2411         break;
2412         break;
2413     case SignExtend8To32:
2414         inst.visitArg(0, func, Arg.Use, GP, 8);
2415         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2416         break;
2417         break;
2418     case ZeroExtend16To32:
2419         inst.visitArg(0, func, Arg.Use, GP, 16);
2420         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2421         break;
2422         break;
2423     case SignExtend16To32:
2424         inst.visitArg(0, func, Arg.Use, GP, 16);
2425         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2426         break;
2427         break;
2428     case MoveFloat:
2429         inst.visitArg(0, func, Arg.Use, FP, 32);
2430         inst.visitArg(1, func, Arg.Def, FP, 32);
2431         break;
2432         break;
2433     case MoveDouble:
2434         inst.visitArg(0, func, Arg.Use, FP, 64);
2435         inst.visitArg(1, func, Arg.Def, FP, 64);
2436         break;
2437         break;
2438     case MoveZeroToDouble:
2439         inst.visitArg(0, func, Arg.Def, FP, 64);
2440         break;
2441         break;
2442     case Move64ToDouble:
2443         inst.visitArg(0, func, Arg.Use, GP, 64);
2444         inst.visitArg(1, func, Arg.Def, FP, 64);
2445         break;
2446         break;
2447     case Move32ToFloat:
2448         inst.visitArg(0, func, Arg.Use, GP, 32);
2449         inst.visitArg(1, func, Arg.Def, FP, 32);
2450         break;
2451         break;
2452     case MoveDoubleTo64:
2453         inst.visitArg(0, func, Arg.Use, FP, 64);
2454         inst.visitArg(1, func, Arg.Def, GP, 64);
2455         break;
2456         break;
2457     case MoveFloatTo32:
2458         inst.visitArg(0, func, Arg.Use, FP, 32);
2459         inst.visitArg(1, func, Arg.Def, GP, 32);
2460         break;
2461         break;
2462     case Load8:
2463         inst.visitArg(0, func, Arg.Use, GP, 8);
2464         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2465         break;
2466         break;
2467     case Store8:
2468         inst.visitArg(0, func, Arg.Use, GP, 8);
2469         inst.visitArg(1, func, Arg.Def, GP, 8);
2470         break;
2471         break;
2472     case Load8SignedExtendTo32:
2473         inst.visitArg(0, func, Arg.Use, GP, 8);
2474         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2475         break;
2476         break;
2477     case Load16:
2478         inst.visitArg(0, func, Arg.Use, GP, 16);
2479         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2480         break;
2481         break;
2482     case Load16SignedExtendTo32:
2483         inst.visitArg(0, func, Arg.Use, GP, 16);
2484         inst.visitArg(1, func, Arg.ZDef, GP, 32);
2485         break;
2486         break;
2487     case Store16:
2488         inst.visitArg(0, func, Arg.Use, GP, 16);
2489         inst.visitArg(1, func, Arg.Def, GP, 16);
2490         break;
2491         break;
2492     case Compare32:
2493         inst.visitArg(0, func, Arg.Use, GP, 32);
2494         inst.visitArg(1, func, Arg.Use, GP, 32);
2495         inst.visitArg(2, func, Arg.Use, GP, 32);
2496         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2497         break;
2498         break;
2499     case Compare64:
2500         inst.visitArg(0, func, Arg.Use, GP, 32);
2501         inst.visitArg(1, func, Arg.Use, GP, 64);
2502         inst.visitArg(2, func, Arg.Use, GP, 64);
2503         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2504         break;
2505         break;
2506     case Test32:
2507         inst.visitArg(0, func, Arg.Use, GP, 32);
2508         inst.visitArg(1, func, Arg.Use, GP, 32);
2509         inst.visitArg(2, func, Arg.Use, GP, 32);
2510         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2511         break;
2512         break;
2513     case Test64:
2514         inst.visitArg(0, func, Arg.Use, GP, 32);
2515         inst.visitArg(1, func, Arg.Use, GP, 64);
2516         inst.visitArg(2, func, Arg.Use, GP, 64);
2517         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2518         break;
2519         break;
2520     case CompareDouble:
2521         inst.visitArg(0, func, Arg.Use, GP, 32);
2522         inst.visitArg(1, func, Arg.Use, FP, 64);
2523         inst.visitArg(2, func, Arg.Use, FP, 64);
2524         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2525         break;
2526         break;
2527     case CompareFloat:
2528         inst.visitArg(0, func, Arg.Use, GP, 32);
2529         inst.visitArg(1, func, Arg.Use, FP, 32);
2530         inst.visitArg(2, func, Arg.Use, FP, 32);
2531         inst.visitArg(3, func, Arg.ZDef, GP, 32);
2532         break;
2533         break;
2534     case Branch8:
2535         inst.visitArg(0, func, Arg.Use, GP, 32);
2536         inst.visitArg(1, func, Arg.Use, GP, 8);
2537         inst.visitArg(2, func, Arg.Use, GP, 8);
2538         break;
2539         break;
2540     case Branch32:
2541         inst.visitArg(0, func, Arg.Use, GP, 32);
2542         inst.visitArg(1, func, Arg.Use, GP, 32);
2543         inst.visitArg(2, func, Arg.Use, GP, 32);
2544         break;
2545         break;
2546     case Branch64:
2547         inst.visitArg(0, func, Arg.Use, GP, 32);
2548         inst.visitArg(1, func, Arg.Use, GP, 64);
2549         inst.visitArg(2, func, Arg.Use, GP, 64);
2550         break;
2551         break;
2552     case BranchTest8:
2553         inst.visitArg(0, func, Arg.Use, GP, 32);
2554         inst.visitArg(1, func, Arg.Use, GP, 8);
2555         inst.visitArg(2, func, Arg.Use, GP, 8);
2556         break;
2557         break;
2558     case BranchTest32:
2559         inst.visitArg(0, func, Arg.Use, GP, 32);
2560         inst.visitArg(1, func, Arg.Use, GP, 32);
2561         inst.visitArg(2, func, Arg.Use, GP, 32);
2562         break;
2563         break;
2564     case BranchTest64:
2565         inst.visitArg(0, func, Arg.Use, GP, 32);
2566         inst.visitArg(1, func, Arg.Use, GP, 64);
2567         inst.visitArg(2, func, Arg.Use, GP, 64);
2568         break;
2569         break;
2570     case BranchDouble:
2571         inst.visitArg(0, func, Arg.Use, GP, 32);
2572         inst.visitArg(1, func, Arg.Use, FP, 64);
2573         inst.visitArg(2, func, Arg.Use, FP, 64);
2574         break;
2575         break;
2576     case BranchFloat:
2577         inst.visitArg(0, func, Arg.Use, GP, 32);
2578         inst.visitArg(1, func, Arg.Use, FP, 32);
2579         inst.visitArg(2, func, Arg.Use, FP, 32);
2580         break;
2581         break;
2582     case BranchAdd32:
2583         switch (inst.args.length) {
2584         case 4:
2585             inst.visitArg(0, func, Arg.Use, GP, 32);
2586             inst.visitArg(1, func, Arg.Use, GP, 32);
2587             inst.visitArg(2, func, Arg.Use, GP, 32);
2588             inst.visitArg(3, func, Arg.ZDef, GP, 32);
2589             break;
2590         case 3:
2591             inst.visitArg(0, func, Arg.Use, GP, 32);
2592             inst.visitArg(1, func, Arg.Use, GP, 32);
2593             inst.visitArg(2, func, Arg.UseZDef, GP, 32);
2594             break;
2595         default:
2596             throw new Error("Bad overload");
2597             break;
2598         }
2599         break;
2600     case BranchAdd64:
2601         switch (inst.args.length) {
2602         case 4:
2603             inst.visitArg(0, func, Arg.Use, GP, 32);
2604             inst.visitArg(1, func, Arg.Use, GP, 64);
2605             inst.visitArg(2, func, Arg.Use, GP, 64);
2606             inst.visitArg(3, func, Arg.ZDef, GP, 64);
2607             break;
2608         case 3:
2609             inst.visitArg(0, func, Arg.Use, GP, 32);
2610             inst.visitArg(1, func, Arg.Use, GP, 64);
2611             inst.visitArg(2, func, Arg.UseDef, GP, 64);
2612             break;
2613         default:
2614             throw new Error("Bad overload");
2615             break;
2616         }
2617         break;
2618     case BranchMul32:
2619         switch (inst.args.length) {
2620         case 3:
2621             inst.visitArg(0, func, Arg.Use, GP, 32);
2622             inst.visitArg(1, func, Arg.Use, GP, 32);
2623             inst.visitArg(2, func, Arg.UseZDef, GP, 32);
2624             break;
2625         case 4:
2626             inst.visitArg(0, func, Arg.Use, GP, 32);
2627             inst.visitArg(1, func, Arg.Use, GP, 32);
2628             inst.visitArg(2, func, Arg.Use, GP, 32);
2629             inst.visitArg(3, func, Arg.ZDef, GP, 32);
2630             break;
2631         case 6:
2632             inst.visitArg(0, func, Arg.Use, GP, 32);
2633             inst.visitArg(1, func, Arg.Use, GP, 32);
2634             inst.visitArg(2, func, Arg.Use, GP, 32);
2635             inst.visitArg(3, func, Arg.Scratch, GP, 32);
2636             inst.visitArg(4, func, Arg.Scratch, GP, 32);
2637             inst.visitArg(5, func, Arg.ZDef, GP, 32);
2638             break;
2639         default:
2640             throw new Error("Bad overload");
2641             break;
2642         }
2643         break;
2644     case BranchMul64:
2645         switch (inst.args.length) {
2646         case 3:
2647             inst.visitArg(0, func, Arg.Use, GP, 32);
2648             inst.visitArg(1, func, Arg.Use, GP, 64);
2649             inst.visitArg(2, func, Arg.UseZDef, GP, 64);
2650             break;
2651         case 6:
2652             inst.visitArg(0, func, Arg.Use, GP, 32);
2653             inst.visitArg(1, func, Arg.Use, GP, 64);
2654             inst.visitArg(2, func, Arg.Use, GP, 64);
2655             inst.visitArg(3, func, Arg.Scratch, GP, 64);
2656             inst.visitArg(4, func, Arg.Scratch, GP, 64);
2657             inst.visitArg(5, func, Arg.ZDef, GP, 64);
2658             break;
2659         default:
2660             throw new Error("Bad overload");
2661             break;
2662         }
2663         break;
2664     case BranchSub32:
2665         inst.visitArg(0, func, Arg.Use, GP, 32);
2666         inst.visitArg(1, func, Arg.Use, GP, 32);
2667         inst.visitArg(2, func, Arg.UseZDef, GP, 32);
2668         break;
2669         break;
2670     case BranchSub64:
2671         inst.visitArg(0, func, Arg.Use, GP, 32);
2672         inst.visitArg(1, func, Arg.Use, GP, 64);
2673         inst.visitArg(2, func, Arg.UseDef, GP, 64);
2674         break;
2675         break;
2676     case BranchNeg32:
2677         inst.visitArg(0, func, Arg.Use, GP, 32);
2678         inst.visitArg(1, func, Arg.UseZDef, GP, 32);
2679         break;
2680         break;
2681     case BranchNeg64:
2682         inst.visitArg(0, func, Arg.Use, GP, 32);
2683         inst.visitArg(1, func, Arg.UseZDef, GP, 64);
2684         break;
2685         break;
2686     case MoveConditionally32:
2687         switch (inst.args.length) {
2688         case 5:
2689             inst.visitArg(0, func, Arg.Use, GP, 32);
2690             inst.visitArg(1, func, Arg.Use, GP, 32);
2691             inst.visitArg(2, func, Arg.Use, GP, 32);
2692             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2693             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2694             break;
2695         case 6:
2696             inst.visitArg(0, func, Arg.Use, GP, 32);
2697             inst.visitArg(1, func, Arg.Use, GP, 32);
2698             inst.visitArg(2, func, Arg.Use, GP, 32);
2699             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2700             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2701             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2702             break;
2703         default:
2704             throw new Error("Bad overload");
2705             break;
2706         }
2707         break;
2708     case MoveConditionally64:
2709         switch (inst.args.length) {
2710         case 5:
2711             inst.visitArg(0, func, Arg.Use, GP, 32);
2712             inst.visitArg(1, func, Arg.Use, GP, 64);
2713             inst.visitArg(2, func, Arg.Use, GP, 64);
2714             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2715             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2716             break;
2717         case 6:
2718             inst.visitArg(0, func, Arg.Use, GP, 32);
2719             inst.visitArg(1, func, Arg.Use, GP, 64);
2720             inst.visitArg(2, func, Arg.Use, GP, 64);
2721             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2722             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2723             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2724             break;
2725         default:
2726             throw new Error("Bad overload");
2727             break;
2728         }
2729         break;
2730     case MoveConditionallyTest32:
2731         switch (inst.args.length) {
2732         case 5:
2733             inst.visitArg(0, func, Arg.Use, GP, 32);
2734             inst.visitArg(1, func, Arg.Use, GP, 32);
2735             inst.visitArg(2, func, Arg.Use, GP, 32);
2736             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2737             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2738             break;
2739         case 6:
2740             inst.visitArg(0, func, Arg.Use, GP, 32);
2741             inst.visitArg(1, func, Arg.Use, GP, 32);
2742             inst.visitArg(2, func, Arg.Use, GP, 32);
2743             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2744             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2745             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2746             break;
2747         default:
2748             throw new Error("Bad overload");
2749             break;
2750         }
2751         break;
2752     case MoveConditionallyTest64:
2753         switch (inst.args.length) {
2754         case 5:
2755             inst.visitArg(0, func, Arg.Use, GP, 32);
2756             inst.visitArg(1, func, Arg.Use, GP, 64);
2757             inst.visitArg(2, func, Arg.Use, GP, 64);
2758             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2759             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2760             break;
2761         case 6:
2762             inst.visitArg(0, func, Arg.Use, GP, 32);
2763             inst.visitArg(1, func, Arg.Use, GP, 32);
2764             inst.visitArg(2, func, Arg.Use, GP, 32);
2765             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2766             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2767             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2768             break;
2769         default:
2770             throw new Error("Bad overload");
2771             break;
2772         }
2773         break;
2774     case MoveConditionallyDouble:
2775         switch (inst.args.length) {
2776         case 6:
2777             inst.visitArg(0, func, Arg.Use, GP, 32);
2778             inst.visitArg(1, func, Arg.Use, FP, 64);
2779             inst.visitArg(2, func, Arg.Use, FP, 64);
2780             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2781             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2782             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2783             break;
2784         case 5:
2785             inst.visitArg(0, func, Arg.Use, GP, 32);
2786             inst.visitArg(1, func, Arg.Use, FP, 64);
2787             inst.visitArg(2, func, Arg.Use, FP, 64);
2788             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2789             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2790             break;
2791         default:
2792             throw new Error("Bad overload");
2793             break;
2794         }
2795         break;
2796     case MoveConditionallyFloat:
2797         switch (inst.args.length) {
2798         case 6:
2799             inst.visitArg(0, func, Arg.Use, GP, 32);
2800             inst.visitArg(1, func, Arg.Use, FP, 32);
2801             inst.visitArg(2, func, Arg.Use, FP, 32);
2802             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2803             inst.visitArg(4, func, Arg.Use, GP, Ptr);
2804             inst.visitArg(5, func, Arg.Def, GP, Ptr);
2805             break;
2806         case 5:
2807             inst.visitArg(0, func, Arg.Use, GP, 32);
2808             inst.visitArg(1, func, Arg.Use, FP, 32);
2809             inst.visitArg(2, func, Arg.Use, FP, 32);
2810             inst.visitArg(3, func, Arg.Use, GP, Ptr);
2811             inst.visitArg(4, func, Arg.UseDef, GP, Ptr);
2812             break;
2813         default:
2814             throw new Error("Bad overload");
2815             break;
2816         }
2817         break;
2818     case MoveDoubleConditionally32:
2819         inst.visitArg(0, func, Arg.Use, GP, 32);
2820         inst.visitArg(1, func, Arg.Use, GP, 32);
2821         inst.visitArg(2, func, Arg.Use, GP, 32);
2822         inst.visitArg(3, func, Arg.Use, FP, 64);
2823         inst.visitArg(4, func, Arg.Use, FP, 64);
2824         inst.visitArg(5, func, Arg.Def, FP, 64);
2825         break;
2826         break;
2827     case MoveDoubleConditionally64:
2828         inst.visitArg(0, func, Arg.Use, GP, 32);
2829         inst.visitArg(1, func, Arg.Use, GP, 64);
2830         inst.visitArg(2, func, Arg.Use, GP, 64);
2831         inst.visitArg(3, func, Arg.Use, FP, 64);
2832         inst.visitArg(4, func, Arg.Use, FP, 64);
2833         inst.visitArg(5, func, Arg.Def, FP, 64);
2834         break;
2835         break;
2836     case MoveDoubleConditionallyTest32:
2837         inst.visitArg(0, func, Arg.Use, GP, 32);
2838         inst.visitArg(1, func, Arg.Use, GP, 32);
2839         inst.visitArg(2, func, Arg.Use, GP, 32);
2840         inst.visitArg(3, func, Arg.Use, FP, 64);
2841         inst.visitArg(4, func, Arg.Use, FP, 64);
2842         inst.visitArg(5, func, Arg.Def, FP, 64);
2843         break;
2844         break;
2845     case MoveDoubleConditionallyTest64:
2846         inst.visitArg(0, func, Arg.Use, GP, 32);
2847         inst.visitArg(1, func, Arg.Use, GP, 64);
2848         inst.visitArg(2, func, Arg.Use, GP, 64);
2849         inst.visitArg(3, func, Arg.Use, FP, 64);
2850         inst.visitArg(4, func, Arg.Use, FP, 64);
2851         inst.visitArg(5, func, Arg.Def, FP, 64);
2852         break;
2853         break;
2854     case MoveDoubleConditionallyDouble:
2855         inst.visitArg(0, func, Arg.Use, GP, 32);
2856         inst.visitArg(1, func, Arg.Use, FP, 64);
2857         inst.visitArg(2, func, Arg.Use, FP, 64);
2858         inst.visitArg(3, func, Arg.Use, FP, 64);
2859         inst.visitArg(4, func, Arg.Use, FP, 64);
2860         inst.visitArg(5, func, Arg.Def, FP, 64);
2861         break;
2862         break;
2863     case MoveDoubleConditionallyFloat:
2864         inst.visitArg(0, func, Arg.Use, GP, 32);
2865         inst.visitArg(1, func, Arg.Use, FP, 32);
2866         inst.visitArg(2, func, Arg.Use, FP, 32);
2867         inst.visitArg(3, func, Arg.Use, FP, 64);
2868         inst.visitArg(4, func, Arg.Use, FP, 64);
2869         inst.visitArg(5, func, Arg.Def, FP, 64);
2870         break;
2871         break;
2872     case Jump:
2873         break;
2874         break;
2875     case Ret32:
2876         inst.visitArg(0, func, Arg.Use, GP, 32);
2877         break;
2878         break;
2879     case Ret64:
2880         inst.visitArg(0, func, Arg.Use, GP, 64);
2881         break;
2882         break;
2883     case RetFloat:
2884         inst.visitArg(0, func, Arg.Use, FP, 32);
2885         break;
2886         break;
2887     case RetDouble:
2888         inst.visitArg(0, func, Arg.Use, FP, 64);
2889         break;
2890         break;
2891     case Oops:
2892         break;
2893         break;
2894     case Shuffle:
2895         ShuffleCustom.forEachArg(inst, func);
2896         break;
2897     case Patch:
2898         PatchCustom.forEachArg(inst, func);
2899         break;
2900     case CCall:
2901         CCallCustom.forEachArg(inst, func);
2902         break;
2903     case ColdCCall:
2904         ColdCCallCustom.forEachArg(inst, func);
2905         break;
2906     default:
2907         throw "Bad opcode";
2908     }
2909 }
2910 function Inst_hasNonArgEffects(inst)
2911 {
2912     switch (inst.opcode) {
2913     case Branch8:
2914     case Branch32:
2915     case Branch64:
2916     case BranchTest8:
2917     case BranchTest32:
2918     case BranchTest64:
2919     case BranchDouble:
2920     case BranchFloat:
2921     case BranchAdd32:
2922     case BranchAdd64:
2923     case BranchMul32:
2924     case BranchMul64:
2925     case BranchSub32:
2926     case BranchSub64:
2927     case BranchNeg32:
2928     case BranchNeg64:
2929     case Jump:
2930     case Ret32:
2931     case Ret64:
2932     case RetFloat:
2933     case RetDouble:
2934     case Oops:
2935         return true;
2936     case Shuffle:
2937         return ShuffleCustom.hasNonArgNonControlEffects(inst);
2938     case Patch:
2939         return PatchCustom.hasNonArgNonControlEffects(inst);
2940     case CCall:
2941         return CCallCustom.hasNonArgNonControlEffects(inst);
2942     case ColdCCall:
2943         return ColdCCallCustom.hasNonArgNonControlEffects(inst);
2944     default:
2945         return false;
2946     }
2947 }
2948 function opcodeCode(opcode)
2949 {
2950     switch (opcode) {
2951     case AbsDouble:
2952         return 0
2953     case AbsFloat:
2954         return 1
2955     case Add16:
2956         return 2
2957     case Add32:
2958         return 3
2959     case Add64:
2960         return 4
2961     case Add8:
2962         return 5
2963     case AddDouble:
2964         return 6
2965     case AddFloat:
2966         return 7
2967     case And32:
2968         return 8
2969     case And64:
2970         return 9
2971     case AndDouble:
2972         return 10
2973     case AndFloat:
2974         return 11
2975     case Branch32:
2976         return 12
2977     case Branch64:
2978         return 13
2979     case Branch8:
2980         return 14
2981     case BranchAdd32:
2982         return 15
2983     case BranchAdd64:
2984         return 16
2985     case BranchDouble:
2986         return 17
2987     case BranchFloat:
2988         return 18
2989     case BranchMul32:
2990         return 19
2991     case BranchMul64:
2992         return 20
2993     case BranchNeg32:
2994         return 21
2995     case BranchNeg64:
2996         return 22
2997     case BranchSub32:
2998         return 23
2999     case BranchSub64:
3000         return 24
3001     case BranchTest32:
3002         return 25
3003     case BranchTest64:
3004         return 26
3005     case BranchTest8:
3006         return 27
3007     case CCall:
3008         return 28
3009     case CeilDouble:
3010         return 29
3011     case CeilFloat:
3012         return 30
3013     case ColdCCall:
3014         return 31
3015     case Compare32:
3016         return 32
3017     case Compare64:
3018         return 33
3019     case CompareDouble:
3020         return 34
3021     case CompareFloat:
3022         return 35
3023     case ConvertDoubleToFloat:
3024         return 36
3025     case ConvertFloatToDouble:
3026         return 37
3027     case ConvertInt32ToDouble:
3028         return 38
3029     case ConvertInt32ToFloat:
3030         return 39
3031     case ConvertInt64ToDouble:
3032         return 40
3033     case ConvertInt64ToFloat:
3034         return 41
3035     case CountLeadingZeros32:
3036         return 42
3037     case CountLeadingZeros64:
3038         return 43
3039     case Div32:
3040         return 44
3041     case Div64:
3042         return 45
3043     case DivDouble:
3044         return 46
3045     case DivFloat:
3046         return 47
3047     case FloorDouble:
3048         return 48
3049     case FloorFloat:
3050         return 49
3051     case Jump:
3052         return 50
3053     case Lea:
3054         return 51
3055     case Load16:
3056         return 52
3057     case Load16SignedExtendTo32:
3058         return 53
3059     case Load8:
3060         return 54
3061     case Load8SignedExtendTo32:
3062         return 55
3063     case Lshift32:
3064         return 56
3065     case Lshift64:
3066         return 57
3067     case Move:
3068         return 58
3069     case Move32:
3070         return 59
3071     case Move32ToFloat:
3072         return 60
3073     case Move64ToDouble:
3074         return 61
3075     case MoveConditionally32:
3076         return 62
3077     case MoveConditionally64:
3078         return 63
3079     case MoveConditionallyDouble:
3080         return 64
3081     case MoveConditionallyFloat:
3082         return 65
3083     case MoveConditionallyTest32:
3084         return 66
3085     case MoveConditionallyTest64:
3086         return 67
3087     case MoveDouble:
3088         return 68
3089     case MoveDoubleConditionally32:
3090         return 69
3091     case MoveDoubleConditionally64:
3092         return 70
3093     case MoveDoubleConditionallyDouble:
3094         return 71
3095     case MoveDoubleConditionallyFloat:
3096         return 72
3097     case MoveDoubleConditionallyTest32:
3098         return 73
3099     case MoveDoubleConditionallyTest64:
3100         return 74
3101     case MoveDoubleTo64:
3102         return 75
3103     case MoveFloat:
3104         return 76
3105     case MoveFloatTo32:
3106         return 77
3107     case MoveZeroToDouble:
3108         return 78
3109     case Mul32:
3110         return 79
3111     case Mul64:
3112         return 80
3113     case MulDouble:
3114         return 81
3115     case MulFloat:
3116         return 82
3117     case MultiplyAdd32:
3118         return 83
3119     case MultiplyAdd64:
3120         return 84
3121     case MultiplyNeg32:
3122         return 85
3123     case MultiplyNeg64:
3124         return 86
3125     case MultiplySub32:
3126         return 87
3127     case MultiplySub64:
3128         return 88
3129     case Neg32:
3130         return 89
3131     case Neg64:
3132         return 90
3133     case NegateDouble:
3134         return 91
3135     case Nop:
3136         return 92
3137     case Not32:
3138         return 93
3139     case Not64:
3140         return 94
3141     case Oops:
3142         return 95
3143     case Or32:
3144         return 96
3145     case Or64:
3146         return 97
3147     case Patch:
3148         return 98
3149     case Ret32:
3150         return 99
3151     case Ret64:
3152         return 100
3153     case RetDouble:
3154         return 101
3155     case RetFloat:
3156         return 102
3157     case Rshift32:
3158         return 103
3159     case Rshift64:
3160         return 104
3161     case Shuffle:
3162         return 105
3163     case SignExtend16To32:
3164         return 106
3165     case SignExtend32ToPtr:
3166         return 107
3167     case SignExtend8To32:
3168         return 108
3169     case SqrtDouble:
3170         return 109
3171     case SqrtFloat:
3172         return 110
3173     case Store16:
3174         return 111
3175     case Store8:
3176         return 112
3177     case StoreZero32:
3178         return 113
3179     case Sub32:
3180         return 114
3181     case Sub64:
3182         return 115
3183     case SubDouble:
3184         return 116
3185     case SubFloat:
3186         return 117
3187     case Swap32:
3188         return 118
3189     case Swap64:
3190         return 119
3191     case Test32:
3192         return 120
3193     case Test64:
3194         return 121
3195     case Urshift32:
3196         return 122
3197     case Urshift64:
3198         return 123
3199     case X86ConvertToDoubleWord32:
3200         return 124
3201     case X86ConvertToQuadWord64:
3202         return 125
3203     case X86Div32:
3204         return 126
3205     case X86Div64:
3206         return 127
3207     case Xor32:
3208         return 128
3209     case Xor64:
3210         return 129
3211     case XorDouble:
3212         return 130
3213     case XorFloat:
3214         return 131
3215     case ZeroExtend16To32:
3216         return 132
3217     case ZeroExtend8To32:
3218         return 133
3219     default:
3220         throw new Error("bad opcode");
3221     }
3222 }
3223
3224 class Reg extends TmpBase {
3225     constructor(index, type, name, isCalleeSave)
3226     {
3227         super();
3228         this._index = index;
3229         this._type = type;
3230         this._name = name;
3231         this._isCalleeSave = !!isCalleeSave;
3232     }
3233     
3234     static fromReg(reg)
3235     {
3236         return reg;
3237     }
3238     
3239     get index() { return this._index; }
3240     get type() { return this._type; }
3241     get name() { return this._name; }
3242     get isCalleeSave() { return this._isCalleeSave; }
3243     
3244     get isReg() { return true; }
3245     
3246     hash()
3247     {
3248         if (this.isGP)
3249             return 1 + this._index;
3250         return -1 - this._index;
3251     }
3252     
3253     toString()
3254     {
3255         return `%${this._name}`;
3256     }
3257     
3258     static extract(arg)
3259     {
3260         if (arg.isReg)
3261             return arg.reg;
3262         return null;
3263     }
3264     
3265     static forEachFast(arg, func)
3266     {
3267         return arg.forEachTmpFast(tmp => {
3268             if (!tmp.isReg)
3269                 return;
3270             return func(tmp);
3271         });
3272     }
3273     
3274     static forEach(arg, argRole, argType, argWidth, func)
3275     {
3276         return arg.forEachTmp(
3277             argRole, argType, argWidth,
3278             (tmp, role, type, width) => {
3279                 if (!tmp.isReg)
3280                     return;
3281                 return func(tmp, role, type, width);
3282             });
3283     }
3284 }
3285
3286 {
3287     Reg.regs = [];
3288     function newReg(...args)
3289     {
3290         let result = new Reg(...args);
3291         Reg.regs.push(result);
3292         return result;
3293     }
3294
3295     // Define X86_64 GPRs
3296     {
3297         let index = 0;
3298         function newGPR(name, isCalleeSave) { return newReg(index++, GP, name, isCalleeSave); }
3299         
3300         Reg.rax = newGPR("rax");
3301         Reg.rcx = newGPR("rcx");
3302         Reg.rdx = newGPR("rdx");
3303         Reg.rbx = newGPR("rbx", true);
3304         Reg.rsp = newGPR("rsp");
3305         Reg.rbp = newGPR("rbp", true);
3306         Reg.rsi = newGPR("rsi");
3307         Reg.rdi = newGPR("rdi");
3308         for (let i = 8; i <= 15; ++i)
3309             Reg[`r${i}`] = newGPR(`r${i}`, i >= 12);
3310     }
3311
3312     // Define X86_64 FPRs.
3313     for (let i = 0; i <= 15; ++i)
3314         Reg[`xmm${i}`] = newReg(i, FP, `xmm${i}`);
3315
3316     Reg.gprs = []
3317     Reg.fprs = []
3318     Reg.calleeSaveGPRs = []
3319     Reg.calleeSaveFPRs = []
3320     Reg.calleeSaves = []
3321     for (let reg of Reg.regs) {
3322         if (reg.isGP) {
3323             Reg.gprs.push(reg);
3324             if (reg.isCalleeSave)
3325                 Reg.calleeSaveGPRs.push(reg);
3326         } else {
3327             Reg.fprs.push(reg);
3328             if (reg.isCalleeSave)
3329                 Reg.calleeSaveFPRS.push(reg);
3330         }
3331         if (reg.isCalleeSave)
3332             Reg.calleeSaves.push(reg);
3333     }
3334     
3335     Reg.callFrameRegister = Reg.rbp;
3336     Reg.stackPointerRegister = Reg.rsp;
3337 }
3338
3339 class StackSlot {
3340     constructor(index, byteSize, kind)
3341     {
3342         this._index = index;
3343         this._byteSize = byteSize;
3344         this._kind = kind;
3345     }
3346     
3347     get byteSize() { return this._byteSize; }
3348     get kind() { return this._kind; }
3349     
3350     get isLocked() { return this._kind == Locked; }
3351     get isSpill() { return this._kind == Spill; }
3352     
3353     get index() { return this._index; }
3354
3355     ensureSize(size)
3356     {
3357         if (this._offsetFromFP)
3358             throw new Error("Stack slot already allocated");
3359         this._byteSize = Math.max(this._byteSize, size);
3360     }
3361     
3362     get alignment()
3363     {
3364         if (this._byteSize <= 1)
3365             return 1;
3366         if (this._byteSize <= 2)
3367             return 2;
3368         if (this._byteSize <= 4)
3369             return 4;
3370         return 8;
3371     }
3372     
3373     get offsetFromFP() { return this._offsetFromFP; }
3374     
3375     setOffsetFromFP(value) { this._offsetFromFP = value; }
3376     
3377     hash()
3378     {
3379         return ((this._kind == Spill ? 1 : 0) + this._byteSize * 3 + (this._offsetFromFP ? this._offsetFromFP * 7 : 0)) >>> 0;
3380     }
3381     
3382     toString()
3383     {
3384         return "" + (this.isSpill ? "spill" : "stack") + this._index + "<" + this._byteSize +
3385             (this._offsetFromFP ? ", offset = " + this._offsetFromFP : "") + ">";
3386     }
3387     
3388     static extract(arg)
3389     {
3390         if (arg.isStack)
3391             return arg.stackSlot;
3392         return null;
3393     }
3394     
3395     static forEachFast(arg, func)
3396     {
3397         if (!arg.isStack)
3398             return;
3399         
3400         let replacement;
3401         if (replacement = func(arg.stackSlot))
3402             return Arg.createStack(replacement, this._offset);
3403     }
3404     
3405     static forEach(arg, role, type, width, func)
3406     {
3407         if (!arg.isStack)
3408             return;
3409         
3410         let replacement;
3411         if (replacement = func(arg.stackSlot, role, type, width))
3412             return Arg.createStack(replacement, this._offset);
3413     }
3414 }
3415
3416 class Tmp extends TmpBase {
3417     constructor(index, type)
3418     {
3419         super();
3420         this._index = index;
3421         this._type = type;
3422     }
3423     
3424     static fromReg(reg)
3425     {
3426         return reg;
3427     }
3428     
3429     get index() { return this._index; }
3430     get type() { return this._type; }
3431     
3432     get isReg() { return false; }
3433     
3434     hash()
3435     {
3436         if (isGP)
3437             return Reg.gprs[Reg.gprs.length - 1].hash() + 1 + this._index;
3438         return Reg.fprs[Reg.fprs.length - 1].hash() - 1 - this._index;
3439     }
3440
3441     toString()
3442     {
3443         return "%" + (this.isGP ? "" : "f") + "tmp" + this._index;
3444     }
3445     
3446     static extract(arg)
3447     {
3448         if (arg.isTmp)
3449             return arg.tmp;
3450         return null;
3451     }
3452
3453     static forEachFast(arg, func) { return arg.forEachTmpFast(func); }
3454     static forEach(arg, role, type, width, func) { return arg.forEachTmp(role, type, width, func); }
3455 }
3456
3457 function isRepresentableAsInt32(value)
3458 {
3459     return (value | 0) === value;
3460 }
3461
3462 function addIndexed(list, cons, ...args)
3463 {
3464     let result = new cons(list.length, ...args);
3465     list.push(result);
3466     return result;
3467 }
3468
3469 const stackAlignmentBytes = 16;
3470
3471 function roundUpToMultipleOf(amount, value)
3472 {
3473     return Math.ceil(value / amount) * amount;
3474 }
3475
3476 function symbolName(symbol)
3477 {
3478     let fullString = symbol.toString();
3479     return fullString.substring("Symbol(".length, fullString.length - ")".length);
3480 }
3481
3482 function lowerSymbolName(symbol)
3483 {
3484     return symbolName(symbol).toLowerCase();
3485 }
3486
3487 function setToString(set)
3488 {
3489     let result = "";
3490     for (let value of set) {
3491         if (result)
3492             result += ", ";
3493         result += value;
3494     }
3495     return result;
3496 }
3497
3498 function mergeIntoSet(target, source)
3499 {
3500     let didAdd = false;
3501     for (let value of source) {
3502         if (target.has(value))
3503             continue;
3504         target.add(value);
3505         didAdd = true;
3506     }
3507     return didAdd;
3508 }
3509
3510 function nonEmptyRangesOverlap(leftMin, leftMax, rightMin, rightMax)
3511 {
3512     if (leftMin >= leftMax)
3513         throw new Error("Bad left range");
3514     if (rightMin >= rightMax)
3515         throw new Error("Bad right range");
3516     
3517     if (leftMin <= rightMin && leftMax > rightMin)
3518         return true;
3519     if (rightMin <= leftMin && rightMax > leftMin)
3520         return true;
3521     return false;
3522 }
3523
3524 function rangesOverlap(leftMin, leftMax, rightMin, rightMax)
3525 {
3526     if (leftMin > leftMax)
3527         throw new Error("Bad left range");
3528     if (rightMin > rightMax)
3529         throw new Error("Bad right range");
3530     
3531     if (leftMin == leftMax)
3532         return false;
3533     if (rightMin == rightMax)
3534         return false;
3535     
3536     return nonEmptyRangesOverlap(leftMin, leftMax, rightMin, rightMax);
3537 }
3538
3539 function removeAllMatching(array, func)
3540 {
3541     let srcIndex = 0;
3542     let dstIndex = 0;
3543     while&