B3 should be able to compile a program with Switch
[WebKit-https.git] / Source / JavaScriptCore / b3 / testb3.cpp
1 /*
2  * Copyright (C) 2015 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
26 #include "config.h"
27
28 #include "B3ArgumentRegValue.h"
29 #include "B3BasicBlockInlines.h"
30 #include "B3CCallValue.h"
31 #include "B3Compilation.h"
32 #include "B3Const32Value.h"
33 #include "B3ConstPtrValue.h"
34 #include "B3ControlValue.h"
35 #include "B3MemoryValue.h"
36 #include "B3Procedure.h"
37 #include "B3StackSlotValue.h"
38 #include "B3SwitchValue.h"
39 #include "B3UpsilonValue.h"
40 #include "B3ValueInlines.h"
41 #include "CCallHelpers.h"
42 #include "InitializeThreading.h"
43 #include "JSCInlines.h"
44 #include "LinkBuffer.h"
45 #include "VM.h"
46 #include <wtf/Lock.h>
47 #include <wtf/NumberOfCores.h>
48 #include <wtf/Threading.h>
49
50 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
51 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
52
53 static void usage()
54 {
55     dataLog("Usage: testb3 [<filter>]\n");
56     if (hiddenTruthBecauseNoReturnIsStupid())
57         exit(1);
58 }
59
60 #if ENABLE(B3_JIT)
61
62 using namespace JSC;
63 using namespace JSC::B3;
64
65 namespace {
66
67 // Nothing fancy for now; we just use the existing WTF assertion machinery.
68 #define CHECK(x) RELEASE_ASSERT(x)
69
70 VM* vm;
71
72 std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
73 {
74     return std::make_unique<Compilation>(*vm, procedure, optLevel);
75 }
76
77 template<typename T, typename... Arguments>
78 T invoke(const Compilation& code, Arguments... arguments)
79 {
80     T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(code.code().executableAddress());
81     return function(arguments...);
82 }
83
84 template<typename T, typename... Arguments>
85 T compileAndRun(Procedure& procedure, Arguments... arguments)
86 {
87     return invoke<T>(*compile(procedure), arguments...);
88 }
89
90 void test42()
91 {
92     Procedure proc;
93     BasicBlock* root = proc.addBlock();
94     Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
95     root->appendNew<ControlValue>(proc, Return, Origin(), const42);
96
97     CHECK(compileAndRun<int>(proc) == 42);
98 }
99
100 void testLoad42()
101 {
102     Procedure proc;
103     BasicBlock* root = proc.addBlock();
104     int x = 42;
105     root->appendNew<ControlValue>(
106         proc, Return, Origin(),
107         root->appendNew<MemoryValue>(
108             proc, Load, Int32, Origin(),
109             root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
110
111     CHECK(compileAndRun<int>(proc) == 42);
112 }
113
114 void testArg(int argument)
115 {
116     Procedure proc;
117     BasicBlock* root = proc.addBlock();
118     root->appendNew<ControlValue>(
119         proc, Return, Origin(),
120         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
121
122     CHECK(compileAndRun<int>(proc, argument) == argument);
123 }
124
125 void testReturnConst64(int64_t value)
126 {
127     Procedure proc;
128     BasicBlock* root = proc.addBlock();
129     root->appendNew<ControlValue>(
130         proc, Return, Origin(),
131         root->appendNew<Const64Value>(proc, Origin(), value));
132
133     CHECK(compileAndRun<int64_t>(proc) == value);
134 }
135
136 void testAddArg(int a)
137 {
138     Procedure proc;
139     BasicBlock* root = proc.addBlock();
140     Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
141     root->appendNew<ControlValue>(
142         proc, Return, Origin(),
143         root->appendNew<Value>(proc, Add, Origin(), value, value));
144
145     CHECK(compileAndRun<int>(proc, a) == a + a);
146 }
147
148 void testAddArgs(int a, int b)
149 {
150     Procedure proc;
151     BasicBlock* root = proc.addBlock();
152     root->appendNew<ControlValue>(
153         proc, Return, Origin(),
154         root->appendNew<Value>(
155             proc, Add, Origin(),
156             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
157             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
158
159     CHECK(compileAndRun<int>(proc, a, b) == a + b);
160 }
161
162 void testAddArgImm(int a, int b)
163 {
164     Procedure proc;
165     BasicBlock* root = proc.addBlock();
166     root->appendNew<ControlValue>(
167         proc, Return, Origin(),
168         root->appendNew<Value>(
169             proc, Add, Origin(),
170             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
171             root->appendNew<Const64Value>(proc, Origin(), b)));
172
173     CHECK(compileAndRun<int>(proc, a) == a + b);
174 }
175
176 void testAddImmArg(int a, int b)
177 {
178     Procedure proc;
179     BasicBlock* root = proc.addBlock();
180     root->appendNew<ControlValue>(
181         proc, Return, Origin(),
182         root->appendNew<Value>(
183             proc, Add, Origin(),
184             root->appendNew<Const64Value>(proc, Origin(), a),
185             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
186
187     CHECK(compileAndRun<int>(proc, b) == a + b);
188 }
189
190 void testAddArgs32(int a, int b)
191 {
192     Procedure proc;
193     BasicBlock* root = proc.addBlock();
194     root->appendNew<ControlValue>(
195         proc, Return, Origin(),
196         root->appendNew<Value>(
197             proc, Add, Origin(),
198             root->appendNew<Value>(
199                 proc, Trunc, Origin(),
200                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
201             root->appendNew<Value>(
202                 proc, Trunc, Origin(),
203                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
204
205     CHECK(compileAndRun<int>(proc, a, b) == a + b);
206 }
207
208 void testAddLoadTwice()
209 {
210     auto test = [&] (unsigned optLevel) {
211         Procedure proc;
212         BasicBlock* root = proc.addBlock();
213         int32_t value = 42;
214         Value* load = root->appendNew<MemoryValue>(
215             proc, Load, Int32, Origin(),
216             root->appendNew<ConstPtrValue>(proc, Origin(), &value));
217         root->appendNew<ControlValue>(
218             proc, Return, Origin(),
219             root->appendNew<Value>(proc, Add, Origin(), load, load));
220
221         auto code = compile(proc, optLevel);
222         CHECK(invoke<int32_t>(*code) == 42 * 2);
223     };
224
225     test(0);
226     test(1);
227 }
228
229 void testMulArg(int a)
230 {
231     Procedure proc;
232     BasicBlock* root = proc.addBlock();
233     Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
234     root->appendNew<ControlValue>(
235         proc, Return, Origin(),
236         root->appendNew<Value>(proc, Mul, Origin(), value, value));
237
238     CHECK(compileAndRun<int>(proc, a) == a * a);
239 }
240
241 void testMulArgs(int a, int b)
242 {
243     Procedure proc;
244     BasicBlock* root = proc.addBlock();
245     root->appendNew<ControlValue>(
246         proc, Return, Origin(),
247         root->appendNew<Value>(
248             proc, Mul, Origin(),
249             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
250             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
251
252     CHECK(compileAndRun<int>(proc, a, b) == a * b);
253 }
254
255 void testMulArgImm(int64_t a, int64_t b)
256 {
257     Procedure proc;
258     BasicBlock* root = proc.addBlock();
259     root->appendNew<ControlValue>(
260         proc, Return, Origin(),
261         root->appendNew<Value>(
262             proc, Mul, Origin(),
263             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
264             root->appendNew<Const64Value>(proc, Origin(), b)));
265
266     CHECK(compileAndRun<int64_t>(proc, a) == a * b);
267 }
268
269 void testMulImmArg(int a, int b)
270 {
271     Procedure proc;
272     BasicBlock* root = proc.addBlock();
273     root->appendNew<ControlValue>(
274         proc, Return, Origin(),
275         root->appendNew<Value>(
276             proc, Mul, Origin(),
277             root->appendNew<Const64Value>(proc, Origin(), a),
278             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
279
280     CHECK(compileAndRun<int>(proc, b) == a * b);
281 }
282
283 void testMulArgs32(int a, int b)
284 {
285     Procedure proc;
286     BasicBlock* root = proc.addBlock();
287     root->appendNew<ControlValue>(
288         proc, Return, Origin(),
289         root->appendNew<Value>(
290             proc, Mul, Origin(),
291             root->appendNew<Value>(
292                 proc, Trunc, Origin(),
293                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
294             root->appendNew<Value>(
295                 proc, Trunc, Origin(),
296                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
297
298     CHECK(compileAndRun<int>(proc, a, b) == a * b);
299 }
300
301 void testMulLoadTwice()
302 {
303     auto test = [&] (unsigned optLevel) {
304         Procedure proc;
305         BasicBlock* root = proc.addBlock();
306         int32_t value = 42;
307         Value* load = root->appendNew<MemoryValue>(
308             proc, Load, Int32, Origin(),
309             root->appendNew<ConstPtrValue>(proc, Origin(), &value));
310         root->appendNew<ControlValue>(
311             proc, Return, Origin(),
312             root->appendNew<Value>(proc, Mul, Origin(), load, load));
313
314         auto code = compile(proc, optLevel);
315         CHECK(invoke<int32_t>(*code) == 42 * 42);
316     };
317
318     test(0);
319     test(1);
320 }
321
322 void testSubArg(int a)
323 {
324     Procedure proc;
325     BasicBlock* root = proc.addBlock();
326     Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
327     root->appendNew<ControlValue>(
328         proc, Return, Origin(),
329         root->appendNew<Value>(proc, Sub, Origin(), value, value));
330
331     CHECK(!compileAndRun<int>(proc, a));
332 }
333
334 void testSubArgs(int a, int b)
335 {
336     Procedure proc;
337     BasicBlock* root = proc.addBlock();
338     root->appendNew<ControlValue>(
339         proc, Return, Origin(),
340         root->appendNew<Value>(
341             proc, Sub, Origin(),
342             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
343             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
344
345     CHECK(compileAndRun<int>(proc, a, b) == a - b);
346 }
347
348 void testSubArgImm(int64_t a, int64_t b)
349 {
350     Procedure proc;
351     BasicBlock* root = proc.addBlock();
352     root->appendNew<ControlValue>(
353         proc, Return, Origin(),
354         root->appendNew<Value>(
355             proc, Sub, Origin(),
356             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
357             root->appendNew<Const64Value>(proc, Origin(), b)));
358
359     CHECK(compileAndRun<int64_t>(proc, a) == a - b);
360 }
361
362 void testSubImmArg(int a, int b)
363 {
364     Procedure proc;
365     BasicBlock* root = proc.addBlock();
366     root->appendNew<ControlValue>(
367         proc, Return, Origin(),
368         root->appendNew<Value>(
369             proc, Sub, Origin(),
370             root->appendNew<Const64Value>(proc, Origin(), a),
371             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
372
373     CHECK(compileAndRun<int>(proc, b) == a - b);
374 }
375
376 void testSubArgs32(int a, int b)
377 {
378     Procedure proc;
379     BasicBlock* root = proc.addBlock();
380     root->appendNew<ControlValue>(
381         proc, Return, Origin(),
382         root->appendNew<Value>(
383             proc, Sub, Origin(),
384             root->appendNew<Value>(
385                 proc, Trunc, Origin(),
386                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
387             root->appendNew<Value>(
388                 proc, Trunc, Origin(),
389                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
390
391     CHECK(compileAndRun<int>(proc, a, b) == a - b);
392 }
393
394 void testSubArgImm32(int a, int b)
395 {
396     Procedure proc;
397     BasicBlock* root = proc.addBlock();
398     root->appendNew<ControlValue>(
399         proc, Return, Origin(),
400         root->appendNew<Value>(
401             proc, Sub, Origin(),
402             root->appendNew<Value>(
403                 proc, Trunc, Origin(),
404                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
405             root->appendNew<Const32Value>(proc, Origin(), b)));
406
407     CHECK(compileAndRun<int>(proc, a) == a - b);
408 }
409
410 void testSubImmArg32(int a, int b)
411 {
412     Procedure proc;
413     BasicBlock* root = proc.addBlock();
414     root->appendNew<ControlValue>(
415         proc, Return, Origin(),
416         root->appendNew<Value>(
417             proc, Sub, Origin(),
418             root->appendNew<Const32Value>(proc, Origin(), a),
419             root->appendNew<Value>(
420                 proc, Trunc, Origin(),
421                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
422
423     CHECK(compileAndRun<int>(proc, b) == a - b);
424 }
425
426 void testBitAndArgs(int64_t a, int64_t b)
427 {
428     Procedure proc;
429     BasicBlock* root = proc.addBlock();
430     root->appendNew<ControlValue>(
431         proc, Return, Origin(),
432         root->appendNew<Value>(
433             proc, BitAnd, Origin(),
434             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
435             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
436
437     CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
438 }
439
440 void testBitAndSameArg(int64_t a)
441 {
442     Procedure proc;
443     BasicBlock* root = proc.addBlock();
444     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
445     root->appendNew<ControlValue>(
446         proc, Return, Origin(),
447         root->appendNew<Value>(
448             proc, BitAnd, Origin(),
449             argument,
450             argument));
451
452     CHECK(compileAndRun<int64_t>(proc, a) == a);
453 }
454
455 void testBitAndImms(int64_t a, int64_t b)
456 {
457     Procedure proc;
458     BasicBlock* root = proc.addBlock();
459     root->appendNew<ControlValue>(
460         proc, Return, Origin(),
461         root->appendNew<Value>(
462             proc, BitAnd, Origin(),
463             root->appendNew<Const64Value>(proc, Origin(), a),
464             root->appendNew<Const64Value>(proc, Origin(), b)));
465
466     CHECK(compileAndRun<int64_t>(proc) == (a & b));
467 }
468
469 void testBitAndArgImm(int64_t a, int64_t b)
470 {
471     Procedure proc;
472     BasicBlock* root = proc.addBlock();
473     root->appendNew<ControlValue>(
474         proc, Return, Origin(),
475         root->appendNew<Value>(
476             proc, BitAnd, Origin(),
477             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
478             root->appendNew<Const64Value>(proc, Origin(), b)));
479
480     CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
481 }
482
483 void testBitAndImmArg(int64_t a, int64_t b)
484 {
485     Procedure proc;
486     BasicBlock* root = proc.addBlock();
487     root->appendNew<ControlValue>(
488         proc, Return, Origin(),
489         root->appendNew<Value>(
490             proc, BitAnd, Origin(),
491             root->appendNew<Const64Value>(proc, Origin(), a),
492             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
493
494     CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
495 }
496
497 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
498 {
499     Procedure proc;
500     BasicBlock* root = proc.addBlock();
501     Value* innerBitAnd = root->appendNew<Value>(
502         proc, BitAnd, Origin(),
503         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
504         root->appendNew<Const64Value>(proc, Origin(), b));
505     root->appendNew<ControlValue>(
506         proc, Return, Origin(),
507         root->appendNew<Value>(
508             proc, BitAnd, Origin(),
509             innerBitAnd,
510             root->appendNew<Const64Value>(proc, Origin(), c)));
511
512     CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
513 }
514
515 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
516 {
517     Procedure proc;
518     BasicBlock* root = proc.addBlock();
519     Value* innerBitAnd = root->appendNew<Value>(
520         proc, BitAnd, Origin(),
521         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
522         root->appendNew<Const64Value>(proc, Origin(), c));
523     root->appendNew<ControlValue>(
524         proc, Return, Origin(),
525         root->appendNew<Value>(
526             proc, BitAnd, Origin(),
527             root->appendNew<Const64Value>(proc, Origin(), a),
528             innerBitAnd));
529
530     CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
531 }
532
533 void testBitAndArgs32(int a, int b)
534 {
535     Procedure proc;
536     BasicBlock* root = proc.addBlock();
537     root->appendNew<ControlValue>(
538         proc, Return, Origin(),
539         root->appendNew<Value>(
540             proc, BitAnd, Origin(),
541             root->appendNew<Value>(
542                 proc, Trunc, Origin(),
543                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
544             root->appendNew<Value>(
545                 proc, Trunc, Origin(),
546                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
547
548     CHECK(compileAndRun<int>(proc, a, b) == (a & b));
549 }
550
551 void testBitAndSameArg32(int a)
552 {
553     Procedure proc;
554     BasicBlock* root = proc.addBlock();
555     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
556         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
557     root->appendNew<ControlValue>(
558         proc, Return, Origin(),
559         root->appendNew<Value>(
560             proc, BitAnd, Origin(),
561             argument,
562             argument));
563
564     CHECK(compileAndRun<int>(proc, a) == a);
565 }
566
567 void testBitAndImms32(int a, int b)
568 {
569     Procedure proc;
570     BasicBlock* root = proc.addBlock();
571     root->appendNew<ControlValue>(
572         proc, Return, Origin(),
573         root->appendNew<Value>(
574             proc, BitAnd, Origin(),
575             root->appendNew<Const32Value>(proc, Origin(), a),
576             root->appendNew<Const32Value>(proc, Origin(), b)));
577
578     CHECK(compileAndRun<int>(proc) == (a & b));
579 }
580
581 void testBitAndArgImm32(int a, int b)
582 {
583     Procedure proc;
584     BasicBlock* root = proc.addBlock();
585     root->appendNew<ControlValue>(
586         proc, Return, Origin(),
587         root->appendNew<Value>(
588             proc, BitAnd, Origin(),
589             root->appendNew<Value>(
590                 proc, Trunc, Origin(),
591                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
592             root->appendNew<Const32Value>(proc, Origin(), b)));
593
594     CHECK(compileAndRun<int>(proc, a) == (a & b));
595 }
596
597 void testBitAndImmArg32(int a, int b)
598 {
599     Procedure proc;
600     BasicBlock* root = proc.addBlock();
601     root->appendNew<ControlValue>(
602         proc, Return, Origin(),
603         root->appendNew<Value>(
604             proc, BitAnd, Origin(),
605             root->appendNew<Const32Value>(proc, Origin(), a),
606             root->appendNew<Value>(
607                 proc, Trunc, Origin(),
608                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
609
610     CHECK(compileAndRun<int>(proc, b) == (a & b));
611 }
612
613 void testBitAndBitAndArgImmImm32(int a, int b, int c)
614 {
615     Procedure proc;
616     BasicBlock* root = proc.addBlock();
617     Value* innerBitAnd = root->appendNew<Value>(
618         proc, BitAnd, Origin(),
619         root->appendNew<Value>(
620             proc, Trunc, Origin(),
621             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
622         root->appendNew<Const32Value>(proc, Origin(), b));
623     root->appendNew<ControlValue>(
624         proc, Return, Origin(),
625         root->appendNew<Value>(
626             proc, BitAnd, Origin(),
627             innerBitAnd,
628             root->appendNew<Const32Value>(proc, Origin(), c)));
629
630     CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
631 }
632
633 void testBitAndImmBitAndArgImm32(int a, int b, int c)
634 {
635     Procedure proc;
636     BasicBlock* root = proc.addBlock();
637     Value* innerBitAnd = root->appendNew<Value>(
638         proc, BitAnd, Origin(),
639         root->appendNew<Value>(
640             proc, Trunc, Origin(),
641             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
642         root->appendNew<Const32Value>(proc, Origin(), c));
643     root->appendNew<ControlValue>(
644         proc, Return, Origin(),
645         root->appendNew<Value>(
646             proc, BitAnd, Origin(),
647             root->appendNew<Const32Value>(proc, Origin(), a),
648             innerBitAnd));
649
650     CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
651 }
652
653 void testBitOrArgs(int64_t a, int64_t b)
654 {
655     Procedure proc;
656     BasicBlock* root = proc.addBlock();
657     root->appendNew<ControlValue>(
658         proc, Return, Origin(),
659         root->appendNew<Value>(
660             proc, BitOr, Origin(),
661             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
662             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
663
664     CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
665 }
666
667 void testBitOrSameArg(int64_t a)
668 {
669     Procedure proc;
670     BasicBlock* root = proc.addBlock();
671     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
672     root->appendNew<ControlValue>(
673         proc, Return, Origin(),
674         root->appendNew<Value>(
675             proc, BitOr, Origin(),
676             argument,
677             argument));
678
679     CHECK(compileAndRun<int64_t>(proc, a) == a);
680 }
681
682 void testBitOrImms(int64_t a, int64_t b)
683 {
684     Procedure proc;
685     BasicBlock* root = proc.addBlock();
686     root->appendNew<ControlValue>(
687         proc, Return, Origin(),
688         root->appendNew<Value>(
689             proc, BitOr, Origin(),
690             root->appendNew<Const64Value>(proc, Origin(), a),
691             root->appendNew<Const64Value>(proc, Origin(), b)));
692
693     CHECK(compileAndRun<int64_t>(proc) == (a | b));
694 }
695
696 void testBitOrArgImm(int64_t a, int64_t b)
697 {
698     Procedure proc;
699     BasicBlock* root = proc.addBlock();
700     root->appendNew<ControlValue>(
701         proc, Return, Origin(),
702         root->appendNew<Value>(
703             proc, BitOr, Origin(),
704             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
705             root->appendNew<Const64Value>(proc, Origin(), b)));
706
707     CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
708 }
709
710 void testBitOrImmArg(int64_t a, int64_t b)
711 {
712     Procedure proc;
713     BasicBlock* root = proc.addBlock();
714     root->appendNew<ControlValue>(
715         proc, Return, Origin(),
716         root->appendNew<Value>(
717             proc, BitOr, Origin(),
718             root->appendNew<Const64Value>(proc, Origin(), a),
719             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
720
721     CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
722 }
723
724 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
725 {
726     Procedure proc;
727     BasicBlock* root = proc.addBlock();
728     Value* innerBitOr = root->appendNew<Value>(
729         proc, BitOr, Origin(),
730         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
731         root->appendNew<Const64Value>(proc, Origin(), b));
732     root->appendNew<ControlValue>(
733         proc, Return, Origin(),
734         root->appendNew<Value>(
735             proc, BitOr, Origin(),
736             innerBitOr,
737             root->appendNew<Const64Value>(proc, Origin(), c)));
738
739     CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
740 }
741
742 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
743 {
744     Procedure proc;
745     BasicBlock* root = proc.addBlock();
746     Value* innerBitOr = root->appendNew<Value>(
747         proc, BitOr, Origin(),
748         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
749         root->appendNew<Const64Value>(proc, Origin(), c));
750     root->appendNew<ControlValue>(
751         proc, Return, Origin(),
752         root->appendNew<Value>(
753             proc, BitOr, Origin(),
754             root->appendNew<Const64Value>(proc, Origin(), a),
755             innerBitOr));
756
757     CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
758 }
759
760 void testBitOrArgs32(int a, int b)
761 {
762     Procedure proc;
763     BasicBlock* root = proc.addBlock();
764     root->appendNew<ControlValue>(
765         proc, Return, Origin(),
766         root->appendNew<Value>(
767             proc, BitOr, Origin(),
768             root->appendNew<Value>(
769                 proc, Trunc, Origin(),
770                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
771             root->appendNew<Value>(
772                 proc, Trunc, Origin(),
773                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
774
775     CHECK(compileAndRun<int>(proc, a, b) == (a | b));
776 }
777
778 void testBitOrSameArg32(int a)
779 {
780     Procedure proc;
781     BasicBlock* root = proc.addBlock();
782     Value* argument = root->appendNew<Value>(
783         proc, Trunc, Origin(),
784             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
785     root->appendNew<ControlValue>(
786         proc, Return, Origin(),
787         root->appendNew<Value>(
788             proc, BitOr, Origin(),
789             argument,
790             argument));
791
792     CHECK(compileAndRun<int>(proc, a) == a);
793 }
794
795 void testBitOrImms32(int a, int b)
796 {
797     Procedure proc;
798     BasicBlock* root = proc.addBlock();
799     root->appendNew<ControlValue>(
800         proc, Return, Origin(),
801         root->appendNew<Value>(
802             proc, BitOr, Origin(),
803             root->appendNew<Const32Value>(proc, Origin(), a),
804             root->appendNew<Const32Value>(proc, Origin(), b)));
805
806     CHECK(compileAndRun<int>(proc) == (a | b));
807 }
808
809 void testBitOrArgImm32(int a, int b)
810 {
811     Procedure proc;
812     BasicBlock* root = proc.addBlock();
813     root->appendNew<ControlValue>(
814         proc, Return, Origin(),
815         root->appendNew<Value>(
816             proc, BitOr, Origin(),
817             root->appendNew<Value>(
818                 proc, Trunc, Origin(),
819                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
820             root->appendNew<Const32Value>(proc, Origin(), b)));
821
822     CHECK(compileAndRun<int>(proc, a) == (a | b));
823 }
824
825 void testBitOrImmArg32(int a, int b)
826 {
827     Procedure proc;
828     BasicBlock* root = proc.addBlock();
829     root->appendNew<ControlValue>(
830         proc, Return, Origin(),
831         root->appendNew<Value>(
832             proc, BitOr, Origin(),
833             root->appendNew<Const32Value>(proc, Origin(), a),
834             root->appendNew<Value>(
835                 proc, Trunc, Origin(),
836                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
837
838     CHECK(compileAndRun<int>(proc, b) == (a | b));
839 }
840
841 void testBitOrBitOrArgImmImm32(int a, int b, int c)
842 {
843     Procedure proc;
844     BasicBlock* root = proc.addBlock();
845     Value* innerBitOr = root->appendNew<Value>(
846         proc, BitOr, Origin(),
847         root->appendNew<Value>(
848             proc, Trunc, Origin(),
849             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
850         root->appendNew<Const32Value>(proc, Origin(), b));
851     root->appendNew<ControlValue>(
852         proc, Return, Origin(),
853         root->appendNew<Value>(
854             proc, BitOr, Origin(),
855             innerBitOr,
856             root->appendNew<Const32Value>(proc, Origin(), c)));
857
858     CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
859 }
860
861 void testBitOrImmBitOrArgImm32(int a, int b, int c)
862 {
863     Procedure proc;
864     BasicBlock* root = proc.addBlock();
865     Value* innerBitOr = root->appendNew<Value>(
866         proc, BitOr, Origin(),
867         root->appendNew<Value>(
868             proc, Trunc, Origin(),
869             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
870         root->appendNew<Const32Value>(proc, Origin(), c));
871     root->appendNew<ControlValue>(
872         proc, Return, Origin(),
873         root->appendNew<Value>(
874             proc, BitOr, Origin(),
875             root->appendNew<Const32Value>(proc, Origin(), a),
876             innerBitOr));
877
878     CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
879 }
880
881 void testBitXorArgs(int64_t a, int64_t b)
882 {
883     Procedure proc;
884     BasicBlock* root = proc.addBlock();
885     root->appendNew<ControlValue>(
886         proc, Return, Origin(),
887         root->appendNew<Value>(
888             proc, BitXor, Origin(),
889             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
890             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
891
892     CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
893 }
894
895 void testBitXorSameArg(int64_t a)
896 {
897     Procedure proc;
898     BasicBlock* root = proc.addBlock();
899     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
900     root->appendNew<ControlValue>(
901         proc, Return, Origin(),
902         root->appendNew<Value>(
903             proc, BitXor, Origin(),
904             argument,
905             argument));
906
907     CHECK(!compileAndRun<int64_t>(proc, a));
908 }
909
910 void testBitXorImms(int64_t a, int64_t b)
911 {
912     Procedure proc;
913     BasicBlock* root = proc.addBlock();
914     root->appendNew<ControlValue>(
915         proc, Return, Origin(),
916         root->appendNew<Value>(
917             proc, BitXor, Origin(),
918             root->appendNew<Const64Value>(proc, Origin(), a),
919             root->appendNew<Const64Value>(proc, Origin(), b)));
920
921     CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
922 }
923
924 void testBitXorArgImm(int64_t a, int64_t b)
925 {
926     Procedure proc;
927     BasicBlock* root = proc.addBlock();
928     root->appendNew<ControlValue>(
929         proc, Return, Origin(),
930         root->appendNew<Value>(
931             proc, BitXor, Origin(),
932             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
933             root->appendNew<Const64Value>(proc, Origin(), b)));
934
935     CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
936 }
937
938 void testBitXorImmArg(int64_t a, int64_t b)
939 {
940     Procedure proc;
941     BasicBlock* root = proc.addBlock();
942     root->appendNew<ControlValue>(
943         proc, Return, Origin(),
944         root->appendNew<Value>(
945             proc, BitXor, Origin(),
946             root->appendNew<Const64Value>(proc, Origin(), a),
947             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
948
949     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
950 }
951
952 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
953 {
954     Procedure proc;
955     BasicBlock* root = proc.addBlock();
956     Value* innerBitXor = root->appendNew<Value>(
957         proc, BitXor, Origin(),
958         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
959         root->appendNew<Const64Value>(proc, Origin(), b));
960     root->appendNew<ControlValue>(
961         proc, Return, Origin(),
962         root->appendNew<Value>(
963             proc, BitXor, Origin(),
964             innerBitXor,
965             root->appendNew<Const64Value>(proc, Origin(), c)));
966
967     CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
968 }
969
970 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
971 {
972     Procedure proc;
973     BasicBlock* root = proc.addBlock();
974     Value* innerBitXor = root->appendNew<Value>(
975         proc, BitXor, Origin(),
976         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
977         root->appendNew<Const64Value>(proc, Origin(), c));
978     root->appendNew<ControlValue>(
979         proc, Return, Origin(),
980         root->appendNew<Value>(
981             proc, BitXor, Origin(),
982             root->appendNew<Const64Value>(proc, Origin(), a),
983             innerBitXor));
984
985     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
986 }
987
988 void testBitXorArgs32(int a, int b)
989 {
990     Procedure proc;
991     BasicBlock* root = proc.addBlock();
992     root->appendNew<ControlValue>(
993         proc, Return, Origin(),
994         root->appendNew<Value>(
995             proc, BitXor, Origin(),
996             root->appendNew<Value>(
997                 proc, Trunc, Origin(),
998                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
999             root->appendNew<Value>(
1000                 proc, Trunc, Origin(),
1001                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1002
1003     CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
1004 }
1005
1006 void testBitXorSameArg32(int a)
1007 {
1008     Procedure proc;
1009     BasicBlock* root = proc.addBlock();
1010     Value* argument = root->appendNew<Value>(
1011         proc, Trunc, Origin(),
1012             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1013     root->appendNew<ControlValue>(
1014         proc, Return, Origin(),
1015         root->appendNew<Value>(
1016             proc, BitXor, Origin(),
1017             argument,
1018             argument));
1019
1020     CHECK(!compileAndRun<int>(proc, a));
1021 }
1022
1023 void testBitXorImms32(int a, int b)
1024 {
1025     Procedure proc;
1026     BasicBlock* root = proc.addBlock();
1027     root->appendNew<ControlValue>(
1028         proc, Return, Origin(),
1029         root->appendNew<Value>(
1030             proc, BitXor, Origin(),
1031             root->appendNew<Const32Value>(proc, Origin(), a),
1032             root->appendNew<Const32Value>(proc, Origin(), b)));
1033
1034     CHECK(compileAndRun<int>(proc) == (a ^ b));
1035 }
1036
1037 void testBitXorArgImm32(int a, int b)
1038 {
1039     Procedure proc;
1040     BasicBlock* root = proc.addBlock();
1041     root->appendNew<ControlValue>(
1042         proc, Return, Origin(),
1043         root->appendNew<Value>(
1044             proc, BitXor, Origin(),
1045             root->appendNew<Value>(
1046                 proc, Trunc, Origin(),
1047                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1048             root->appendNew<Const32Value>(proc, Origin(), b)));
1049
1050     CHECK(compileAndRun<int>(proc, a) == (a ^ b));
1051 }
1052
1053 void testBitXorImmArg32(int a, int b)
1054 {
1055     Procedure proc;
1056     BasicBlock* root = proc.addBlock();
1057     root->appendNew<ControlValue>(
1058         proc, Return, Origin(),
1059         root->appendNew<Value>(
1060             proc, BitXor, Origin(),
1061             root->appendNew<Const32Value>(proc, Origin(), a),
1062             root->appendNew<Value>(
1063                 proc, Trunc, Origin(),
1064                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1065
1066     CHECK(compileAndRun<int>(proc, b) == (a ^ b));
1067 }
1068
1069 void testBitXorBitXorArgImmImm32(int a, int b, int c)
1070 {
1071     Procedure proc;
1072     BasicBlock* root = proc.addBlock();
1073     Value* innerBitXor = root->appendNew<Value>(
1074         proc, BitXor, Origin(),
1075         root->appendNew<Value>(
1076             proc, Trunc, Origin(),
1077             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1078         root->appendNew<Const32Value>(proc, Origin(), b));
1079     root->appendNew<ControlValue>(
1080         proc, Return, Origin(),
1081         root->appendNew<Value>(
1082             proc, BitXor, Origin(),
1083             innerBitXor,
1084             root->appendNew<Const32Value>(proc, Origin(), c)));
1085
1086     CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
1087 }
1088
1089 void testBitXorImmBitXorArgImm32(int a, int b, int c)
1090 {
1091     Procedure proc;
1092     BasicBlock* root = proc.addBlock();
1093     Value* innerBitXor = root->appendNew<Value>(
1094         proc, BitXor, Origin(),
1095         root->appendNew<Value>(
1096             proc, Trunc, Origin(),
1097             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1098         root->appendNew<Const32Value>(proc, Origin(), c));
1099     root->appendNew<ControlValue>(
1100         proc, Return, Origin(),
1101         root->appendNew<Value>(
1102             proc, BitXor, Origin(),
1103             root->appendNew<Const32Value>(proc, Origin(), a),
1104             innerBitXor));
1105
1106     CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
1107 }
1108
1109 void testShlArgs(int64_t a, int64_t b)
1110 {
1111     Procedure proc;
1112     BasicBlock* root = proc.addBlock();
1113     root->appendNew<ControlValue>(
1114         proc, Return, Origin(),
1115         root->appendNew<Value>(
1116             proc, Shl, Origin(),
1117             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1118             root->appendNew<Value>(
1119                 proc, Trunc, Origin(),
1120                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1121
1122     CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
1123 }
1124
1125 void testShlImms(int64_t a, int64_t b)
1126 {
1127     Procedure proc;
1128     BasicBlock* root = proc.addBlock();
1129     root->appendNew<ControlValue>(
1130         proc, Return, Origin(),
1131         root->appendNew<Value>(
1132             proc, Shl, Origin(),
1133             root->appendNew<Const64Value>(proc, Origin(), a),
1134             root->appendNew<Const32Value>(proc, Origin(), b)));
1135
1136     CHECK(compileAndRun<int64_t>(proc) == (a << b));
1137 }
1138
1139 void testShlArgImm(int64_t a, int64_t b)
1140 {
1141     Procedure proc;
1142     BasicBlock* root = proc.addBlock();
1143     root->appendNew<ControlValue>(
1144         proc, Return, Origin(),
1145         root->appendNew<Value>(
1146             proc, Shl, Origin(),
1147             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1148             root->appendNew<Const32Value>(proc, Origin(), b)));
1149
1150     CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
1151 }
1152
1153 void testShlArg32(int32_t a)
1154 {
1155     Procedure proc;
1156     BasicBlock* root = proc.addBlock();
1157     Value* value = root->appendNew<Value>(
1158         proc, Trunc, Origin(),
1159         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1160     root->appendNew<ControlValue>(
1161         proc, Return, Origin(),
1162         root->appendNew<Value>(proc, Shl, Origin(), value, value));
1163
1164     CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
1165 }
1166
1167 void testShlArgs32(int32_t a, int32_t b)
1168 {
1169     Procedure proc;
1170     BasicBlock* root = proc.addBlock();
1171     root->appendNew<ControlValue>(
1172         proc, Return, Origin(),
1173         root->appendNew<Value>(
1174             proc, Shl, Origin(),
1175             root->appendNew<Value>(
1176                 proc, Trunc, Origin(),
1177                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1178             root->appendNew<Value>(
1179                 proc, Trunc, Origin(),
1180                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1181
1182     CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
1183 }
1184
1185 void testShlImms32(int32_t a, int32_t b)
1186 {
1187     Procedure proc;
1188     BasicBlock* root = proc.addBlock();
1189     root->appendNew<ControlValue>(
1190         proc, Return, Origin(),
1191         root->appendNew<Value>(
1192             proc, Shl, Origin(),
1193             root->appendNew<Const32Value>(proc, Origin(), a),
1194             root->appendNew<Const32Value>(proc, Origin(), b)));
1195
1196     CHECK(compileAndRun<int32_t>(proc) == (a << b));
1197 }
1198
1199 void testShlArgImm32(int32_t a, int32_t b)
1200 {
1201     Procedure proc;
1202     BasicBlock* root = proc.addBlock();
1203     root->appendNew<ControlValue>(
1204         proc, Return, Origin(),
1205         root->appendNew<Value>(
1206             proc, Shl, Origin(),
1207             root->appendNew<Value>(
1208                 proc, Trunc, Origin(),
1209                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1210             root->appendNew<Const32Value>(proc, Origin(), b)));
1211
1212     CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
1213 }
1214
1215 void testSShrArgs(int64_t a, int64_t b)
1216 {
1217     Procedure proc;
1218     BasicBlock* root = proc.addBlock();
1219     root->appendNew<ControlValue>(
1220         proc, Return, Origin(),
1221         root->appendNew<Value>(
1222             proc, SShr, Origin(),
1223             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1224             root->appendNew<Value>(
1225                 proc, Trunc, Origin(),
1226                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1227
1228     CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
1229 }
1230
1231 void testSShrImms(int64_t a, int64_t b)
1232 {
1233     Procedure proc;
1234     BasicBlock* root = proc.addBlock();
1235     root->appendNew<ControlValue>(
1236         proc, Return, Origin(),
1237         root->appendNew<Value>(
1238             proc, SShr, Origin(),
1239             root->appendNew<Const64Value>(proc, Origin(), a),
1240             root->appendNew<Const32Value>(proc, Origin(), b)));
1241
1242     CHECK(compileAndRun<int64_t>(proc) == (a >> b));
1243 }
1244
1245 void testSShrArgImm(int64_t a, int64_t b)
1246 {
1247     Procedure proc;
1248     BasicBlock* root = proc.addBlock();
1249     root->appendNew<ControlValue>(
1250         proc, Return, Origin(),
1251         root->appendNew<Value>(
1252             proc, SShr, Origin(),
1253             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1254             root->appendNew<Const32Value>(proc, Origin(), b)));
1255
1256     CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
1257 }
1258
1259 void testSShrArg32(int32_t a)
1260 {
1261     Procedure proc;
1262     BasicBlock* root = proc.addBlock();
1263     Value* value = root->appendNew<Value>(
1264         proc, Trunc, Origin(),
1265         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1266     root->appendNew<ControlValue>(
1267         proc, Return, Origin(),
1268         root->appendNew<Value>(proc, SShr, Origin(), value, value));
1269
1270     CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
1271 }
1272
1273 void testSShrArgs32(int32_t a, int32_t b)
1274 {
1275     Procedure proc;
1276     BasicBlock* root = proc.addBlock();
1277     root->appendNew<ControlValue>(
1278         proc, Return, Origin(),
1279         root->appendNew<Value>(
1280             proc, SShr, Origin(),
1281             root->appendNew<Value>(
1282                 proc, Trunc, Origin(),
1283                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1284             root->appendNew<Value>(
1285                 proc, Trunc, Origin(),
1286                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1287
1288     CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
1289 }
1290
1291 void testSShrImms32(int32_t a, int32_t b)
1292 {
1293     Procedure proc;
1294     BasicBlock* root = proc.addBlock();
1295     root->appendNew<ControlValue>(
1296         proc, Return, Origin(),
1297         root->appendNew<Value>(
1298             proc, SShr, Origin(),
1299             root->appendNew<Const32Value>(proc, Origin(), a),
1300             root->appendNew<Const32Value>(proc, Origin(), b)));
1301
1302     CHECK(compileAndRun<int32_t>(proc) == (a >> b));
1303 }
1304
1305 void testSShrArgImm32(int32_t a, int32_t b)
1306 {
1307     Procedure proc;
1308     BasicBlock* root = proc.addBlock();
1309     root->appendNew<ControlValue>(
1310         proc, Return, Origin(),
1311         root->appendNew<Value>(
1312             proc, SShr, Origin(),
1313             root->appendNew<Value>(
1314                 proc, Trunc, Origin(),
1315                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1316             root->appendNew<Const32Value>(proc, Origin(), b)));
1317
1318     CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
1319 }
1320
1321 void testZShrArgs(uint64_t a, uint64_t b)
1322 {
1323     Procedure proc;
1324     BasicBlock* root = proc.addBlock();
1325     root->appendNew<ControlValue>(
1326         proc, Return, Origin(),
1327         root->appendNew<Value>(
1328             proc, ZShr, Origin(),
1329             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1330             root->appendNew<Value>(
1331                 proc, Trunc, Origin(),
1332                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1333
1334     CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
1335 }
1336
1337 void testZShrImms(uint64_t a, uint64_t b)
1338 {
1339     Procedure proc;
1340     BasicBlock* root = proc.addBlock();
1341     root->appendNew<ControlValue>(
1342         proc, Return, Origin(),
1343         root->appendNew<Value>(
1344             proc, ZShr, Origin(),
1345             root->appendNew<Const64Value>(proc, Origin(), a),
1346             root->appendNew<Const32Value>(proc, Origin(), b)));
1347
1348     CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
1349 }
1350
1351 void testZShrArgImm(uint64_t a, uint64_t b)
1352 {
1353     Procedure proc;
1354     BasicBlock* root = proc.addBlock();
1355     root->appendNew<ControlValue>(
1356         proc, Return, Origin(),
1357         root->appendNew<Value>(
1358             proc, ZShr, Origin(),
1359             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1360             root->appendNew<Const32Value>(proc, Origin(), b)));
1361
1362     CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
1363 }
1364
1365 void testZShrArg32(uint32_t a)
1366 {
1367     Procedure proc;
1368     BasicBlock* root = proc.addBlock();
1369     Value* value = root->appendNew<Value>(
1370         proc, Trunc, Origin(),
1371         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1372     root->appendNew<ControlValue>(
1373         proc, Return, Origin(),
1374         root->appendNew<Value>(proc, ZShr, Origin(), value, value));
1375
1376     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
1377 }
1378
1379 void testZShrArgs32(uint32_t a, uint32_t b)
1380 {
1381     Procedure proc;
1382     BasicBlock* root = proc.addBlock();
1383     root->appendNew<ControlValue>(
1384         proc, Return, Origin(),
1385         root->appendNew<Value>(
1386             proc, ZShr, Origin(),
1387             root->appendNew<Value>(
1388                 proc, Trunc, Origin(),
1389                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1390             root->appendNew<Value>(
1391                 proc, Trunc, Origin(),
1392                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1393
1394     CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
1395 }
1396
1397 void testZShrImms32(uint32_t a, uint32_t b)
1398 {
1399     Procedure proc;
1400     BasicBlock* root = proc.addBlock();
1401     root->appendNew<ControlValue>(
1402         proc, Return, Origin(),
1403         root->appendNew<Value>(
1404             proc, ZShr, Origin(),
1405             root->appendNew<Const32Value>(proc, Origin(), a),
1406             root->appendNew<Const32Value>(proc, Origin(), b)));
1407
1408     CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
1409 }
1410
1411 void testZShrArgImm32(uint32_t a, uint32_t b)
1412 {
1413     Procedure proc;
1414     BasicBlock* root = proc.addBlock();
1415     root->appendNew<ControlValue>(
1416         proc, Return, Origin(),
1417         root->appendNew<Value>(
1418             proc, ZShr, Origin(),
1419             root->appendNew<Value>(
1420                 proc, Trunc, Origin(),
1421                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1422             root->appendNew<Const32Value>(proc, Origin(), b)));
1423
1424     CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
1425 }
1426
1427 void testStore(int value)
1428 {
1429     Procedure proc;
1430     BasicBlock* root = proc.addBlock();
1431     int slot = 0xbaadbeef;
1432     root->appendNew<MemoryValue>(
1433         proc, Store, Origin(),
1434         root->appendNew<Value>(
1435             proc, Trunc, Origin(),
1436             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1437         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
1438     root->appendNew<ControlValue>(
1439         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1440
1441     CHECK(!compileAndRun<int>(proc, value));
1442     CHECK(slot == value);
1443 }
1444
1445 void testStoreConstant(int value)
1446 {
1447     Procedure proc;
1448     BasicBlock* root = proc.addBlock();
1449     int slot = 0xbaadbeef;
1450     root->appendNew<MemoryValue>(
1451         proc, Store, Origin(),
1452         root->appendNew<Const32Value>(proc, Origin(), value),
1453         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
1454     root->appendNew<ControlValue>(
1455         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1456
1457     CHECK(!compileAndRun<int>(proc));
1458     CHECK(slot == value);
1459 }
1460
1461 void testStoreConstantPtr(intptr_t value)
1462 {
1463     Procedure proc;
1464     BasicBlock* root = proc.addBlock();
1465     intptr_t slot;
1466     if (is64Bit())
1467         slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
1468     else
1469         slot = 0xbaadbeef;
1470     root->appendNew<MemoryValue>(
1471         proc, Store, Origin(),
1472         root->appendNew<ConstPtrValue>(proc, Origin(), value),
1473         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
1474     root->appendNew<ControlValue>(
1475         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1476
1477     CHECK(!compileAndRun<int>(proc));
1478     CHECK(slot == value);
1479 }
1480
1481 void testTrunc(int64_t value)
1482 {
1483     Procedure proc;
1484     BasicBlock* root = proc.addBlock();
1485     root->appendNew<ControlValue>(
1486         proc, Return, Origin(),
1487         root->appendNew<Value>(
1488             proc, Trunc, Origin(),
1489             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1490
1491     CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
1492 }
1493
1494 void testAdd1(int value)
1495 {
1496     Procedure proc;
1497     BasicBlock* root = proc.addBlock();
1498     root->appendNew<ControlValue>(
1499         proc, Return, Origin(),
1500         root->appendNew<Value>(
1501             proc, Add, Origin(),
1502             root->appendNew<Value>(
1503                 proc, Trunc, Origin(),
1504                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1505             root->appendNew<Const32Value>(proc, Origin(), 1)));
1506
1507     CHECK(compileAndRun<int>(proc, value) == value + 1);
1508 }
1509
1510 void testAdd1Ptr(intptr_t value)
1511 {
1512     Procedure proc;
1513     BasicBlock* root = proc.addBlock();
1514     root->appendNew<ControlValue>(
1515         proc, Return, Origin(),
1516         root->appendNew<Value>(
1517             proc, Add, Origin(),
1518             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1519             root->appendNew<ConstPtrValue>(proc, Origin(), 1)));
1520
1521     CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
1522 }
1523
1524 void testNeg32(int32_t value)
1525 {
1526     Procedure proc;
1527     BasicBlock* root = proc.addBlock();
1528     root->appendNew<ControlValue>(
1529         proc, Return, Origin(),
1530         root->appendNew<Value>(
1531             proc, Sub, Origin(),
1532             root->appendNew<Const32Value>(proc, Origin(), 0),
1533             root->appendNew<Value>(
1534                 proc, Trunc, Origin(),
1535                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1536
1537     CHECK(compileAndRun<int32_t>(proc, value) == -value);
1538 }
1539
1540 void testNegPtr(intptr_t value)
1541 {
1542     Procedure proc;
1543     BasicBlock* root = proc.addBlock();
1544     root->appendNew<ControlValue>(
1545         proc, Return, Origin(),
1546         root->appendNew<Value>(
1547             proc, Sub, Origin(),
1548             root->appendNew<ConstPtrValue>(proc, Origin(), 0),
1549             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1550
1551     CHECK(compileAndRun<intptr_t>(proc, value) == -value);
1552 }
1553
1554 void testStoreAddLoad(int amount)
1555 {
1556     Procedure proc;
1557     BasicBlock* root = proc.addBlock();
1558     int slot = 37;
1559     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1560     root->appendNew<MemoryValue>(
1561         proc, Store, Origin(),
1562         root->appendNew<Value>(
1563             proc, Add, Origin(),
1564             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1565             root->appendNew<Const32Value>(proc, Origin(), amount)),
1566         slotPtr);
1567     root->appendNew<ControlValue>(
1568         proc, Return, Origin(),
1569         root->appendNew<Const32Value>(proc, Origin(), 0));
1570
1571     CHECK(!compileAndRun<int>(proc));
1572     CHECK(slot == 37 + amount);
1573 }
1574
1575 void testStoreSubLoad(int amount)
1576 {
1577     Procedure proc;
1578     BasicBlock* root = proc.addBlock();
1579     int32_t startValue = std::numeric_limits<int32_t>::min();
1580     int32_t slot = startValue;
1581     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1582     root->appendNew<MemoryValue>(
1583         proc, Store, Origin(),
1584         root->appendNew<Value>(
1585             proc, Sub, Origin(),
1586             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1587             root->appendNew<Value>(
1588                 proc, Trunc, Origin(),
1589                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
1590         slotPtr);
1591     root->appendNew<ControlValue>(
1592         proc, Return, Origin(),
1593         root->appendNew<Const32Value>(proc, Origin(), 0));
1594
1595     CHECK(!compileAndRun<int>(proc, amount));
1596     CHECK(slot == startValue - amount);
1597 }
1598
1599 void testStoreAddLoadInterference(int amount)
1600 {
1601     Procedure proc;
1602     BasicBlock* root = proc.addBlock();
1603     int slot = 37;
1604     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1605     ArgumentRegValue* otherSlotPtr =
1606         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1607     MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr);
1608     root->appendNew<MemoryValue>(
1609         proc, Store, Origin(),
1610         root->appendNew<Const32Value>(proc, Origin(), 666),
1611         otherSlotPtr);
1612     root->appendNew<MemoryValue>(
1613         proc, Store, Origin(),
1614         root->appendNew<Value>(
1615             proc, Add, Origin(),
1616             load, root->appendNew<Const32Value>(proc, Origin(), amount)),
1617         slotPtr);
1618     root->appendNew<ControlValue>(
1619         proc, Return, Origin(),
1620         root->appendNew<Const32Value>(proc, Origin(), 0));
1621
1622     CHECK(!compileAndRun<int>(proc, &slot));
1623     CHECK(slot == 37 + amount);
1624 }
1625
1626 void testStoreAddAndLoad(int amount, int mask)
1627 {
1628     Procedure proc;
1629     BasicBlock* root = proc.addBlock();
1630     int slot = 37;
1631     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1632     root->appendNew<MemoryValue>(
1633         proc, Store, Origin(),
1634         root->appendNew<Value>(
1635             proc, BitAnd, Origin(),
1636             root->appendNew<Value>(
1637                 proc, Add, Origin(),
1638                 root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1639                 root->appendNew<Const32Value>(proc, Origin(), amount)),
1640             root->appendNew<Const32Value>(proc, Origin(), mask)),
1641         slotPtr);
1642     root->appendNew<ControlValue>(
1643         proc, Return, Origin(),
1644         root->appendNew<Const32Value>(proc, Origin(), 0));
1645
1646     CHECK(!compileAndRun<int>(proc));
1647     CHECK(slot == ((37 + amount) & mask));
1648 }
1649
1650 void testStoreNegLoad32(int32_t value)
1651 {
1652     Procedure proc;
1653     BasicBlock* root = proc.addBlock();
1654
1655     int32_t slot = value;
1656
1657     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1658     
1659     root->appendNew<MemoryValue>(
1660         proc, Store, Origin(),
1661         root->appendNew<Value>(
1662             proc, Sub, Origin(),
1663             root->appendNew<Const32Value>(proc, Origin(), 0),
1664             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr)),
1665         slotPtr);
1666     
1667     root->appendNew<ControlValue>(
1668         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1669
1670     CHECK(!compileAndRun<int32_t>(proc));
1671     CHECK(slot == -value);
1672 }
1673
1674 void testStoreNegLoadPtr(intptr_t value)
1675 {
1676     Procedure proc;
1677     BasicBlock* root = proc.addBlock();
1678
1679     intptr_t slot = value;
1680
1681     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1682     
1683     root->appendNew<MemoryValue>(
1684         proc, Store, Origin(),
1685         root->appendNew<Value>(
1686             proc, Sub, Origin(),
1687             root->appendNew<ConstPtrValue>(proc, Origin(), 0),
1688             root->appendNew<MemoryValue>(proc, Load, pointerType(), Origin(), slotPtr)),
1689         slotPtr);
1690     
1691     root->appendNew<ControlValue>(
1692         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1693
1694     CHECK(!compileAndRun<int32_t>(proc));
1695     CHECK(slot == -value);
1696 }
1697
1698 void testAdd1Uncommuted(int value)
1699 {
1700     Procedure proc;
1701     BasicBlock* root = proc.addBlock();
1702     root->appendNew<ControlValue>(
1703         proc, Return, Origin(),
1704         root->appendNew<Value>(
1705             proc, Add, Origin(),
1706             root->appendNew<Const32Value>(proc, Origin(), 1),
1707             root->appendNew<Value>(
1708                 proc, Trunc, Origin(),
1709                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1710
1711     CHECK(compileAndRun<int>(proc, value) == value + 1);
1712 }
1713
1714 void testLoadOffset()
1715 {
1716     Procedure proc;
1717     BasicBlock* root = proc.addBlock();
1718     int array[] = { 1, 2 };
1719     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1720     root->appendNew<ControlValue>(
1721         proc, Return, Origin(),
1722         root->appendNew<Value>(
1723             proc, Add, Origin(),
1724             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
1725             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
1726
1727     CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
1728 }
1729
1730 void testLoadOffsetNotConstant()
1731 {
1732     Procedure proc;
1733     BasicBlock* root = proc.addBlock();
1734     int array[] = { 1, 2 };
1735     Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1736     root->appendNew<ControlValue>(
1737         proc, Return, Origin(),
1738         root->appendNew<Value>(
1739             proc, Add, Origin(),
1740             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
1741             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
1742
1743     CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
1744 }
1745
1746 void testLoadOffsetUsingAdd()
1747 {
1748     Procedure proc;
1749     BasicBlock* root = proc.addBlock();
1750     int array[] = { 1, 2 };
1751     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1752     root->appendNew<ControlValue>(
1753         proc, Return, Origin(),
1754         root->appendNew<Value>(
1755             proc, Add, Origin(),
1756             root->appendNew<MemoryValue>(
1757                 proc, Load, Int32, Origin(),
1758                 root->appendNew<Value>(
1759                     proc, Add, Origin(), arrayPtr,
1760                     root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
1761             root->appendNew<MemoryValue>(
1762                 proc, Load, Int32, Origin(),
1763                 root->appendNew<Value>(
1764                     proc, Add, Origin(), arrayPtr,
1765                     root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
1766     
1767     CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
1768 }
1769
1770 void testLoadOffsetUsingAddInterference()
1771 {
1772     Procedure proc;
1773     BasicBlock* root = proc.addBlock();
1774     int array[] = { 1, 2 };
1775     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1776     ArgumentRegValue* otherArrayPtr =
1777         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1778     Const32Value* theNumberOfTheBeast = root->appendNew<Const32Value>(proc, Origin(), 666);
1779     MemoryValue* left = root->appendNew<MemoryValue>(
1780         proc, Load, Int32, Origin(),
1781         root->appendNew<Value>(
1782             proc, Add, Origin(), arrayPtr,
1783             root->appendNew<ConstPtrValue>(proc, Origin(), 0)));
1784     MemoryValue* right = root->appendNew<MemoryValue>(
1785         proc, Load, Int32, Origin(),
1786         root->appendNew<Value>(
1787             proc, Add, Origin(), arrayPtr,
1788             root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))));
1789     root->appendNew<MemoryValue>(
1790         proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, 0);
1791     root->appendNew<MemoryValue>(
1792         proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, sizeof(int));
1793     root->appendNew<ControlValue>(
1794         proc, Return, Origin(),
1795         root->appendNew<Value>(
1796             proc, Add, Origin(), left, right));
1797     
1798     CHECK(compileAndRun<int>(proc, &array[0]) == 1 + 2);
1799     CHECK(array[0] == 666);
1800     CHECK(array[1] == 666);
1801 }
1802
1803 void testLoadOffsetUsingAddNotConstant()
1804 {
1805     Procedure proc;
1806     BasicBlock* root = proc.addBlock();
1807     int array[] = { 1, 2 };
1808     Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1809     root->appendNew<ControlValue>(
1810         proc, Return, Origin(),
1811         root->appendNew<Value>(
1812             proc, Add, Origin(),
1813             root->appendNew<MemoryValue>(
1814                 proc, Load, Int32, Origin(),
1815                 root->appendNew<Value>(
1816                     proc, Add, Origin(), arrayPtr,
1817                     root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
1818             root->appendNew<MemoryValue>(
1819                 proc, Load, Int32, Origin(),
1820                 root->appendNew<Value>(
1821                     proc, Add, Origin(), arrayPtr,
1822                     root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
1823     
1824     CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
1825 }
1826
1827 void testFramePointer()
1828 {
1829     Procedure proc;
1830     BasicBlock* root = proc.addBlock();
1831     root->appendNew<ControlValue>(
1832         proc, Return, Origin(),
1833         root->appendNew<Value>(proc, FramePointer, Origin()));
1834
1835     void* fp = compileAndRun<void*>(proc);
1836     CHECK(fp < &proc);
1837     CHECK(fp >= bitwise_cast<char*>(&proc) - 10000);
1838 }
1839
1840 void testStackSlot()
1841 {
1842     Procedure proc;
1843     BasicBlock* root = proc.addBlock();
1844     root->appendNew<ControlValue>(
1845         proc, Return, Origin(),
1846         root->appendNew<StackSlotValue>(proc, Origin(), 1, StackSlotKind::Anonymous));
1847
1848     void* stackSlot = compileAndRun<void*>(proc);
1849     CHECK(stackSlot < &proc);
1850     CHECK(stackSlot >= bitwise_cast<char*>(&proc) - 10000);
1851 }
1852
1853 void testLoadFromFramePointer()
1854 {
1855     Procedure proc;
1856     BasicBlock* root = proc.addBlock();
1857     root->appendNew<ControlValue>(
1858         proc, Return, Origin(),
1859         root->appendNew<MemoryValue>(
1860             proc, Load, pointerType(), Origin(),
1861             root->appendNew<Value>(proc, FramePointer, Origin())));
1862
1863     void* fp = compileAndRun<void*>(proc);
1864     void* myFP = __builtin_frame_address(0);
1865     CHECK(fp <= myFP);
1866     CHECK(fp >= bitwise_cast<char*>(myFP) - 10000);
1867 }
1868
1869 void testStoreLoadStackSlot(int value)
1870 {
1871     Procedure proc;
1872     BasicBlock* root = proc.addBlock();
1873
1874     StackSlotValue* stack = root->appendNew<StackSlotValue>(
1875         proc, Origin(), sizeof(int), StackSlotKind::Anonymous);
1876
1877     root->appendNew<MemoryValue>(
1878         proc, Store, Origin(),
1879         root->appendNew<Value>(
1880             proc, Trunc, Origin(),
1881             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1882         stack);
1883     
1884     root->appendNew<ControlValue>(
1885         proc, Return, Origin(),
1886         root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), stack));
1887
1888     CHECK(compileAndRun<int>(proc, value) == value);
1889 }
1890
1891 template<typename T>
1892 int32_t modelLoad(int32_t value)
1893 {
1894     union {
1895         int32_t original;
1896         T loaded;
1897     } u;
1898
1899     u.original = value;
1900     if (std::is_signed<T>::value)
1901         return static_cast<int32_t>(u.loaded);
1902     return static_cast<int32_t>(static_cast<uint32_t>(u.loaded));
1903 }
1904
1905 template<typename T>
1906 void testLoad(B3::Opcode opcode, int32_t value)
1907 {
1908     // Simple load from an absolute address.
1909     {
1910         Procedure proc;
1911         BasicBlock* root = proc.addBlock();
1912         
1913         root->appendNew<ControlValue>(
1914             proc, Return, Origin(),
1915             root->appendNew<MemoryValue>(
1916                 proc, opcode, Int32, Origin(),
1917                 root->appendNew<ConstPtrValue>(proc, Origin(), &value)));
1918
1919         CHECK(compileAndRun<int32_t>(proc) == modelLoad<T>(value));
1920     }
1921     
1922     // Simple load from an address in a register.
1923     {
1924         Procedure proc;
1925         BasicBlock* root = proc.addBlock();
1926         
1927         root->appendNew<ControlValue>(
1928             proc, Return, Origin(),
1929             root->appendNew<MemoryValue>(
1930                 proc, opcode, Int32, Origin(),
1931                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1932
1933         CHECK(compileAndRun<int32_t>(proc, &value) == modelLoad<T>(value));
1934     }
1935     
1936     // Simple load from an address in a register, at an offset.
1937     {
1938         Procedure proc;
1939         BasicBlock* root = proc.addBlock();
1940         
1941         root->appendNew<ControlValue>(
1942             proc, Return, Origin(),
1943             root->appendNew<MemoryValue>(
1944                 proc, opcode, Int32, Origin(),
1945                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1946                 sizeof(int32_t)));
1947
1948         CHECK(compileAndRun<int32_t>(proc, &value - 1) == modelLoad<T>(value));
1949     }
1950
1951     // Load from a simple base-index with various scales.
1952     for (unsigned logScale = 0; logScale <= 3; ++logScale) {
1953         Procedure proc;
1954         BasicBlock* root = proc.addBlock();
1955
1956         root->appendNew<ControlValue>(
1957             proc, Return, Origin(),
1958             root->appendNew<MemoryValue>(
1959                 proc, opcode, Int32, Origin(),
1960                 root->appendNew<Value>(
1961                     proc, Add, Origin(),
1962                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1963                     root->appendNew<Value>(
1964                         proc, Shl, Origin(),
1965                         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
1966                         root->appendNew<Const32Value>(proc, Origin(), logScale)))));
1967
1968         CHECK(compileAndRun<int32_t>(proc, &value - 2, (sizeof(int32_t) * 2) >> logScale) == modelLoad<T>(value));
1969     }
1970
1971     // Load from a simple base-index with various scales, but commuted.
1972     for (unsigned logScale = 0; logScale <= 3; ++logScale) {
1973         Procedure proc;
1974         BasicBlock* root = proc.addBlock();
1975
1976         root->appendNew<ControlValue>(
1977             proc, Return, Origin(),
1978             root->appendNew<MemoryValue>(
1979                 proc, opcode, Int32, Origin(),
1980                 root->appendNew<Value>(
1981                     proc, Add, Origin(),
1982                     root->appendNew<Value>(
1983                         proc, Shl, Origin(),
1984                         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
1985                         root->appendNew<Const32Value>(proc, Origin(), logScale)),
1986                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1987
1988         CHECK(compileAndRun<int32_t>(proc, &value - 2, (sizeof(int32_t) * 2) >> logScale) == modelLoad<T>(value));
1989     }
1990 }
1991
1992 void testSpillGP()
1993 {
1994     Procedure proc;
1995     BasicBlock* root = proc.addBlock();
1996
1997     Vector<Value*> sources;
1998     sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1999     sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2000
2001     for (unsigned i = 0; i < 30; ++i) {
2002         sources.append(
2003             root->appendNew<Value>(proc, Add, Origin(), sources[sources.size() - 1], sources[sources.size() - 2])
2004         );
2005     }
2006
2007     Value* total = root->appendNew<Const64Value>(proc, Origin(), 0);
2008     for (Value* value : sources)
2009         total = root->appendNew<Value>(proc, Add, Origin(), total, value);
2010
2011     root->appendNew<ControlValue>(proc, Return, Origin(), total);
2012     compileAndRun<int>(proc, 1, 2);
2013 }
2014
2015 void testBranch()
2016 {
2017     Procedure proc;
2018     BasicBlock* root = proc.addBlock();
2019     BasicBlock* thenCase = proc.addBlock();
2020     BasicBlock* elseCase = proc.addBlock();
2021
2022     root->appendNew<ControlValue>(
2023         proc, Branch, Origin(),
2024         root->appendNew<Value>(
2025             proc, Trunc, Origin(),
2026             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2027         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2028
2029     thenCase->appendNew<ControlValue>(
2030         proc, Return, Origin(),
2031         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2032
2033     elseCase->appendNew<ControlValue>(
2034         proc, Return, Origin(),
2035         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2036
2037     auto code = compile(proc);
2038     CHECK(invoke<int>(*code, 42) == 1);
2039     CHECK(invoke<int>(*code, 0) == 0);
2040 }
2041
2042 void testBranchPtr()
2043 {
2044     Procedure proc;
2045     BasicBlock* root = proc.addBlock();
2046     BasicBlock* thenCase = proc.addBlock();
2047     BasicBlock* elseCase = proc.addBlock();
2048
2049     root->appendNew<ControlValue>(
2050         proc, Branch, Origin(),
2051         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2052         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2053
2054     thenCase->appendNew<ControlValue>(
2055         proc, Return, Origin(),
2056         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2057
2058     elseCase->appendNew<ControlValue>(
2059         proc, Return, Origin(),
2060         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2061
2062     auto code = compile(proc);
2063     CHECK(invoke<int>(*code, static_cast<intptr_t>(42)) == 1);
2064     CHECK(invoke<int>(*code, static_cast<intptr_t>(0)) == 0);
2065 }
2066
2067 void testDiamond()
2068 {
2069     Procedure proc;
2070     BasicBlock* root = proc.addBlock();
2071     BasicBlock* thenCase = proc.addBlock();
2072     BasicBlock* elseCase = proc.addBlock();
2073     BasicBlock* done = proc.addBlock();
2074
2075     root->appendNew<ControlValue>(
2076         proc, Branch, Origin(),
2077         root->appendNew<Value>(
2078             proc, Trunc, Origin(),
2079             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2080         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2081
2082     UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
2083         proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2084     thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
2085
2086     UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
2087         proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2088     elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
2089
2090     Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
2091     thenResult->setPhi(phi);
2092     elseResult->setPhi(phi);
2093     done->appendNew<ControlValue>(proc, Return, Origin(), phi);
2094
2095     auto code = compile(proc);
2096     CHECK(invoke<int>(*code, 42) == 1);
2097     CHECK(invoke<int>(*code, 0) == 0);
2098 }
2099
2100 void testBranchNotEqual()
2101 {
2102     Procedure proc;
2103     BasicBlock* root = proc.addBlock();
2104     BasicBlock* thenCase = proc.addBlock();
2105     BasicBlock* elseCase = proc.addBlock();
2106
2107     root->appendNew<ControlValue>(
2108         proc, Branch, Origin(),
2109         root->appendNew<Value>(
2110             proc, NotEqual, Origin(),
2111             root->appendNew<Value>(
2112                 proc, Trunc, Origin(),
2113                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2114             root->appendNew<Const32Value>(proc, Origin(), 0)),
2115         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2116
2117     thenCase->appendNew<ControlValue>(
2118         proc, Return, Origin(),
2119         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2120
2121     elseCase->appendNew<ControlValue>(
2122         proc, Return, Origin(),
2123         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2124
2125     auto code = compile(proc);
2126     CHECK(invoke<int>(*code, 42) == 1);
2127     CHECK(invoke<int>(*code, 0) == 0);
2128 }
2129
2130 void testBranchNotEqualCommute()
2131 {
2132     Procedure proc;
2133     BasicBlock* root = proc.addBlock();
2134     BasicBlock* thenCase = proc.addBlock();
2135     BasicBlock* elseCase = proc.addBlock();
2136
2137     root->appendNew<ControlValue>(
2138         proc, Branch, Origin(),
2139         root->appendNew<Value>(
2140             proc, NotEqual, Origin(),
2141             root->appendNew<Const32Value>(proc, Origin(), 0),
2142             root->appendNew<Value>(
2143                 proc, Trunc, Origin(),
2144                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
2145         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2146
2147     thenCase->appendNew<ControlValue>(
2148         proc, Return, Origin(),
2149         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2150
2151     elseCase->appendNew<ControlValue>(
2152         proc, Return, Origin(),
2153         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2154
2155     auto code = compile(proc);
2156     CHECK(invoke<int>(*code, 42) == 1);
2157     CHECK(invoke<int>(*code, 0) == 0);
2158 }
2159
2160 void testBranchNotEqualNotEqual()
2161 {
2162     Procedure proc;
2163     BasicBlock* root = proc.addBlock();
2164     BasicBlock* thenCase = proc.addBlock();
2165     BasicBlock* elseCase = proc.addBlock();
2166
2167     root->appendNew<ControlValue>(
2168         proc, Branch, Origin(),
2169         root->appendNew<Value>(
2170             proc, NotEqual, Origin(),
2171             root->appendNew<Value>(
2172                 proc, NotEqual, Origin(),
2173                 root->appendNew<Value>(
2174                     proc, Trunc, Origin(),
2175                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2176                 root->appendNew<Const32Value>(proc, Origin(), 0)),
2177             root->appendNew<Const32Value>(proc, Origin(), 0)),
2178         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2179
2180     thenCase->appendNew<ControlValue>(
2181         proc, Return, Origin(),
2182         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2183
2184     elseCase->appendNew<ControlValue>(
2185         proc, Return, Origin(),
2186         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2187
2188     auto code = compile(proc);
2189     CHECK(invoke<int>(*code, 42) == 1);
2190     CHECK(invoke<int>(*code, 0) == 0);
2191 }
2192
2193 void testBranchEqual()
2194 {
2195     Procedure proc;
2196     BasicBlock* root = proc.addBlock();
2197     BasicBlock* thenCase = proc.addBlock();
2198     BasicBlock* elseCase = proc.addBlock();
2199
2200     root->appendNew<ControlValue>(
2201         proc, Branch, Origin(),
2202         root->appendNew<Value>(
2203             proc, Equal, Origin(),
2204             root->appendNew<Value>(
2205                 proc, Trunc, Origin(),
2206                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2207             root->appendNew<Const32Value>(proc, Origin(), 0)),
2208         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2209
2210     thenCase->appendNew<ControlValue>(
2211         proc, Return, Origin(),
2212         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
2213
2214     elseCase->appendNew<ControlValue>(
2215         proc, Return, Origin(),
2216         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
2217
2218     auto code = compile(proc);
2219     CHECK(invoke<int>(*code, 42) == 1);
2220     CHECK(invoke<int>(*code, 0) == 0);
2221 }
2222
2223 void testBranchEqualEqual()
2224 {
2225     Procedure proc;
2226     BasicBlock* root = proc.addBlock();
2227     BasicBlock* thenCase = proc.addBlock();
2228     BasicBlock* elseCase = proc.addBlock();
2229
2230     root->appendNew<ControlValue>(
2231         proc, Branch, Origin(),
2232         root->appendNew<Value>(
2233             proc, Equal, Origin(),
2234             root->appendNew<Value>(
2235                 proc, Equal, Origin(),
2236                 root->appendNew<Value>(
2237                     proc, Trunc, Origin(),
2238                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2239                 root->appendNew<Const32Value>(proc, Origin(), 0)),
2240             root->appendNew<Const32Value>(proc, Origin(), 0)),
2241         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2242
2243     thenCase->appendNew<ControlValue>(
2244         proc, Return, Origin(),
2245         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2246
2247     elseCase->appendNew<ControlValue>(
2248         proc, Return, Origin(),
2249         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2250
2251     auto code = compile(proc);
2252     CHECK(invoke<int>(*code, 42) == 1);
2253     CHECK(invoke<int>(*code, 0) == 0);
2254 }
2255
2256 void testBranchEqualCommute()
2257 {
2258     Procedure proc;
2259     BasicBlock* root = proc.addBlock();
2260     BasicBlock* thenCase = proc.addBlock();
2261     BasicBlock* elseCase = proc.addBlock();
2262
2263     root->appendNew<ControlValue>(
2264         proc, Branch, Origin(),
2265         root->appendNew<Value>(
2266             proc, Equal, Origin(),
2267             root->appendNew<Const32Value>(proc, Origin(), 0),
2268             root->appendNew<Value>(
2269                 proc, Trunc, Origin(),
2270                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
2271         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2272
2273     thenCase->appendNew<ControlValue>(
2274         proc, Return, Origin(),
2275         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
2276
2277     elseCase->appendNew<ControlValue>(
2278         proc, Return, Origin(),
2279         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
2280
2281     auto code = compile(proc);
2282     CHECK(invoke<int>(*code, 42) == 1);
2283     CHECK(invoke<int>(*code, 0) == 0);
2284 }
2285
2286 void testBranchEqualEqual1()
2287 {
2288     Procedure proc;
2289     BasicBlock* root = proc.addBlock();
2290     BasicBlock* thenCase = proc.addBlock();
2291     BasicBlock* elseCase = proc.addBlock();
2292
2293     root->appendNew<ControlValue>(
2294         proc, Branch, Origin(),
2295         root->appendNew<Value>(
2296             proc, Equal, Origin(),
2297             root->appendNew<Value>(
2298                 proc, Equal, Origin(),
2299                 root->appendNew<Value>(
2300                     proc, Trunc, Origin(),
2301                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2302                 root->appendNew<Const32Value>(proc, Origin(), 0)),
2303             root->appendNew<Const32Value>(proc, Origin(), 1)),
2304         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2305
2306     thenCase->appendNew<ControlValue>(
2307         proc, Return, Origin(),
2308         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
2309
2310     elseCase->appendNew<ControlValue>(
2311         proc, Return, Origin(),
2312         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
2313
2314     auto code = compile(proc);
2315     CHECK(invoke<int>(*code, 42) == 1);
2316     CHECK(invoke<int>(*code, 0) == 0);
2317 }
2318
2319 void testBranchFold(int value)
2320 {
2321     Procedure proc;
2322     BasicBlock* root = proc.addBlock();
2323     BasicBlock* thenCase = proc.addBlock();
2324     BasicBlock* elseCase = proc.addBlock();
2325
2326     root->appendNew<ControlValue>(
2327         proc, Branch, Origin(),
2328         root->appendNew<Const32Value>(proc, Origin(), value),
2329         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2330
2331     thenCase->appendNew<ControlValue>(
2332         proc, Return, Origin(),
2333         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2334
2335     elseCase->appendNew<ControlValue>(
2336         proc, Return, Origin(),
2337         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2338
2339     CHECK(compileAndRun<int>(proc) == !!value);
2340 }
2341
2342 void testDiamondFold(int value)
2343 {
2344     Procedure proc;
2345     BasicBlock* root = proc.addBlock();
2346     BasicBlock* thenCase = proc.addBlock();
2347     BasicBlock* elseCase = proc.addBlock();
2348     BasicBlock* done = proc.addBlock();
2349
2350     root->appendNew<ControlValue>(
2351         proc, Branch, Origin(),
2352         root->appendNew<Const32Value>(proc, Origin(), value),
2353         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2354
2355     UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
2356         proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2357     thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
2358
2359     UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
2360         proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2361     elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
2362
2363     Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
2364     thenResult->setPhi(phi);
2365     elseResult->setPhi(phi);
2366     done->appendNew<ControlValue>(proc, Return, Origin(), phi);
2367
2368     CHECK(compileAndRun<int>(proc) == !!value);
2369 }
2370
2371 void testBranchNotEqualFoldPtr(intptr_t value)
2372 {
2373     Procedure proc;
2374     BasicBlock* root = proc.addBlock();
2375     BasicBlock* thenCase = proc.addBlock();
2376     BasicBlock* elseCase = proc.addBlock();
2377
2378     root->appendNew<ControlValue>(
2379         proc, Branch, Origin(),
2380         root->appendNew<Value>(
2381             proc, NotEqual, Origin(),
2382             root->appendNew<ConstPtrValue>(proc, Origin(), value),
2383             root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
2384         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2385
2386     thenCase->appendNew<ControlValue>(
2387         proc, Return, Origin(),
2388         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2389
2390     elseCase->appendNew<ControlValue>(
2391         proc, Return, Origin(),
2392         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2393
2394     CHECK(compileAndRun<int>(proc) == !!value);
2395 }
2396
2397 void testBranchEqualFoldPtr(intptr_t value)
2398 {
2399     Procedure proc;
2400     BasicBlock* root = proc.addBlock();
2401     BasicBlock* thenCase = proc.addBlock();
2402     BasicBlock* elseCase = proc.addBlock();
2403
2404     root->appendNew<ControlValue>(
2405         proc, Branch, Origin(),
2406         root->appendNew<Value>(
2407             proc, Equal, Origin(),
2408             root->appendNew<ConstPtrValue>(proc, Origin(), value),
2409             root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
2410         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2411
2412     thenCase->appendNew<ControlValue>(
2413         proc, Return, Origin(),
2414         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
2415
2416     elseCase->appendNew<ControlValue>(
2417         proc, Return, Origin(),
2418         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2419
2420     CHECK(compileAndRun<int>(proc) == !value);
2421 }
2422
2423 void testComplex(unsigned numVars, unsigned numConstructs)
2424 {
2425     double before = monotonicallyIncreasingTimeMS();
2426     
2427     Procedure proc;
2428     BasicBlock* current = proc.addBlock();
2429
2430     Const32Value* one = current->appendNew<Const32Value>(proc, Origin(), 1);
2431
2432     Vector<int32_t> varSlots;
2433     for (unsigned i = numVars; i--;)
2434         varSlots.append(i);
2435
2436     Vector<Value*> vars;
2437     for (int32_t& varSlot : varSlots) {
2438         Value* varSlotPtr = current->appendNew<ConstPtrValue>(proc, Origin(), &varSlot);
2439         vars.append(current->appendNew<MemoryValue>(proc, Load, Int32, Origin(), varSlotPtr));
2440     }
2441
2442     for (unsigned i = 0; i < numConstructs; ++i) {
2443         if (i & 1) {
2444             // Control flow diamond.
2445             unsigned predicateVarIndex = (i >> 1) % numVars;
2446             unsigned thenIncVarIndex = ((i >> 1) + 1) % numVars;
2447             unsigned elseIncVarIndex = ((i >> 1) + 2) % numVars;
2448
2449             BasicBlock* thenBlock = proc.addBlock();
2450             BasicBlock* elseBlock = proc.addBlock();
2451             BasicBlock* continuation = proc.addBlock();
2452
2453             current->appendNew<ControlValue>(
2454                 proc, Branch, Origin(), vars[predicateVarIndex],
2455                 FrequentedBlock(thenBlock), FrequentedBlock(elseBlock));
2456
2457             UpsilonValue* thenThenResult = thenBlock->appendNew<UpsilonValue>(
2458                 proc, Origin(),
2459                 thenBlock->appendNew<Value>(proc, Add, Origin(), vars[thenIncVarIndex], one));
2460             UpsilonValue* thenElseResult = thenBlock->appendNew<UpsilonValue>(
2461                 proc, Origin(), vars[elseIncVarIndex]);
2462             thenBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
2463
2464             UpsilonValue* elseElseResult = elseBlock->appendNew<UpsilonValue>(
2465                 proc, Origin(),
2466                 elseBlock->appendNew<Value>(proc, Add, Origin(), vars[elseIncVarIndex], one));
2467             UpsilonValue* elseThenResult = elseBlock->appendNew<UpsilonValue>(
2468                 proc, Origin(), vars[thenIncVarIndex]);
2469             elseBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
2470
2471             Value* thenPhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
2472             thenThenResult->setPhi(thenPhi);
2473             elseThenResult->setPhi(thenPhi);
2474             vars[thenIncVarIndex] = thenPhi;
2475             
2476             Value* elsePhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
2477             thenElseResult->setPhi(elsePhi);
2478             elseElseResult->setPhi(elsePhi);
2479             vars[elseIncVarIndex] = thenPhi;
2480             
2481             current = continuation;
2482         } else {
2483             // Loop.
2484
2485             BasicBlock* loopEntry = proc.addBlock();
2486             BasicBlock* loopReentry = proc.addBlock();
2487             BasicBlock* loopBody = proc.addBlock();
2488             BasicBlock* loopExit = proc.addBlock();
2489             BasicBlock* loopSkip = proc.addBlock();
2490             BasicBlock* continuation = proc.addBlock();
2491             
2492             Value* startIndex = vars[(i >> 1) % numVars];
2493             Value* startSum = current->appendNew<Const32Value>(proc, Origin(), 0);
2494             current->appendNew<ControlValue>(
2495                 proc, Branch, Origin(), startIndex,
2496                 FrequentedBlock(loopEntry), FrequentedBlock(loopSkip));
2497
2498             UpsilonValue* startIndexForBody = loopEntry->appendNew<UpsilonValue>(
2499                 proc, Origin(), startIndex);
2500             UpsilonValue* startSumForBody = loopEntry->appendNew<UpsilonValue>(
2501                 proc, Origin(), startSum);
2502             loopEntry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
2503
2504             Value* bodyIndex = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
2505             startIndexForBody->setPhi(bodyIndex);
2506             Value* bodySum = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
2507             startSumForBody->setPhi(bodySum);
2508             Value* newBodyIndex = loopBody->appendNew<Value>(proc, Sub, Origin(), bodyIndex, one);
2509             Value* newBodySum = loopBody->appendNew<Value>(
2510                 proc, Add, Origin(),
2511                 bodySum,
2512                 loopBody->appendNew<MemoryValue>(
2513                     proc, Load, Int32, Origin(),
2514                     loopBody->appendNew<Value>(
2515                         proc, Add, Origin(),
2516                         loopBody->appendNew<ConstPtrValue>(proc, Origin(), varSlots.data()),
2517                         loopBody->appendNew<Value>(
2518                             proc, Shl, Origin(),
2519                             loopBody->appendNew<Value>(
2520                                 proc, ZExt32, Origin(),
2521                                 loopBody->appendNew<Value>(
2522                                     proc, BitAnd, Origin(),
2523                                     newBodyIndex,
2524                                     loopBody->appendNew<Const32Value>(
2525                                         proc, Origin(), numVars - 1))),
2526                             loopBody->appendNew<Const32Value>(proc, Origin(), 2)))));
2527             loopBody->appendNew<ControlValue>(
2528                 proc, Branch, Origin(), newBodyIndex,
2529                 FrequentedBlock(loopReentry), FrequentedBlock(loopExit));
2530
2531             loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodyIndex, bodyIndex);
2532             loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodySum, bodySum);
2533             loopReentry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
2534
2535             UpsilonValue* exitSum = loopExit->appendNew<UpsilonValue>(proc, Origin(), newBodySum);
2536             loopExit->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
2537
2538             UpsilonValue* skipSum = loopSkip->appendNew<UpsilonValue>(proc, Origin(), startSum);
2539             loopSkip->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
2540
2541             Value* finalSum = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
2542             exitSum->setPhi(finalSum);
2543             skipSum->setPhi(finalSum);
2544
2545             current = continuation;
2546             vars[((i >> 1) + 1) % numVars] = finalSum;
2547         }
2548     }
2549
2550     current->appendNew<ControlValue>(proc, Return, Origin(), vars[0]);
2551
2552     compile(proc);
2553
2554     double after = monotonicallyIncreasingTimeMS();
2555     dataLog(toCString("    That took ", after - before, " ms.\n"));
2556 }
2557
2558 void testSimplePatchpoint()
2559 {
2560     Procedure proc;
2561     BasicBlock* root = proc.addBlock();
2562     Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2563     Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2564     PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
2565     patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
2566     patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
2567     patchpoint->setGenerator(
2568         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2569             CHECK(params.reps.size() == 3);
2570             CHECK(params.reps[0].isGPR());
2571             CHECK(params.reps[1].isGPR());
2572             CHECK(params.reps[2].isGPR());
2573             jit.move(params.reps[1].gpr(), params.reps[0].gpr());
2574             jit.add32(params.reps[2].gpr(), params.reps[0].gpr());
2575         });
2576     root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
2577
2578     CHECK(compileAndRun<int>(proc, 1, 2) == 3);
2579 }
2580
2581 void testPatchpointCallArg()
2582 {
2583     Procedure proc;
2584     BasicBlock* root = proc.addBlock();
2585     Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2586     Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2587     PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
2588     patchpoint->append(ConstrainedValue(arg1, ValueRep::stackArgument(0)));
2589     patchpoint->append(ConstrainedValue(arg2, ValueRep::stackArgument(8)));
2590     patchpoint->setGenerator(
2591         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2592             CHECK(params.reps.size() == 3);
2593             CHECK(params.reps[0].isGPR());
2594             CHECK(params.reps[1].isStack());
2595             CHECK(params.reps[2].isStack());
2596             jit.load32(
2597                 CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[1].offsetFromFP()),
2598                 params.reps[0].gpr());
2599             jit.add32(
2600                 CCallHelpers::Address(GPRInfo::callFrameRegister, params.reps[2].offsetFromFP()),
2601                 params.reps[0].gpr());
2602         });
2603     root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
2604
2605     CHECK(compileAndRun<int>(proc, 1, 2) == 3);
2606 }
2607
2608 void testSimpleCheck()
2609 {
2610     Procedure proc;
2611     BasicBlock* root = proc.addBlock();
2612     Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2613     CheckValue* check = root->appendNew<CheckValue>(proc, Check, Origin(), arg);
2614     check->setGenerator(
2615         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2616             CHECK(params.reps.size() == 1);
2617             CHECK(params.reps[0].isConstant());
2618             CHECK(params.reps[0].value() == 1);
2619
2620             // This should always work because a function this simple should never have callee
2621             // saves.
2622             jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
2623             jit.emitFunctionEpilogue();
2624             jit.ret();
2625         });
2626     root->appendNew<ControlValue>(
2627         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2628
2629     auto code = compile(proc);
2630     
2631     CHECK(invoke<int>(*code, 0) == 0);
2632     CHECK(invoke<int>(*code, 1) == 42);
2633 }
2634
2635 void testCheckLessThan()
2636 {
2637     Procedure proc;
2638     BasicBlock* root = proc.addBlock();
2639     Value* arg = root->appendNew<Value>(
2640         proc, Trunc, Origin(),
2641         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2642     CheckValue* check = root->appendNew<CheckValue>(
2643         proc, Check, Origin(),
2644         root->appendNew<Value>(
2645             proc, LessThan, Origin(), arg,
2646             root->appendNew<Const32Value>(proc, Origin(), 42)));
2647     check->setGenerator(
2648         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2649             CHECK(params.reps.size() == 1);
2650             CHECK(params.reps[0].isConstant());
2651             CHECK(params.reps[0].value() == 1);
2652
2653             // This should always work because a function this simple should never have callee
2654             // saves.
2655             jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
2656             jit.emitFunctionEpilogue();
2657             jit.ret();
2658         });
2659     root->appendNew<ControlValue>(
2660         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2661
2662     auto code = compile(proc);
2663     
2664     CHECK(invoke<int>(*code, 42) == 0);
2665     CHECK(invoke<int>(*code, 1000) == 0);
2666     CHECK(invoke<int>(*code, 41) == 42);
2667     CHECK(invoke<int>(*code, 0) == 42);
2668     CHECK(invoke<int>(*code, -1) == 42);
2669 }
2670
2671 void testCheckMegaCombo()
2672 {
2673     Procedure proc;
2674     BasicBlock* root = proc.addBlock();
2675     Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2676     Value* index = root->appendNew<Value>(
2677         proc, ZExt32, Origin(),
2678         root->appendNew<Value>(
2679             proc, Trunc, Origin(),
2680             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2681
2682     Value* ptr = root->appendNew<Value>(
2683         proc, Add, Origin(), base,
2684         root->appendNew<Value>(
2685             proc, Shl, Origin(), index,
2686             root->appendNew<Const32Value>(proc, Origin(), 1)));
2687     
2688     CheckValue* check = root->appendNew<CheckValue>(
2689         proc, Check, Origin(),
2690         root->appendNew<Value>(
2691             proc, LessThan, Origin(),
2692             root->appendNew<MemoryValue>(proc, Load8S, Origin(), ptr),
2693             root->appendNew<Const32Value>(proc, Origin(), 42)));
2694     check->setGenerator(
2695         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2696             CHECK(params.reps.size() == 1);
2697             CHECK(params.reps[0].isConstant());
2698             CHECK(params.reps[0].value() == 1);
2699
2700             // This should always work because a function this simple should never have callee
2701             // saves.
2702             jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
2703             jit.emitFunctionEpilogue();
2704             jit.ret();
2705         });
2706     root->appendNew<ControlValue>(
2707         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2708
2709     auto code = compile(proc);
2710
2711     int8_t value;
2712     value = 42;
2713     CHECK(invoke<int>(*code, &value - 2, 1) == 0);
2714     value = 127;
2715     CHECK(invoke<int>(*code, &value - 2, 1) == 0);
2716     value = 41;
2717     CHECK(invoke<int>(*code, &value - 2, 1) == 42);
2718     value = 0;
2719     CHECK(invoke<int>(*code, &value - 2, 1) == 42);
2720     value = -1;
2721     CHECK(invoke<int>(*code, &value - 2, 1) == 42);
2722 }
2723
2724 template<typename LeftFunctor, typename RightFunctor>
2725 void genericTestCompare(
2726     B3::Opcode opcode, const LeftFunctor& leftFunctor, const RightFunctor& rightFunctor,
2727     int left, int right, int result)
2728 {
2729     // Using a compare.
2730     {
2731         Procedure proc;
2732         BasicBlock* root = proc.addBlock();
2733
2734         Value* leftValue = leftFunctor(root, proc);
2735         Value* rightValue = rightFunctor(root, proc);
2736         
2737         root->appendNew<ControlValue>(
2738             proc, Return, Origin(),
2739             root->appendNew<Value>(
2740                 proc, NotEqual, Origin(),
2741                 root->appendNew<Value>(proc, opcode, Origin(), leftValue, rightValue),
2742                 root->appendNew<Const32Value>(proc, Origin(), 0)));
2743
2744         CHECK(compileAndRun<int>(proc, left, right) == result);
2745     }
2746     
2747     // Using a branch.
2748     {
2749         Procedure proc;
2750         BasicBlock* root = proc.addBlock();
2751         BasicBlock* thenCase = proc.addBlock();
2752         BasicBlock* elseCase = proc.addBlock();
2753
2754         Value* leftValue = leftFunctor(root, proc);
2755         Value* rightValue = rightFunctor(root, proc);
2756
2757         root->appendNew<ControlValue>(
2758             proc, Branch, Origin(),
2759             root->appendNew<Value>(proc, opcode, Origin(), leftValue, rightValue),
2760             FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2761
2762         // We use a patchpoint on the then case to ensure that this doesn't get if-converted.
2763         PatchpointValue* patchpoint = thenCase->appendNew<PatchpointValue>(proc, Int32, Origin());
2764         patchpoint->setGenerator(
2765             [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
2766                 CHECK(params.reps.size() == 1);
2767                 CHECK(params.reps[0].isGPR());
2768                 jit.move(CCallHelpers::TrustedImm32(1), params.reps[0].gpr());
2769             });
2770         thenCase->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
2771
2772         elseCase->appendNew<ControlValue>(
2773             proc, Return, Origin(),
2774             elseCase->appendNew<Const32Value>(proc, Origin(), 0));
2775
2776         CHECK(compileAndRun<int>(proc, left, right) == result);
2777     }
2778 }
2779
2780 int modelCompare(B3::Opcode opcode, int left, int right)
2781 {
2782     switch (opcode) {
2783     case Equal:
2784         return left == right;
2785     case NotEqual:
2786         return left != right;
2787     case LessThan:
2788         return left < right;
2789     case GreaterThan:
2790         return left > right;
2791     case LessEqual:
2792         return left <= right;
2793     case GreaterEqual:
2794         return left >= right;
2795     case Above:
2796         return static_cast<unsigned>(left) > static_cast<unsigned>(right);
2797     case Below:
2798         return static_cast<unsigned>(left) < static_cast<unsigned>(right);
2799     case AboveEqual:
2800         return static_cast<unsigned>(left) >= static_cast<unsigned>(right);
2801     case BelowEqual:
2802         return static_cast<unsigned>(left) <= static_cast<unsigned>(right);
2803     case BitAnd:
2804         return !!(left & right);
2805     default:
2806         RELEASE_ASSERT_NOT_REACHED();
2807         return 0;
2808     }
2809 }
2810
2811 template<typename T>
2812 void testCompareLoad(B3::Opcode opcode, B3::Opcode loadOpcode, int left, int right)
2813 {
2814     int result = modelCompare(opcode, modelLoad<T>(left), right);
2815     
2816     // Test addr-to-tmp
2817     int slot = left;
2818     genericTestCompare(
2819         opcode,
2820         [&] (BasicBlock* block, Procedure& proc) {
2821             return block->appendNew<MemoryValue>(
2822                 proc, loadOpcode, Int32, Origin(),
2823                 block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
2824         },
2825         [&] (BasicBlock* block, Procedure& proc) {
2826             return block->appendNew<Value>(
2827                 proc, Trunc, Origin(),
2828                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2829         },
2830         left, right, result);
2831
2832     // Test addr-to-imm
2833     slot = left;
2834     genericTestCompare(
2835         opcode,
2836         [&] (BasicBlock* block, Procedure& proc) {
2837             return block->appendNew<MemoryValue>(
2838                 proc, loadOpcode, Int32, Origin(),
2839                 block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
2840         },
2841         [&] (BasicBlock* block, Procedure& proc) {
2842             return block->appendNew<Const32Value>(proc, Origin(), right);
2843         },
2844         left, right, result);
2845
2846     result = modelCompare(opcode, left, modelLoad<T>(right));
2847     
2848     // Test tmp-to-addr
2849     slot = right;
2850     genericTestCompare(
2851         opcode,
2852         [&] (BasicBlock* block, Procedure& proc) {
2853             return block->appendNew<Value>(
2854                 proc, Trunc, Origin(),
2855                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2856         },
2857         [&] (BasicBlock* block, Procedure& proc) {
2858             return block->appendNew<MemoryValue>(
2859                 proc, loadOpcode, Int32, Origin(),
2860                 block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
2861         },
2862         left, right, result);
2863
2864     // Test imm-to-addr
2865     slot = right;
2866     genericTestCompare(
2867         opcode,
2868         [&] (BasicBlock* block, Procedure& proc) {
2869             return block->appendNew<Const32Value>(proc, Origin(), left);
2870         },
2871         [&] (BasicBlock* block, Procedure& proc) {
2872             return block->appendNew<MemoryValue>(
2873                 proc, loadOpcode, Int32, Origin(),
2874                 block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
2875         },
2876         left, right, result);
2877
2878     // Test addr-to-addr, with the same addr.
2879     slot = left;
2880     Value* value;
2881     genericTestCompare(
2882         opcode,
2883         [&] (BasicBlock* block, Procedure& proc) {
2884             value = block->appendNew<MemoryValue>(
2885                 proc, loadOpcode, Int32, Origin(),
2886                 block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
2887             return value;
2888         },
2889         [&] (BasicBlock*, Procedure&) {
2890             return value;
2891         },
2892         left, left, modelCompare(opcode, modelLoad<T>(left), modelLoad<T>(left)));
2893 }
2894
2895 void testCompareImpl(B3::Opcode opcode, int left, int right)
2896 {
2897     int result = modelCompare(opcode, left, right);
2898     
2899     // Test tmp-to-tmp.
2900     genericTestCompare(
2901         opcode,
2902         [&] (BasicBlock* block, Procedure& proc) {
2903             return block->appendNew<Value>(
2904                 proc, Trunc, Origin(),
2905                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2906         },
2907         [&] (BasicBlock* block, Procedure& proc) {
2908             return block->appendNew<Value>(
2909                 proc, Trunc, Origin(),
2910                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2911         },
2912         left, right, result);
2913
2914     // Test imm-to-tmp.
2915     genericTestCompare(
2916         opcode,
2917         [&] (BasicBlock* block, Procedure& proc) {
2918             return block->appendNew<Const32Value>(proc, Origin(), left);
2919         },
2920         [&] (BasicBlock* block, Procedure& proc) {
2921             return block->appendNew<Value>(
2922                 proc, Trunc, Origin(),
2923                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2924         },
2925         left, right, result);
2926
2927     // Test tmp-to-imm.
2928     genericTestCompare(
2929         opcode,
2930         [&] (BasicBlock* block, Procedure& proc) {
2931             return block->appendNew<Value>(
2932                 proc, Trunc, Origin(),
2933                 block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2934         },
2935         [&] (BasicBlock* block, Procedure& proc) {
2936             return block->appendNew<Const32Value>(proc, Origin(), right);
2937         },
2938         left, right, result);
2939
2940     // Test imm-to-imm.
2941     genericTestCompare(
2942         opcode,
2943         [&] (BasicBlock* block, Procedure& proc) {
2944             return block->appendNew<Const32Value>(proc, Origin(), left);
2945         },
2946         [&] (BasicBlock* block, Procedure& proc) {
2947             return block->appendNew<Const32Value>(proc, Origin(), right);
2948         },
2949         left, right, result);
2950
2951     testCompareLoad<int32_t>(opcode, Load, left, right);
2952     testCompareLoad<int8_t>(opcode, Load8S, left, right);
2953     testCompareLoad<uint8_t>(opcode, Load8Z, left, right);
2954     testCompareLoad<int16_t>(opcode, Load16S, left, right);
2955     testCompareLoad<uint16_t>(opcode, Load16Z, left, right);
2956 }
2957
2958 void testCompare(B3::Opcode opcode, int left, int right)
2959 {
2960     auto variants = [&] (int left, int right) {
2961         testCompareImpl(opcode, left, right);
2962         testCompareImpl(opcode, left, right + 1);
2963         testCompareImpl(opcode, left, right - 1);
2964
2965         auto multipliedTests = [&] (int factor) {
2966             testCompareImpl(opcode, left * factor, right);
2967             testCompareImpl(opcode, left * factor, right + 1);
2968             testCompareImpl(opcode, left * factor, right - 1);
2969         
2970             testCompareImpl(opcode, left, right * factor);
2971             testCompareImpl(opcode, left, (right + 1) * factor);
2972             testCompareImpl(opcode, left, (right - 1) * factor);
2973         
2974             testCompareImpl(opcode, left * factor, right * factor);
2975             testCompareImpl(opcode, left * factor, (right + 1) * factor);
2976             testCompareImpl(opcode, left * factor, (right - 1) * factor);
2977         };
2978
2979         multipliedTests(10);
2980         multipliedTests(100);
2981         multipliedTests(1000);
2982         multipliedTests(100000);
2983     };
2984
2985     variants(left, right);
2986     variants(-left, right);
2987     variants(left, -right);
2988     variants(-left, -right);
2989 }
2990
2991 int simpleFunction(int a, int b)
2992 {
2993     return a + b;
2994 }
2995
2996 void testCallSimple(int a, int b)
2997 {
2998     Procedure proc;
2999     BasicBlock* root = proc.addBlock();
3000     root->appendNew<ControlValue>(
3001         proc, Return, Origin(),
3002         root->appendNew<CCallValue>(
3003             proc, Int32, Origin(),
3004             root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
3005             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3006             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
3007
3008     CHECK(compileAndRun<int>(proc, a, b) == a + b);
3009 }
3010
3011 int functionWithHellaArguments(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z)
3012 {
3013     return (a << 0) + (b << 1) + (c << 2) + (d << 3) + (e << 4) + (f << 5) + (g << 6) + (h << 7) + (i << 8) + (j << 9) + (k << 10) + (l << 11) + (m << 12) + (n << 13) + (o << 14) + (p << 15) + (q << 16) + (r << 17) + (s << 18) + (t << 19) + (u << 20) + (v << 21) + (w << 22) + (x << 23) + (y << 24) + (z << 25);
3014 }
3015
3016 void testCallFunctionWithHellaArguments()
3017 {
3018     Procedure proc;
3019     BasicBlock* root = proc.addBlock();
3020
3021     Vector<Value*> args;
3022     for (unsigned i = 0; i < 26; ++i)
3023         args.append(root->appendNew<Const32Value>(proc, Origin(), i + 1));
3024
3025     CCallValue* call = root->appendNew<CCallValue>(
3026         proc, Int32, Origin(),
3027         root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(functionWithHellaArguments)));
3028     call->children().appendVector(args);
3029     
3030     root->appendNew<ControlValue>(proc, Return, Origin(), call);
3031
3032     CHECK(compileAndRun<int>(proc) == functionWithHellaArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
3033 }
3034
3035 void testReturnDouble(double value)
3036 {
3037     Procedure proc;
3038     BasicBlock* root = proc.addBlock();
3039     root->appendNew<ControlValue>(
3040         proc, Return, Origin(),
3041         root->appendNew<ConstDoubleValue>(proc, Origin(), value));
3042
3043     CHECK(isIdentical(compileAndRun<double>(proc), value));
3044 }
3045
3046 double simpleFunctionDouble(double a, double b)
3047 {
3048     return a + b;
3049 }
3050
3051 void testCallSimpleDouble(double a, double b)
3052 {
3053     Procedure proc;
3054     BasicBlock* root = proc.addBlock();
3055     root->appendNew<ControlValue>(
3056         proc, Return, Origin(),
3057         root->appendNew<CCallValue>(
3058             proc, Double, Origin(),
3059             root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunctionDouble)),
3060             root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
3061             root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
3062
3063     CHECK(compileAndRun<double>(proc, a, b) == a + b);
3064 }
3065
3066 double functionWithHellaDoubleArguments(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l, double m, double n, double o, double p, double q, double r, double s, double t, double u, double v, double w, double x, double y, double z)
3067 {
3068     return a * pow(2, 0) + b * pow(2, 1) + c * pow(2, 2) + d * pow(2, 3) + e * pow(2, 4) + f * pow(2, 5) + g * pow(2, 6) + h * pow(2, 7) + i * pow(2, 8) + j * pow(2, 9) + k * pow(2, 10) + l * pow(2, 11) + m * pow(2, 12) + n * pow(2, 13) + o * pow(2, 14) + p * pow(2, 15) + q * pow(2, 16) + r * pow(2, 17) + s * pow(2, 18) + t * pow(2, 19) + u * pow(2, 20) + v * pow(2, 21) + w * pow(2, 22) + x * pow(2, 23) + y * pow(2, 24) + z * pow(2, 25);
3069 }
3070
3071 void testCallFunctionWithHellaDoubleArguments()
3072 {
3073     Procedure proc;
3074     BasicBlock* root = proc.addBlock();
3075
3076     Vector<Value*> args;
3077     for (unsigned i = 0; i < 26; ++i)
3078         args.append(root->appendNew<ConstDoubleValue>(proc, Origin(), i + 1));
3079
3080     CCallValue* call = root->appendNew<CCallValue>(
3081         proc, Double, Origin(),
3082         root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(functionWithHellaDoubleArguments)));
3083     call->children().appendVector(args);
3084     
3085     root->appendNew<ControlValue>(proc, Return, Origin(), call);
3086
3087     CHECK(compileAndRun<double>(proc) == functionWithHellaDoubleArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
3088 }
3089
3090 void testChillDiv(int num, int den, int res)
3091 {
3092     // Test non-constant.
3093     {
3094         Procedure proc;
3095         BasicBlock* root = proc.addBlock();
3096         
3097         root->appendNew<ControlValue>(
3098             proc, Return, Origin(),
3099             root->appendNew<Value>(
3100                 proc, ChillDiv, Origin(),
3101                 root->appendNew<Value>(
3102                     proc, Trunc, Origin(),
3103                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3104                 root->appendNew<Value>(
3105                     proc, Trunc, Origin(),
3106                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3107
3108         CHECK(compileAndRun<int>(proc, num, den) == res);
3109     }
3110
3111     // Test constant.
3112     {
3113         Procedure proc;
3114         BasicBlock* root = proc.addBlock();
3115         
3116         root->appendNew<ControlValue>(
3117             proc, Return, Origin(),
3118             root->appendNew<Value>(
3119                 proc, ChillDiv, Origin(),
3120                 root->appendNew<Const32Value>(proc, Origin(), num),
3121                 root->appendNew<Const32Value>(proc, Origin(), den)));
3122         
3123         CHECK(compileAndRun<int>(proc) == res);
3124     }
3125 }
3126
3127 void testChillDivTwice(int num1, int den1, int num2, int den2, int res)
3128 {
3129     Procedure proc;
3130     BasicBlock* root = proc.addBlock();
3131
3132     root->appendNew<ControlValue>(
3133         proc, Return, Origin(),
3134         root->appendNew<Value>(
3135             proc, Add, Origin(),
3136             root->appendNew<Value>(
3137                 proc, ChillDiv, Origin(),
3138                 root->appendNew<Value>(
3139                     proc, Trunc, Origin(),
3140                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3141                 root->appendNew<Value>(
3142                     proc, Trunc, Origin(),
3143                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))),
3144             root->appendNew<Value>(
3145                 proc, ChillDiv, Origin(),
3146                 root->appendNew<Value>(
3147                     proc, Trunc, Origin(),
3148                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
3149                 root->appendNew<Value>(
3150                     proc, Trunc, Origin(),
3151                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)))));
3152     
3153     CHECK(compileAndRun<int>(proc, num1, den1, num2, den2) == res);
3154 }
3155
3156 void testChillDiv64(int64_t num, int64_t den, int64_t res)
3157 {
3158     if (!is64Bit())
3159         return;
3160
3161     // Test non-constant.
3162     {
3163         Procedure proc;
3164         BasicBlock* root = proc.addBlock();
3165         
3166         root->appendNew<ControlValue>(
3167             proc, Return, Origin(),
3168             root->appendNew<Value>(
3169                 proc, ChillDiv, Origin(),
3170                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3171                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
3172         
3173         CHECK(compileAndRun<int64_t>(proc, num, den) == res);
3174     }
3175
3176     // Test constant.
3177     {
3178         Procedure proc;
3179         BasicBlock* root = proc.addBlock();
3180         
3181         root->appendNew<ControlValue>(
3182             proc, Return, Origin(),
3183             root->appendNew<Value>(
3184                 proc, ChillDiv, Origin(),
3185                 root->appendNew<Const64Value>(proc, Origin(), num),
3186                 root->appendNew<Const64Value>(proc, Origin(), den)));
3187         
3188         CHECK(compileAndRun<int64_t>(proc) == res);
3189     }
3190 }
3191
3192 void testSwitch(unsigned degree, unsigned gap = 1)
3193 {
3194     Procedure proc;
3195     BasicBlock* root = proc.addBlock();
3196
3197     BasicBlock* terminate = proc.addBlock();
3198     terminate->appendNew<ControlValue>(
3199         proc, Return, Origin(),
3200         terminate->appendNew<Const32Value>(proc, Origin(), 0));
3201
3202     SwitchValue* switchValue = root->appendNew<SwitchValue>(
3203         proc, Origin(),
3204         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3205         FrequentedBlock(terminate));
3206
3207     for (unsigned i = 0; i < degree; ++i) {
3208         BasicBlock* newBlock = proc.addBlock();
3209         newBlock->appendNew<ControlValue>(
3210             proc, Return, Origin(),
3211             newBlock->appendNew<ArgumentRegValue>(
3212                 proc, Origin(), (i & 1) ? GPRInfo::argumentGPR2 : GPRInfo::argumentGPR1));
3213         switchValue->appendCase(SwitchCase(gap * i, FrequentedBlock(newBlock)));
3214     }
3215
3216     auto code = compile(proc);
3217
3218     for (unsigned i = 0; i < degree; ++i) {
3219         CHECK(invoke<int32_t>(*code, i * gap, 42, 11) == ((i & 1) ? 11 : 42));
3220         if (gap > 1) {
3221             CHECK(!invoke<int32_t>(*code, i * gap + 1, 42, 11));
3222             CHECK(!invoke<int32_t>(*code, i * gap - 1, 42, 11));
3223         }
3224     }
3225
3226     CHECK(!invoke<int32_t>(*code, -1, 42, 11));
3227     CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
3228     CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
3229 }
3230
3231 void testSwitchChillDiv(unsigned degree, unsigned gap = 1)
3232 {
3233     Procedure proc;
3234     BasicBlock* root = proc.addBlock();
3235
3236     Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3237     Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
3238
3239     BasicBlock* terminate = proc.addBlock();
3240     terminate->appendNew<ControlValue>(
3241         proc, Return, Origin(),
3242         terminate->appendNew<Const32Value>(proc, Origin(), 0));
3243
3244     SwitchValue* switchValue = root->appendNew<SwitchValue>(
3245         proc, Origin(),
3246         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
3247         FrequentedBlock(terminate));
3248
3249     for (unsigned i = 0; i < degree; ++i) {
3250         BasicBlock* newBlock = proc.addBlock();
3251
3252         newBlock->appendNew<ControlValue>(
3253             proc, Return, Origin(),
3254             newBlock->appendNew<Value>(
3255                 proc, ChillDiv, Origin(), (i & 1) ? right : left, (i & 1) ? left : right));
3256         
3257         switchValue->appendCase(SwitchCase(gap * i, FrequentedBlock(newBlock)));
3258     }
3259
3260     auto code = compile(proc);
3261
3262     for (unsigned i = 0; i < degree; ++i) {
3263         CHECK(invoke<int32_t>(*code, i * gap, 42, 11) == ((i & 1) ? 11/42 : 42/11));
3264         if (gap > 1) {
3265             CHECK(!invoke<int32_t>(*code, i * gap + 1, 42, 11));
3266             CHECK(!invoke<int32_t>(*code, i * gap - 1, 42, 11));
3267         }
3268     }
3269
3270     CHECK(!invoke<int32_t>(*code, -1, 42, 11));
3271     CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
3272     CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
3273 }
3274
3275 #define RUN(test) do {                          \
3276         if (!shouldRun(#test))                  \
3277             break;                              \
3278         tasks.append(                           \
3279             createSharedTask<void()>(           \
3280                 [&] () {                        \
3281                     dataLog(#test "...\n");     \
3282                     test;                       \
3283                     dataLog(#test ": OK!\n");   \
3284                 }));                            \
3285     } while (false);
3286
3287 void run(const char* filter)
3288 {
3289     JSC::initializeThreading();
3290     vm = &VM::create(LargeHeap).leakRef();
3291
3292     Deque<RefPtr<SharedTask<void()>>> tasks;
3293
3294     auto shouldRun = [&] (const char* testName) -> bool {
3295         return !filter || !!strcasestr(testName, filter);
3296     };
3297
3298     RUN(test42());
3299     RUN(testLoad42());
3300     RUN(testArg(43));
3301     RUN(testReturnConst64(5));
3302     RUN(testReturnConst64(-42));
3303
3304     RUN(testAddArg(111));
3305     RUN(testAddArgs(1, 1));
3306     RUN(testAddArgs(1, 2));
3307     RUN(testAddArgImm(1, 2));
3308     RUN(testAddArgImm(0, 2));
3309     RUN(testAddArgImm(1, 0));
3310     RUN(testAddImmArg(1, 2));
3311     RUN(testAddImmArg(0, 2));
3312     RUN(testAddImmArg(1, 0));
3313     RUN(testAddArgs32(1, 1));
3314     RUN(testAddArgs32(1, 2));
3315     RUN(testAddLoadTwice());
3316
3317     RUN(testMulArg(5));
3318     RUN(testMulArgs(1, 1));
3319     RUN(testMulArgs(1, 2));
3320     RUN(testMulArgs(3, 3));
3321     RUN(testMulArgImm(1, 2));
3322     RUN(testMulArgImm(1, 4));
3323     RUN(testMulArgImm(1, 8));
3324     RUN(testMulArgImm(1, 16));
3325     RUN(testMulArgImm(1, 0x80000000llu));
3326     RUN(testMulArgImm(1, 0x800000000000llu));
3327     RUN(testMulArgImm(7, 2));
3328     RUN(testMulArgImm(7, 4));
3329     RUN(testMulArgImm(7, 8));
3330     RUN(testMulArgImm(7, 16));
3331     RUN(testMulArgImm(7, 0x80000000llu));
3332     RUN(testMulArgImm(7, 0x800000000000llu));
3333     RUN(testMulArgImm(-42, 2));
3334     RUN(testMulArgImm(-42, 4));
3335     RUN(testMulArgImm(-42, 8));
3336     RUN(testMulArgImm(-42, 16));
3337     RUN(testMulArgImm(-42, 0x80000000llu));
3338     RUN(testMulArgImm(-42, 0x800000000000llu));
3339     RUN(testMulArgImm(0, 2));
3340     RUN(testMulArgImm(1, 0));
3341     RUN(testMulArgImm(3, 3));
3342     RUN(testMulArgImm(3, -1));
3343     RUN(testMulArgImm(-3, -1));
3344     RUN(testMulArgImm(0, -1));
3345     RUN(testMulImmArg(1, 2));
3346     RUN(testMulImmArg(0, 2));
3347     RUN(testMulImmArg(1, 0));
3348     RUN(testMulImmArg(3, 3));
3349     RUN(testMulArgs32(1, 1));
3350     RUN(testMulArgs32(1, 2));
3351     RUN(testMulLoadTwice());
3352
3353     RUN(testSubArg(24));
3354     RUN(testSubArgs(1, 1));
3355     RUN(testSubArgs(1, 2));
3356     RUN(testSubArgs(13, -42));
3357     RUN(testSubArgs(-13, 42));
3358     RUN(testSubArgImm(1, 1));
3359     RUN(testSubArgImm(1, 2));
3360     RUN(testSubArgImm(13, -42));
3361     RUN(testSubArgImm(-13, 42));
3362     RUN(testSubArgImm(42, 0));
3363     RUN(testSubImmArg(1, 1));
3364     RUN(testSubImmArg(1, 2));
3365     RUN(testSubImmArg(13, -42));
3366     RUN(testSubImmArg(-13, 42));
3367
3368     RUN(testSubArgs32(1, 1));
3369     RUN(testSubArgs32(1, 2));
3370     RUN(testSubArgs32(13, -42));
3371     RUN(testSubArgs32(-13, 42));
3372     RUN(testSubArgImm32(1, 1));
3373     RUN(testSubArgImm32(1, 2));
3374     RUN(testSubArgImm32(13, -42));
3375     RUN(testSubArgImm32(-13, 42));
3376     RUN(testSubImmArg32(1, 1));
3377     RUN(testSubImmArg32(1, 2));
3378     RUN(testSubImmArg32(13, -42));
3379     RUN(testSubImmArg32(-13, 42));
3380
3381     RUN(testBitAndArgs(43, 43));
3382     RUN(testBitAndArgs(43, 0));
3383     RUN(testBitAndArgs(10, 3));
3384     RUN(testBitAndArgs(42, 0xffffffffffffffff));
3385     RUN(testBitAndSameArg(43));
3386     RUN(testBitAndSameArg(0));
3387     RUN(testBitAndSameArg(3));
3388     RUN(testBitAndSameArg(0xffffffffffffffff));
3389     RUN(testBitAndImms(43, 43));
3390     RUN(testBitAndImms(43, 0));
3391     RUN(testBitAndImms(10, 3));
3392     RUN(testBitAndImms(42, 0xffffffffffffffff));
3393     RUN(testBitAndArgImm(43, 43));
3394     RUN(testBitAndArgImm(43, 0));
3395     RUN(testBitAndArgImm(10, 3));
3396     RUN(testBitAndArgImm(42, 0xffffffffffffffff));
3397     RUN(testBitAndImmArg(43, 43));
3398     RUN(testBitAndImmArg(43, 0));
3399     RUN(testBitAndImmArg(10, 3));
3400     RUN(testBitAndImmArg(42, 0xffffffffffffffff));
3401     RUN(testBitAndBitAndArgImmImm(2, 7, 3));
3402     RUN(testBitAndBitAndArgImmImm(1, 6, 6));
3403     RUN(testBitAndBitAndArgImmImm(0xffff, 24, 7));
3404     RUN(testBitAndImmBitAndArgImm(7, 2, 3));
3405     RUN(testBitAndImmBitAndArgImm(6, 1, 6));
3406     RUN(testBitAndImmBitAndArgImm(24, 0xffff, 7));
3407     RUN(testBitAndArgs32(43, 43));
3408     RUN(testBitAndArgs32(43, 0));
3409     RUN(testBitAndArgs32(10, 3));
3410     RUN(testBitAndArgs32(42, 0xffffffff));
3411     RUN(testBitAndSameArg32(43));
3412     RUN(testBitAndSameArg32(0));
3413     RUN(testBitAndSameArg32(3));
3414     RUN(testBitAndSameArg32(0xffffffff));
3415     RUN(testBitAndImms32(43, 43));
3416     RUN(testBitAndImms32(43, 0));
3417     RUN(testBitAndImms32(10, 3));
3418     RUN(testBitAndImms32(42, 0xffffffff));
3419     RUN(testBitAndArgImm32(43, 43));
3420     RUN(testBitAndArgImm32(43, 0));
3421     RUN(testBitAndArgImm32(10, 3));
3422     RUN(testBitAndArgImm32(42, 0xffffffff));
3423     RUN(testBitAndImmArg32(43, 43));
3424     RUN(testBitAndImmArg32(43, 0));
3425     RUN(testBitAndImmArg32(10, 3));
3426     RUN(testBitAndImmArg32(42, 0xffffffff));
3427     RUN(testBitAndBitAndArgImmImm32(2, 7, 3));
3428     RUN(testBitAndBitAndArgImmImm32(1, 6, 6));
3429     RUN(testBitAndBitAndArgImmImm32(0xffff, 24, 7));
3430     RUN(testBitAndImmBitAndArgImm32(7, 2, 3));
3431     RUN(testBitAndImmBitAndArgImm32(6, 1, 6));
3432     RUN(testBitAndImmBitAndArgImm32(24, 0xffff, 7));
3433
3434     RUN(testBitOrArgs(43, 43));
3435     RUN(testBitOrArgs(43, 0));
3436     RUN(testBitOrArgs(10, 3));
3437     RUN(testBitOrArgs(42, 0xffffffffffffffff));
3438     RUN(testBitOrSameArg(43));
3439     RUN(testBitOrSameArg(0));
3440     RUN(testBitOrSameArg(3));
3441     RUN(testBitOrSameArg(0xffffffffffffffff));
3442     RUN(testBitOrImms(43, 43));
3443     RUN(testBitOrImms(43, 0));
3444     RUN(testBitOrImms(10, 3));
3445     RUN(testBitOrImms(42, 0xffffffffffffffff));
3446     RUN(testBitOrArgImm(43, 43));
3447     RUN(testBitOrArgImm(43, 0));
3448     RUN(testBitOrArgImm(10, 3));
3449     RUN(testBitOrArgImm(42, 0xffffffffffffffff));
3450     RUN(testBitOrImmArg(43, 43));
3451     RUN(testBitOrImmArg(43, 0));
3452     RUN(testBitOrImmArg(10, 3));
3453     RUN(testBitOrImmArg(42, 0xffffffffffffffff));
3454     RUN(testBitOrBitOrArgImmImm(2, 7, 3));
3455     RUN(testBitOrBitOrArgImmImm(1, 6, 6));
3456     RUN(testBitOrBitOrArgImmImm(0xffff, 24, 7));
3457     RUN(testBitOrImmBitOrArgImm(7, 2, 3));
3458     RUN(testBitOrImmBitOrArgImm(6, 1, 6));
3459     RUN(testBitOrImmBitOrArgImm(24, 0xffff, 7));
3460     RUN(testBitOrArgs32(43, 43));
3461     RUN(testBitOrArgs32(43, 0));
3462     RUN(testBitOrArgs32(10, 3));
3463     RUN(testBitOrArgs32(42, 0xffffffff));
3464     RUN(testBitOrSameArg32(43));
3465     RUN(testBitOrSameArg32(0));
3466     RUN(testBitOrSameArg32(3));
3467     RUN(testBitOrSameArg32(0xffffffff));
3468     RUN(testBitOrImms32(43, 43));
3469     RUN(testBitOrImms32(43, 0));
3470     RUN(testBitOrImms32(10, 3));
3471     RUN(testBitOrImms32(42, 0xffffffff));
3472     RUN(testBitOrArgImm32(43, 43));
3473     RUN(testBitOrArgImm32(43, 0));
3474     RUN(testBitOrArgImm32(10, 3));
3475     RUN(testBitOrArgImm32(42, 0xffffffff));
3476     RUN(testBitOrImmArg32(43, 43));
3477     RUN(testBitOrImmArg32(43, 0));
3478     RUN(testBitOrImmArg32(10, 3));
3479     RUN(testBitOrImmArg32(42, 0xffffffff));
3480     RUN(testBitOrBitOrArgImmImm32(2, 7, 3));
3481     RUN(testBitOrBitOrArgImmImm32(1, 6, 6));
3482     RUN(testBitOrBitOrArgImmImm32(0xffff, 24, 7));
3483     RUN(testBitOrImmBitOrArgImm32(7, 2, 3));
3484     RUN(testBitOrImmBitOrArgImm32(6, 1, 6));
3485     RUN(testBitOrImmBitOrArgImm32(24, 0xffff, 7));
3486
3487     RUN(testBitXorArgs(43, 43));
3488     RUN(testBitXorArgs(43, 0));
3489     RUN(testBitXorArgs(10, 3));
3490     RUN(testBitXorArgs(42, 0xffffffffffffffff));
3491     RUN(testBitXorSameArg(43));
3492     RUN(testBitXorSameArg(0));
3493     RUN(testBitXorSameArg(3));
3494     RUN(testBitXorSameArg(0xffffffffffffffff));
3495     RUN(testBitXorImms(43, 43));
3496     RUN(testBitXorImms(43, 0));
3497     RUN(testBitXorImms(10, 3));
3498     RUN(testBitXorImms(42, 0xffffffffffffffff));
3499     RUN(testBitXorArgImm(43, 43));
3500     RUN(testBitXorArgImm(43, 0));
3501     RUN(testBitXorArgImm(10, 3));
3502     RUN(testBitXorArgImm(42, 0xffffffffffffffff));
3503     RUN(testBitXorImmArg(43, 43));
3504     RUN(testBitXorImmArg(43, 0));
3505     RUN(testBitXorImmArg(10, 3));
3506     RUN(testBitXorImmArg(42, 0xffffffffffffffff));
3507     RUN(testBitXorBitXorArgImmImm(2, 7, 3));
3508     RUN(testBitXorBitXorArgImmImm(1, 6, 6));
3509     RUN(testBitXorBitXorArgImmImm(0xffff, 24, 7));
3510     RUN(testBitXorImmBitXorArgImm(7, 2, 3));
3511     RUN(testBitXorImmBitXorArgImm(6, 1, 6));
3512     RUN(testBitXorImmBitXorArgImm(24, 0xffff, 7));
3513     RUN(testBitXorArgs32(43, 43));
3514     RUN(testBitXorArgs32(43, 0));
3515     RUN(testBitXorArgs32(10, 3));
3516     RUN(testBitXorArgs32(42, 0xffffffff));
3517     RUN(testBitXorSameArg32(43));
3518     RUN(testBitXorSameArg32(0));
3519     RUN(testBitXorSameArg32(3));
3520     RUN(testBitXorSameArg32(0xffffffff));
3521     RUN(testBitXorImms32(43, 43));
3522     RUN(testBitXorImms32(43, 0));
3523     RUN(testBitXorImms32(10, 3));
3524     RUN(testBitXorImms32(42, 0xffffffff));
3525     RUN(testBitXorArgImm32(43, 43));
3526     RUN(testBitXorArgImm32(43, 0));
3527     RUN(testBitXorArgImm32(10, 3));
3528     RUN(testBitXorArgImm32(42, 0xffffffff));
3529     RUN(testBitXorImmArg32(43, 43));
3530     RUN(testBitXorImmArg32(43, 0));
3531     RUN(testBitXorImmArg32(10, 3));
3532     RUN(testBitXorImmArg32(42, 0xffffffff));
3533     RUN(testBitXorBitXorArgImmImm32(2, 7, 3));
3534     RUN(testBitXorBitXorArgImmImm32(1, 6, 6));
3535     RUN(testBitXorBitXorArgImmImm32(0xffff, 24, 7));
3536     RUN(testBitXorImmBitXorArgImm32(7, 2, 3));
3537     RUN(testBitXorImmBitXorArgImm32(6, 1, 6));
3538     RUN(testBitXorImmBitXorArgImm32(24, 0xffff, 7));
3539
3540     RUN(testShlArgs(1, 0));
3541     RUN(testShlArgs(1, 1));
3542     RUN(testShlArgs(1, 62));
3543     RUN(testShlArgs(0xffffffffffffffff, 0));
3544     RUN(testShlArgs(0xffffffffffffffff, 1));
3545     RUN(testShlArgs(0xffffffffffffffff, 63));
3546     RUN(testShlImms(1, 0));
3547     RUN(testShlImms(1, 1));
3548     RUN(testShlImms(1, 62));
3549     RUN(testShlImms(1, 65));
3550     RUN(testShlImms(0xffffffffffffffff, 0));
3551     RUN(testShlImms(0xffffffffffffffff, 1));
3552     RUN(testShlImms(0xffffffffffffffff, 63));
3553     RUN(testShlArgImm(1, 0));
3554     RUN(testShlArgImm(1, 1));
3555     RUN(testShlArgImm(1, 62));
3556     RUN(testShlArgImm(1, 65));
3557     RUN(testShlArgImm(0xffffffffffffffff, 0));
3558     RUN(testShlArgImm(0xffffffffffffffff, 1));
3559     RUN(testShlArgImm(0xffffffffffffffff, 63));
3560     RUN(testShlArg32(2));
3561     RUN(testShlArgs32(1, 0));
3562     RUN(testShlArgs32(1, 1));
3563     RUN(testShlArgs32(1, 62));
3564     RUN(testShlImms32(1, 33));
3565     RUN(testShlArgs32(0xffffffff, 0));
3566     RUN(testShlArgs32(0xffffffff, 1));
3567     RUN(testShlArgs32(0xffffffff, 63));
3568     RUN(testShlImms32(1, 0));
3569     RUN(testShlImms32(1, 1));
3570     RUN(testShlImms32(1, 62));
3571     RUN(testShlImms32(1, 33));
3572     RUN(testShlImms32(0xffffffff, 0));
3573     RUN(testShlImms32(0xffffffff, 1));
3574     RUN(testShlImms32(0xffffffff, 63));
3575     RUN(testShlArgImm32(1, 0));
3576     RUN(testShlArgImm32(1, 1));
3577     RUN(testShlArgImm32(1, 62));
3578     RUN(testShlArgImm32(0xffffffff, 0));
3579     RUN(testShlArgImm32(0xffffffff, 1));
3580     RUN(testShlArgImm32(0xffffffff, 63));
3581
3582     RUN(testSShrArgs(1, 0));
3583     RUN(testSShrArgs(1, 1));
3584     RUN(testSShrArgs(1, 62));
3585     RUN(testSShrArgs(0xffffffffffffffff, 0));
3586     RUN(testSShrArgs(0xffffffffffffffff, 1));
3587     RUN(testSShrArgs(0xffffffffffffffff, 63));
3588     RUN(testSShrImms(1, 0));
3589     RUN(testSShrImms(1, 1));
3590     RUN(testSShrImms(1, 62));
3591     RUN(testSShrImms(1, 65));
3592     RUN(testSShrImms(0xffffffffffffffff, 0));
3593     RUN(testSShrImms(0xffffffffffffffff, 1));
3594     RUN(testSShrImms(0xffffffffffffffff, 63));
3595     RUN(testSShrArgImm(1, 0));
3596     RUN(testSShrArgImm(1, 1));
3597     RUN(testSShrArgImm(1, 62));
3598     RUN(testSShrArgImm(1, 65));
3599     RUN(testSShrArgImm(0xffffffffffffffff, 0));
3600     RUN(testSShrArgImm(0xffffffffffffffff, 1));
3601     RUN(testSShrArgImm(0xffffffffffffffff, 63));
3602     RUN(testSShrArg32(32));
3603     RUN(testSShrArgs32(1, 0));
3604     RUN(testSShrArgs32(1, 1));
3605     RUN(testSShrArgs32(1, 62));
3606     RUN(testSShrArgs32(1, 33));
3607     RUN(testSShrArgs32(0xffffffff, 0));
3608     RUN(testSShrArgs32(0xffffffff, 1));
3609     RUN(testSShrArgs32(0xffffffff, 63));
3610     RUN(testSShrImms32(1, 0));
3611     RUN(testSShrImms32(1, 1));
3612     RUN(testSShrImms32(1, 62));
3613     RUN(testSShrImms32(1, 33));
3614     RUN(testSShrImms32(0xffffffff, 0));
3615     RUN(testSShrImms32(0xffffffff, 1));
3616     RUN(testSShrImms32(0xffffffff, 63));
3617     RUN(testSShrArgImm32(1, 0));
3618     RUN(testSShrArgImm32(1, 1));
3619     RUN(testSShrArgImm32(1, 62));
3620     RUN(testSShrArgImm32(0xffffffff, 0));
3621     RUN(testSShrArgImm32(0xffffffff, 1));
3622     RUN(testSShrArgImm32(0xffffffff, 63));
3623
3624     RUN(testZShrArgs(1, 0));
3625     RUN(testZShrArgs(1, 1));
3626     RUN(testZShrArgs(1, 62));
3627     RUN(testZShrArgs(0xffffffffffffffff, 0));
3628     RUN(testZShrArgs(0xffffffffffffffff, 1));
3629     RUN(testZShrArgs(0xffffffffffffffff, 63));
3630     RUN(testZShrImms(1, 0));
3631     RUN(testZShrImms(1, 1));
3632     RUN(testZShrImms(1, 62));
3633     RUN(testZShrImms(1, 65));
3634     RUN(testZShrImms(0xffffffffffffffff, 0));
3635     RUN(testZShrImms(0xffffffffffffffff, 1));
3636     RUN(testZShrImms(0xffffffffffffffff, 63));
3637     RUN(testZShrArgImm(1, 0));
3638     RUN(testZShrArgImm(1, 1));
3639     RUN(testZShrArgImm(1, 62));
3640     RUN(testZShrArgImm(1, 65));
3641     RUN(testZShrArgImm(0xffffffffffffffff, 0));
3642     RUN(testZShrArgImm(0xffffffffffffffff, 1));
3643     RUN(testZShrArgImm(0xffffffffffffffff, 63));
3644     RUN(testZShrArg32(32));
3645     RUN(testZShrArgs32(1, 0));
3646     RUN(testZShrArgs32(1, 1));
3647     RUN(testZShrArgs32(1, 62));
3648     RUN(testZShrArgs32(1, 33));
3649     RUN(testZShrArgs32(0xffffffff, 0));
3650     RUN(testZShrArgs32(0xffffffff, 1));
3651     RUN(testZShrArgs32(0xffffffff, 63));
3652     RUN(testZShrImms32(1, 0));
3653     RUN(testZShrImms32(1, 1));
3654     RUN(testZShrImms32(1, 62));
3655     RUN(testZShrImms32(1, 33));
3656     RUN(testZShrImms32(0xffffffff, 0));
3657     RUN(testZShrImms32(0xffffffff, 1));
3658     RUN(testZShrImms32(0xffffffff, 63));
3659     RUN(testZShrArgImm32(1, 0));
3660     RUN(testZShrArgImm32(1, 1));
3661     RUN(testZShrArgImm32(1, 62));
3662     RUN(testZShrArgImm32(0xffffffff, 0));
3663     RUN(testZShrArgImm32(0xffffffff, 1));
3664     RUN(testZShrArgImm32(0xffffffff, 63));
3665
3666     RUN(testStore(44));
3667     RUN(testStoreConstant(49));
3668     RUN(testStoreConstantPtr(49));
3669     RUN(testTrunc((static_cast<int64_t>(1) << 40) + 42));
3670     RUN(testAdd1(45));
3671     RUN(testAdd1Ptr(51));
3672     RUN(testAdd1Ptr(bitwise_cast<intptr_t>(vm)));
3673     RUN(testNeg32(52));
3674     RUN(testNegPtr(53));
3675     RUN(testStoreAddLoad(46));
3676     RUN(testStoreSubLoad(46));
3677     RUN(testStoreAddLoadInterference(52));
3678     RUN(testStoreAddAndLoad(47, 0xffff));
3679     RUN(testStoreAddAndLoad(470000, 0xffff));
3680     RUN(testStoreNegLoad32(54));
3681     RUN(testStoreNegLoadPtr(55));
3682     RUN(testAdd1Uncommuted(48));
3683     RUN(testLoadOffset());
3684     RUN(testLoadOffsetNotConstant());
3685     RUN(testLoadOffsetUsingAdd());
3686     RUN(testLoadOffsetUsingAddInterference());
3687     RUN(testLoadOffsetUsingAddNotConstant());
3688     RUN(testFramePointer());
3689     RUN(testStackSlot());
3690     RUN(testLoadFromFramePointer());
3691     RUN(testStoreLoadStackSlot(50));
3692     
3693     RUN(testBranch());
3694     RUN(testBranchPtr());
3695     RUN(testDiamond());
3696     RUN(testBranchNotEqual());
3697     RUN(testBranchNotEqualCommute());
3698     RUN(testBranchNotEqualNotEqual());
3699     RUN(testBranchEqual());
3700     RUN(testBranchEqualEqual());
3701     RUN(testBranchEqualCommute());
3702     RUN(testBranchEqualEqual1());
3703     RUN(testBranchFold(42));
3704     RUN(testBranchFold(0));
3705     RUN(testDiamondFold(42));
3706     RUN(testDiamondFold(0));
3707     RUN(testBranchNotEqualFoldPtr(42));
3708     RUN(testBranchNotEqualFoldPtr(0));
3709     RUN(testBranchEqualFoldPtr(42));
3710     RUN(testBranchEqualFoldPtr(0));
3711
3712     RUN(testComplex(64, 128));
3713     RUN(testComplex(64, 256));
3714     RUN(testComplex(64, 384));
3715     RUN(testComplex(4, 128));
3716     RUN(testComplex(4, 256));
3717     RUN(testComplex(4, 384));
3718
3719     RUN(testSimplePatchpoint());
3720     RUN(testPatchpointCallArg());
3721     RUN(testSimpleCheck());
3722     RUN(testCheckLessThan());
3723     RUN(testCheckMegaCombo());
3724
3725     RUN(testCompare(Equal, 42, 42));
3726     RUN(testCompare(NotEqual, 42, 42));
3727     RUN(testCompare(LessThan, 42, 42));
3728     RUN(testCompare(GreaterThan, 42, 42));
3729     RUN(testCompare(LessEqual, 42, 42));
3730     RUN(testCompare(GreaterEqual, 42, 42));
3731     RUN(testCompare(Below, 42, 42));
3732     RUN(testCompare(Above, 42, 42));
3733     RUN(testCompare(BelowEqual, 42, 42));
3734     RUN(testCompare(AboveEqual, 42, 42));
3735
3736     RUN(testCompare(BitAnd, 42, 42));
3737     RUN(testCompare(BitAnd, 42, 0));
3738
3739     RUN(testLoad<int32_t>(Load, 60));
3740     RUN(testLoad<int32_t>(Load, -60));
3741     RUN(testLoad<int32_t>(Load, 1000));
3742     RUN(testLoad<int32_t>(Load, -1000));
3743     RUN(testLoad<int32_t>(Load, 1000000));
3744     RUN(testLoad<int32_t>(Load, -1000000));
3745     RUN(testLoad<int32_t>(Load, 1000000000));
3746     RUN(testLoad<int32_t>(Load, -1000000000));
3747     
3748     RUN(testLoad<int8_t>(Load8S, 60));
3749     RUN(testLoad<int8_t>(Load8S, -60));
3750     RUN(testLoad<int8_t>(Load8S, 1000));
3751     RUN(testLoad<int8_t>(Load8S, -1000));
3752     RUN(testLoad<int8_t>(Load8S, 1000000));
3753     RUN(testLoad<int8_t>(Load8S, -1000000));
3754     RUN(testLoad<int8_t>(Load8S, 1000000000));
3755     RUN(testLoad<int8_t>(Load8S, -1000000000));
3756     
3757     RUN(testLoad<uint8_t>(Load8Z, 60));
3758     RUN(testLoad<uint8_t>(Load8Z, -60));
3759     RUN(testLoad<uint8_t>(Load8Z, 1000));
3760     RUN(testLoad<uint8_t>(Load8Z, -1000));
3761     RUN(testLoad<uint8_t>(Load8Z, 1000000));
3762     RUN(testLoad<uint8_t>(Load8Z, -1000000));
3763     RUN(testLoad<uint8_t>(Load8Z, 1000000000));
3764     RUN(testLoad<uint8_t>(Load8Z, -1000000000));
3765
3766     RUN(testLoad<int16_t>(Load16S, 60));
3767     RUN(testLoad<int16_t>(Load16S, -60));
3768     RUN(testLoad<int16_t>(Load16S, 1000));
3769     RUN(testLoad<int16_t>(Load16S, -1000));
3770     RUN(testLoad<int16_t>(Load16S, 1000000));
3771     RUN(testLoad<int16_t>(Load16S, -1000000));
3772     RUN(testLoad<int16_t>(Load16S, 1000000000));
3773     RUN(testLoad<int16_t>(Load16S, -1000000000));
3774     
3775     RUN(testLoad<uint16_t>(Load16Z, 60));
3776     RUN(testLoad<uint16_t>(Load16Z, -60));
3777     RUN(testLoad<uint16_t>(Load16Z, 1000));
3778     RUN(testLoad<uint16_t>(Load16Z, -1000));
3779     RUN(testLoad<uint16_t>(Load16Z, 1000000));
3780     RUN(testLoad<uint16_t>(Load16Z, -1000000));
3781     RUN(testLoad<uint16_t>(Load16Z, 1000000000));
3782     RUN(testLoad<uint16_t>(Load16Z, -1000000000));
3783
3784     RUN(testSpillGP());
3785
3786     RUN(testCallSimple(1, 2));
3787     RUN(testCallFunctionWithHellaArguments());
3788
3789     RUN(testReturnDouble(0.0));
3790     RUN(testReturnDouble(-0.0));
3791     RUN(testReturnDouble(42.5));
3792
3793     RUN(testCallSimpleDouble(1, 2));
3794     RUN(testCallFunctionWithHellaDoubleArguments());
3795
3796     RUN(testChillDiv(4, 2, 2));
3797     RUN(testChillDiv(1, 0, 0));
3798     RUN(testChillDiv(0, 0, 0));
3799     RUN(testChillDiv(1, -1, -1));
3800     RUN(testChillDiv(-2147483647 - 1, 0, 0));
3801     RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
3802     RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
3803     RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
3804     RUN(testChillDiv64(4, 2, 2));
3805     RUN(testChillDiv64(1, 0, 0));
3806     RUN(testChillDiv64(0, 0, 0));
3807     RUN(testChillDiv64(1, -1, -1));
3808     RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
3809     RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
3810     RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
3811     RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
3812     RUN(testChillDivTwice(4, 2, 6, 2, 5));
3813     RUN(testChillDivTwice(4, 0, 6, 2, 3));
3814     RUN(testChillDivTwice(4, 2, 6, 0, 2));
3815
3816     RUN(testSwitch(0, 1));
3817     RUN(testSwitch(1, 1));
3818     RUN(testSwitch(2, 1));
3819     RUN(testSwitch(2, 2));
3820     RUN(testSwitch(10, 1));
3821     RUN(testSwitch(10, 2));
3822     RUN(testSwitch(100, 1));
3823     RUN(testSwitch(100, 100));
3824
3825     RUN(testSwitchChillDiv(0, 1));
3826     RUN(testSwitchChillDiv(1, 1));
3827     RUN(testSwitchChillDiv(2, 1));
3828     RUN(testSwitchChillDiv(2, 2));
3829     RUN(testSwitchChillDiv(10, 1));
3830     RUN(testSwitchChillDiv(10, 2));
3831     RUN(testSwitchChillDiv(100, 1));
3832     RUN(testSwitchChillDiv(100, 100));
3833
3834     if (tasks.isEmpty())
3835         usage();
3836
3837     Lock lock;
3838
3839     Vector<ThreadIdentifier> threads;
3840     for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
3841         threads.append(
3842             createThread(
3843                 "testb3 thread",
3844                 [&] () {
3845                     for (;;) {
3846                         RefPtr<SharedTask<void()>> task;
3847                         {
3848                             LockHolder locker(lock);
3849                             if (tasks.isEmpty())
3850                                 return;
3851                             task = tasks.takeFirst();
3852                         }
3853
3854                         task->run();
3855                     }
3856                 }));
3857     }
3858
3859     for (ThreadIdentifier thread : threads)
3860         waitForThreadCompletion(thread);
3861 }
3862
3863 } // anonymous namespace
3864
3865 #else // ENABLE(B3_JIT)
3866
3867 static void run(const char*)
3868 {
3869     dataLog("B3 JIT is not enabled.\n");
3870 }
3871
3872 #endif // ENABLE(B3_JIT)
3873
3874 int main(int argc, char** argv)
3875 {
3876     const char* filter = nullptr;
3877     switch (argc) {
3878     case 1:
3879         break;
3880     case 2:
3881         filter = argv[1];
3882         break;
3883     default:
3884         usage();
3885         break;
3886     }
3887     
3888     run(filter);
3889     return 0;
3890 }
3891