[JSC] Add B3-to-Air lowering for BitXor
[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 "B3Const32Value.h"
31 #include "B3ConstPtrValue.h"
32 #include "B3ControlValue.h"
33 #include "B3Generate.h"
34 #include "B3MemoryValue.h"
35 #include "B3Procedure.h"
36 #include "B3StackSlotValue.h"
37 #include "B3UpsilonValue.h"
38 #include "B3ValueInlines.h"
39 #include "CCallHelpers.h"
40 #include "InitializeThreading.h"
41 #include "JSCInlines.h"
42 #include "LinkBuffer.h"
43 #include "VM.h"
44
45 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
46 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
47
48 static void usage()
49 {
50     dataLog("Usage: testb3 [<filter>]\n");
51     if (hiddenTruthBecauseNoReturnIsStupid())
52         exit(1);
53 }
54
55 #if ENABLE(B3_JIT)
56
57 using namespace JSC;
58 using namespace JSC::B3;
59
60 namespace {
61
62 // Nothing fancy for now; we just use the existing WTF assertion machinery.
63 #define CHECK(x) RELEASE_ASSERT(x)
64
65 VM* vm;
66
67 MacroAssemblerCodeRef compile(Procedure& procedure)
68 {
69     CCallHelpers jit(vm);
70     generate(procedure, jit);
71     LinkBuffer linkBuffer(*vm, jit, nullptr);
72     return FINALIZE_CODE(linkBuffer, ("testb3"));
73 }
74
75 template<typename T, typename... Arguments>
76 T invoke(const MacroAssemblerCodeRef& code, Arguments... arguments)
77 {
78     T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(code.code().executableAddress());
79     return function(arguments...);
80 }
81
82 template<typename T, typename... Arguments>
83 T compileAndRun(Procedure& procedure, Arguments... arguments)
84 {
85     return invoke<T>(compile(procedure), arguments...);
86 }
87
88 void test42()
89 {
90     Procedure proc;
91     BasicBlock* root = proc.addBlock();
92     Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
93     root->appendNew<ControlValue>(proc, Return, Origin(), const42);
94
95     CHECK(compileAndRun<int>(proc) == 42);
96 }
97
98 void testLoad42()
99 {
100     Procedure proc;
101     BasicBlock* root = proc.addBlock();
102     int x = 42;
103     root->appendNew<ControlValue>(
104         proc, Return, Origin(),
105         root->appendNew<MemoryValue>(
106             proc, Load, Int32, Origin(),
107             root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
108
109     CHECK(compileAndRun<int>(proc) == 42);
110 }
111
112 void testArg(int argument)
113 {
114     Procedure proc;
115     BasicBlock* root = proc.addBlock();
116     root->appendNew<ControlValue>(
117         proc, Return, Origin(),
118         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
119
120     CHECK(compileAndRun<int>(proc, argument) == argument);
121 }
122
123 void testReturnConst64(int64_t value)
124 {
125     Procedure proc;
126     BasicBlock* root = proc.addBlock();
127     root->appendNew<ControlValue>(
128         proc, Return, Origin(),
129         root->appendNew<Const64Value>(proc, Origin(), value));
130
131     CHECK(compileAndRun<int64_t>(proc) == value);
132 }
133
134 void testAddArgs(int a, int b)
135 {
136     Procedure proc;
137     BasicBlock* root = proc.addBlock();
138     root->appendNew<ControlValue>(
139         proc, Return, Origin(),
140         root->appendNew<Value>(
141             proc, Add, Origin(),
142             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
143             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
144
145     CHECK(compileAndRun<int>(proc, a, b) == a + b);
146 }
147
148 void testAddArgImm(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<Const64Value>(proc, Origin(), b)));
158
159     CHECK(compileAndRun<int>(proc, a) == a + b);
160 }
161
162 void testAddImmArg(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<Const64Value>(proc, Origin(), a),
171             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
172
173     CHECK(compileAndRun<int>(proc, b) == a + b);
174 }
175
176 void testAddArgs32(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<Value>(
185                 proc, Trunc, Origin(),
186                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
187             root->appendNew<Value>(
188                 proc, Trunc, Origin(),
189                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
190
191     CHECK(compileAndRun<int>(proc, a, b) == a + b);
192 }
193
194 void testSubArgs(int a, int b)
195 {
196     Procedure proc;
197     BasicBlock* root = proc.addBlock();
198     root->appendNew<ControlValue>(
199         proc, Return, Origin(),
200         root->appendNew<Value>(
201             proc, Sub, Origin(),
202             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
203             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
204
205     CHECK(compileAndRun<int>(proc, a, b) == a - b);
206 }
207
208 void testSubArgImm(int64_t a, int64_t b)
209 {
210     Procedure proc;
211     BasicBlock* root = proc.addBlock();
212     root->appendNew<ControlValue>(
213         proc, Return, Origin(),
214         root->appendNew<Value>(
215             proc, Sub, Origin(),
216             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
217             root->appendNew<Const64Value>(proc, Origin(), b)));
218
219     CHECK(compileAndRun<int64_t>(proc, a) == a - b);
220 }
221
222 void testSubImmArg(int a, int b)
223 {
224     Procedure proc;
225     BasicBlock* root = proc.addBlock();
226     root->appendNew<ControlValue>(
227         proc, Return, Origin(),
228         root->appendNew<Value>(
229             proc, Sub, Origin(),
230             root->appendNew<Const64Value>(proc, Origin(), a),
231             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
232
233     CHECK(compileAndRun<int>(proc, b) == a - b);
234 }
235
236 void testSubArgs32(int a, int b)
237 {
238     Procedure proc;
239     BasicBlock* root = proc.addBlock();
240     root->appendNew<ControlValue>(
241         proc, Return, Origin(),
242         root->appendNew<Value>(
243             proc, Sub, Origin(),
244             root->appendNew<Value>(
245                 proc, Trunc, Origin(),
246                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
247             root->appendNew<Value>(
248                 proc, Trunc, Origin(),
249                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
250
251     CHECK(compileAndRun<int>(proc, a, b) == a - b);
252 }
253
254 void testSubArgImm32(int a, int b)
255 {
256     Procedure proc;
257     BasicBlock* root = proc.addBlock();
258     root->appendNew<ControlValue>(
259         proc, Return, Origin(),
260         root->appendNew<Value>(
261             proc, Sub, Origin(),
262             root->appendNew<Value>(
263                 proc, Trunc, Origin(),
264                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
265             root->appendNew<Const32Value>(proc, Origin(), b)));
266
267     CHECK(compileAndRun<int>(proc, a) == a - b);
268 }
269
270 void testSubImmArg32(int a, int b)
271 {
272     Procedure proc;
273     BasicBlock* root = proc.addBlock();
274     root->appendNew<ControlValue>(
275         proc, Return, Origin(),
276         root->appendNew<Value>(
277             proc, Sub, Origin(),
278             root->appendNew<Const32Value>(proc, Origin(), a),
279             root->appendNew<Value>(
280                 proc, Trunc, Origin(),
281                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
282
283     CHECK(compileAndRun<int>(proc, b) == a - b);
284 }
285
286 void testBitAndArgs(int64_t a, int64_t b)
287 {
288     Procedure proc;
289     BasicBlock* root = proc.addBlock();
290     root->appendNew<ControlValue>(
291         proc, Return, Origin(),
292         root->appendNew<Value>(
293             proc, BitAnd, Origin(),
294             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
295             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
296
297     CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
298 }
299
300 void testBitAndSameArg(int64_t a)
301 {
302     Procedure proc;
303     BasicBlock* root = proc.addBlock();
304     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
305     root->appendNew<ControlValue>(
306         proc, Return, Origin(),
307         root->appendNew<Value>(
308             proc, BitAnd, Origin(),
309             argument,
310             argument));
311
312     CHECK(compileAndRun<int64_t>(proc, a) == a);
313 }
314
315 void testBitAndImms(int64_t a, int64_t b)
316 {
317     Procedure proc;
318     BasicBlock* root = proc.addBlock();
319     root->appendNew<ControlValue>(
320         proc, Return, Origin(),
321         root->appendNew<Value>(
322             proc, BitAnd, Origin(),
323             root->appendNew<Const64Value>(proc, Origin(), a),
324             root->appendNew<Const64Value>(proc, Origin(), b)));
325
326     CHECK(compileAndRun<int64_t>(proc) == (a & b));
327 }
328
329 void testBitAndArgImm(int64_t a, int64_t b)
330 {
331     Procedure proc;
332     BasicBlock* root = proc.addBlock();
333     root->appendNew<ControlValue>(
334         proc, Return, Origin(),
335         root->appendNew<Value>(
336             proc, BitAnd, Origin(),
337             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
338             root->appendNew<Const64Value>(proc, Origin(), b)));
339
340     CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
341 }
342
343 void testBitAndImmArg(int64_t a, int64_t b)
344 {
345     Procedure proc;
346     BasicBlock* root = proc.addBlock();
347     root->appendNew<ControlValue>(
348         proc, Return, Origin(),
349         root->appendNew<Value>(
350             proc, BitAnd, Origin(),
351             root->appendNew<Const64Value>(proc, Origin(), a),
352             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
353
354     CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
355 }
356
357 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
358 {
359     Procedure proc;
360     BasicBlock* root = proc.addBlock();
361     Value* innerBitAnd = root->appendNew<Value>(
362         proc, BitAnd, Origin(),
363         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
364         root->appendNew<Const64Value>(proc, Origin(), b));
365     root->appendNew<ControlValue>(
366         proc, Return, Origin(),
367         root->appendNew<Value>(
368             proc, BitAnd, Origin(),
369             innerBitAnd,
370             root->appendNew<Const64Value>(proc, Origin(), c)));
371
372     CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
373 }
374
375 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
376 {
377     Procedure proc;
378     BasicBlock* root = proc.addBlock();
379     Value* innerBitAnd = root->appendNew<Value>(
380         proc, BitAnd, Origin(),
381         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
382         root->appendNew<Const64Value>(proc, Origin(), c));
383     root->appendNew<ControlValue>(
384         proc, Return, Origin(),
385         root->appendNew<Value>(
386             proc, BitAnd, Origin(),
387             root->appendNew<Const64Value>(proc, Origin(), a),
388             innerBitAnd));
389
390     CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
391 }
392
393 void testBitAndArgs32(int a, int b)
394 {
395     Procedure proc;
396     BasicBlock* root = proc.addBlock();
397     root->appendNew<ControlValue>(
398         proc, Return, Origin(),
399         root->appendNew<Value>(
400             proc, BitAnd, Origin(),
401             root->appendNew<Value>(
402                 proc, Trunc, Origin(),
403                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
404             root->appendNew<Value>(
405                 proc, Trunc, Origin(),
406                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
407
408     CHECK(compileAndRun<int>(proc, a, b) == (a & b));
409 }
410
411 void testBitAndSameArg32(int a)
412 {
413     Procedure proc;
414     BasicBlock* root = proc.addBlock();
415     Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
416         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
417     root->appendNew<ControlValue>(
418         proc, Return, Origin(),
419         root->appendNew<Value>(
420             proc, BitAnd, Origin(),
421             argument,
422             argument));
423
424     CHECK(compileAndRun<int>(proc, a) == a);
425 }
426
427 void testBitAndImms32(int a, int b)
428 {
429     Procedure proc;
430     BasicBlock* root = proc.addBlock();
431     root->appendNew<ControlValue>(
432         proc, Return, Origin(),
433         root->appendNew<Value>(
434             proc, BitAnd, Origin(),
435             root->appendNew<Const32Value>(proc, Origin(), a),
436             root->appendNew<Const32Value>(proc, Origin(), b)));
437
438     CHECK(compileAndRun<int>(proc) == (a & b));
439 }
440
441 void testBitAndArgImm32(int a, int b)
442 {
443     Procedure proc;
444     BasicBlock* root = proc.addBlock();
445     root->appendNew<ControlValue>(
446         proc, Return, Origin(),
447         root->appendNew<Value>(
448             proc, BitAnd, Origin(),
449             root->appendNew<Value>(
450                 proc, Trunc, Origin(),
451                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
452             root->appendNew<Const32Value>(proc, Origin(), b)));
453
454     CHECK(compileAndRun<int>(proc, a) == (a & b));
455 }
456
457 void testBitAndImmArg32(int a, int b)
458 {
459     Procedure proc;
460     BasicBlock* root = proc.addBlock();
461     root->appendNew<ControlValue>(
462         proc, Return, Origin(),
463         root->appendNew<Value>(
464             proc, BitAnd, Origin(),
465             root->appendNew<Const32Value>(proc, Origin(), a),
466             root->appendNew<Value>(
467                 proc, Trunc, Origin(),
468                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
469
470     CHECK(compileAndRun<int>(proc, b) == (a & b));
471 }
472
473 void testBitAndBitAndArgImmImm32(int a, int b, int c)
474 {
475     Procedure proc;
476     BasicBlock* root = proc.addBlock();
477     Value* innerBitAnd = root->appendNew<Value>(
478         proc, BitAnd, Origin(),
479         root->appendNew<Value>(
480             proc, Trunc, Origin(),
481             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
482         root->appendNew<Const32Value>(proc, Origin(), b));
483     root->appendNew<ControlValue>(
484         proc, Return, Origin(),
485         root->appendNew<Value>(
486             proc, BitAnd, Origin(),
487             innerBitAnd,
488             root->appendNew<Const32Value>(proc, Origin(), c)));
489
490     CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
491 }
492
493 void testBitAndImmBitAndArgImm32(int a, int b, int c)
494 {
495     Procedure proc;
496     BasicBlock* root = proc.addBlock();
497     Value* innerBitAnd = root->appendNew<Value>(
498         proc, BitAnd, Origin(),
499         root->appendNew<Value>(
500             proc, Trunc, Origin(),
501             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
502         root->appendNew<Const32Value>(proc, Origin(), c));
503     root->appendNew<ControlValue>(
504         proc, Return, Origin(),
505         root->appendNew<Value>(
506             proc, BitAnd, Origin(),
507             root->appendNew<Const32Value>(proc, Origin(), a),
508             innerBitAnd));
509
510     CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
511 }
512
513 void testBitOrArgs(int64_t a, int64_t b)
514 {
515     Procedure proc;
516     BasicBlock* root = proc.addBlock();
517     root->appendNew<ControlValue>(
518         proc, Return, Origin(),
519         root->appendNew<Value>(
520             proc, BitOr, Origin(),
521             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
522             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
523
524     CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
525 }
526
527 void testBitOrSameArg(int64_t a)
528 {
529     Procedure proc;
530     BasicBlock* root = proc.addBlock();
531     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
532     root->appendNew<ControlValue>(
533         proc, Return, Origin(),
534         root->appendNew<Value>(
535             proc, BitOr, Origin(),
536             argument,
537             argument));
538
539     CHECK(compileAndRun<int64_t>(proc, a) == a);
540 }
541
542 void testBitOrImms(int64_t a, int64_t b)
543 {
544     Procedure proc;
545     BasicBlock* root = proc.addBlock();
546     root->appendNew<ControlValue>(
547         proc, Return, Origin(),
548         root->appendNew<Value>(
549             proc, BitOr, Origin(),
550             root->appendNew<Const64Value>(proc, Origin(), a),
551             root->appendNew<Const64Value>(proc, Origin(), b)));
552
553     CHECK(compileAndRun<int64_t>(proc) == (a | b));
554 }
555
556 void testBitOrArgImm(int64_t a, int64_t b)
557 {
558     Procedure proc;
559     BasicBlock* root = proc.addBlock();
560     root->appendNew<ControlValue>(
561         proc, Return, Origin(),
562         root->appendNew<Value>(
563             proc, BitOr, Origin(),
564             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
565             root->appendNew<Const64Value>(proc, Origin(), b)));
566
567     CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
568 }
569
570 void testBitOrImmArg(int64_t a, int64_t b)
571 {
572     Procedure proc;
573     BasicBlock* root = proc.addBlock();
574     root->appendNew<ControlValue>(
575         proc, Return, Origin(),
576         root->appendNew<Value>(
577             proc, BitOr, Origin(),
578             root->appendNew<Const64Value>(proc, Origin(), a),
579             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
580
581     CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
582 }
583
584 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
585 {
586     Procedure proc;
587     BasicBlock* root = proc.addBlock();
588     Value* innerBitOr = root->appendNew<Value>(
589         proc, BitOr, Origin(),
590         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
591         root->appendNew<Const64Value>(proc, Origin(), b));
592     root->appendNew<ControlValue>(
593         proc, Return, Origin(),
594         root->appendNew<Value>(
595             proc, BitOr, Origin(),
596             innerBitOr,
597             root->appendNew<Const64Value>(proc, Origin(), c)));
598
599     CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
600 }
601
602 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
603 {
604     Procedure proc;
605     BasicBlock* root = proc.addBlock();
606     Value* innerBitOr = root->appendNew<Value>(
607         proc, BitOr, Origin(),
608         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
609         root->appendNew<Const64Value>(proc, Origin(), c));
610     root->appendNew<ControlValue>(
611         proc, Return, Origin(),
612         root->appendNew<Value>(
613             proc, BitOr, Origin(),
614             root->appendNew<Const64Value>(proc, Origin(), a),
615             innerBitOr));
616
617     CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
618 }
619
620 void testBitOrArgs32(int a, int b)
621 {
622     Procedure proc;
623     BasicBlock* root = proc.addBlock();
624     root->appendNew<ControlValue>(
625         proc, Return, Origin(),
626         root->appendNew<Value>(
627             proc, BitOr, Origin(),
628             root->appendNew<Value>(
629                 proc, Trunc, Origin(),
630                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
631             root->appendNew<Value>(
632                 proc, Trunc, Origin(),
633                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
634
635     CHECK(compileAndRun<int>(proc, a, b) == (a | b));
636 }
637
638 void testBitOrSameArg32(int a)
639 {
640     Procedure proc;
641     BasicBlock* root = proc.addBlock();
642     Value* argument = root->appendNew<Value>(
643         proc, Trunc, Origin(),
644             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
645     root->appendNew<ControlValue>(
646         proc, Return, Origin(),
647         root->appendNew<Value>(
648             proc, BitOr, Origin(),
649             argument,
650             argument));
651
652     CHECK(compileAndRun<int>(proc, a) == a);
653 }
654
655 void testBitOrImms32(int a, int b)
656 {
657     Procedure proc;
658     BasicBlock* root = proc.addBlock();
659     root->appendNew<ControlValue>(
660         proc, Return, Origin(),
661         root->appendNew<Value>(
662             proc, BitOr, Origin(),
663             root->appendNew<Const32Value>(proc, Origin(), a),
664             root->appendNew<Const32Value>(proc, Origin(), b)));
665
666     CHECK(compileAndRun<int>(proc) == (a | b));
667 }
668
669 void testBitOrArgImm32(int a, int b)
670 {
671     Procedure proc;
672     BasicBlock* root = proc.addBlock();
673     root->appendNew<ControlValue>(
674         proc, Return, Origin(),
675         root->appendNew<Value>(
676             proc, BitOr, Origin(),
677             root->appendNew<Value>(
678                 proc, Trunc, Origin(),
679                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
680             root->appendNew<Const32Value>(proc, Origin(), b)));
681
682     CHECK(compileAndRun<int>(proc, a) == (a | b));
683 }
684
685 void testBitOrImmArg32(int a, int b)
686 {
687     Procedure proc;
688     BasicBlock* root = proc.addBlock();
689     root->appendNew<ControlValue>(
690         proc, Return, Origin(),
691         root->appendNew<Value>(
692             proc, BitOr, Origin(),
693             root->appendNew<Const32Value>(proc, Origin(), a),
694             root->appendNew<Value>(
695                 proc, Trunc, Origin(),
696                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
697
698     CHECK(compileAndRun<int>(proc, b) == (a | b));
699 }
700
701 void testBitOrBitOrArgImmImm32(int a, int b, int c)
702 {
703     Procedure proc;
704     BasicBlock* root = proc.addBlock();
705     Value* innerBitOr = root->appendNew<Value>(
706         proc, BitOr, Origin(),
707         root->appendNew<Value>(
708             proc, Trunc, Origin(),
709             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
710         root->appendNew<Const32Value>(proc, Origin(), b));
711     root->appendNew<ControlValue>(
712         proc, Return, Origin(),
713         root->appendNew<Value>(
714             proc, BitOr, Origin(),
715             innerBitOr,
716             root->appendNew<Const32Value>(proc, Origin(), c)));
717
718     CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
719 }
720
721 void testBitOrImmBitOrArgImm32(int a, int b, int c)
722 {
723     Procedure proc;
724     BasicBlock* root = proc.addBlock();
725     Value* innerBitOr = root->appendNew<Value>(
726         proc, BitOr, Origin(),
727         root->appendNew<Value>(
728             proc, Trunc, Origin(),
729             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
730         root->appendNew<Const32Value>(proc, Origin(), c));
731     root->appendNew<ControlValue>(
732         proc, Return, Origin(),
733         root->appendNew<Value>(
734             proc, BitOr, Origin(),
735             root->appendNew<Const32Value>(proc, Origin(), a),
736             innerBitOr));
737
738     CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
739 }
740
741 void testBitXorArgs(int64_t a, int64_t b)
742 {
743     Procedure proc;
744     BasicBlock* root = proc.addBlock();
745     root->appendNew<ControlValue>(
746         proc, Return, Origin(),
747         root->appendNew<Value>(
748             proc, BitXor, Origin(),
749             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
750             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
751
752     CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
753 }
754
755 void testBitXorSameArg(int64_t a)
756 {
757     Procedure proc;
758     BasicBlock* root = proc.addBlock();
759     Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
760     root->appendNew<ControlValue>(
761         proc, Return, Origin(),
762         root->appendNew<Value>(
763             proc, BitXor, Origin(),
764             argument,
765             argument));
766
767     CHECK(!compileAndRun<int64_t>(proc, a));
768 }
769
770 void testBitXorImms(int64_t a, int64_t b)
771 {
772     Procedure proc;
773     BasicBlock* root = proc.addBlock();
774     root->appendNew<ControlValue>(
775         proc, Return, Origin(),
776         root->appendNew<Value>(
777             proc, BitXor, Origin(),
778             root->appendNew<Const64Value>(proc, Origin(), a),
779             root->appendNew<Const64Value>(proc, Origin(), b)));
780
781     CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
782 }
783
784 void testBitXorArgImm(int64_t a, int64_t b)
785 {
786     Procedure proc;
787     BasicBlock* root = proc.addBlock();
788     root->appendNew<ControlValue>(
789         proc, Return, Origin(),
790         root->appendNew<Value>(
791             proc, BitXor, Origin(),
792             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
793             root->appendNew<Const64Value>(proc, Origin(), b)));
794
795     CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
796 }
797
798 void testBitXorImmArg(int64_t a, int64_t b)
799 {
800     Procedure proc;
801     BasicBlock* root = proc.addBlock();
802     root->appendNew<ControlValue>(
803         proc, Return, Origin(),
804         root->appendNew<Value>(
805             proc, BitXor, Origin(),
806             root->appendNew<Const64Value>(proc, Origin(), a),
807             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
808
809     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
810 }
811
812 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
813 {
814     Procedure proc;
815     BasicBlock* root = proc.addBlock();
816     Value* innerBitXor = root->appendNew<Value>(
817         proc, BitXor, Origin(),
818         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
819         root->appendNew<Const64Value>(proc, Origin(), b));
820     root->appendNew<ControlValue>(
821         proc, Return, Origin(),
822         root->appendNew<Value>(
823             proc, BitXor, Origin(),
824             innerBitXor,
825             root->appendNew<Const64Value>(proc, Origin(), c)));
826
827     CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
828 }
829
830 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
831 {
832     Procedure proc;
833     BasicBlock* root = proc.addBlock();
834     Value* innerBitXor = root->appendNew<Value>(
835         proc, BitXor, Origin(),
836         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
837         root->appendNew<Const64Value>(proc, Origin(), c));
838     root->appendNew<ControlValue>(
839         proc, Return, Origin(),
840         root->appendNew<Value>(
841             proc, BitXor, Origin(),
842             root->appendNew<Const64Value>(proc, Origin(), a),
843             innerBitXor));
844
845     CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
846 }
847
848 void testBitXorArgs32(int a, int b)
849 {
850     Procedure proc;
851     BasicBlock* root = proc.addBlock();
852     root->appendNew<ControlValue>(
853         proc, Return, Origin(),
854         root->appendNew<Value>(
855             proc, BitXor, Origin(),
856             root->appendNew<Value>(
857                 proc, Trunc, Origin(),
858                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
859             root->appendNew<Value>(
860                 proc, Trunc, Origin(),
861                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
862
863     CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
864 }
865
866 void testBitXorSameArg32(int a)
867 {
868     Procedure proc;
869     BasicBlock* root = proc.addBlock();
870     Value* argument = root->appendNew<Value>(
871         proc, Trunc, Origin(),
872             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
873     root->appendNew<ControlValue>(
874         proc, Return, Origin(),
875         root->appendNew<Value>(
876             proc, BitXor, Origin(),
877             argument,
878             argument));
879
880     CHECK(!compileAndRun<int>(proc, a));
881 }
882
883 void testBitXorImms32(int a, int b)
884 {
885     Procedure proc;
886     BasicBlock* root = proc.addBlock();
887     root->appendNew<ControlValue>(
888         proc, Return, Origin(),
889         root->appendNew<Value>(
890             proc, BitXor, Origin(),
891             root->appendNew<Const32Value>(proc, Origin(), a),
892             root->appendNew<Const32Value>(proc, Origin(), b)));
893
894     CHECK(compileAndRun<int>(proc) == (a ^ b));
895 }
896
897 void testBitXorArgImm32(int a, int b)
898 {
899     Procedure proc;
900     BasicBlock* root = proc.addBlock();
901     root->appendNew<ControlValue>(
902         proc, Return, Origin(),
903         root->appendNew<Value>(
904             proc, BitXor, Origin(),
905             root->appendNew<Value>(
906                 proc, Trunc, Origin(),
907                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
908             root->appendNew<Const32Value>(proc, Origin(), b)));
909
910     CHECK(compileAndRun<int>(proc, a) == (a ^ b));
911 }
912
913 void testBitXorImmArg32(int a, int b)
914 {
915     Procedure proc;
916     BasicBlock* root = proc.addBlock();
917     root->appendNew<ControlValue>(
918         proc, Return, Origin(),
919         root->appendNew<Value>(
920             proc, BitXor, Origin(),
921             root->appendNew<Const32Value>(proc, Origin(), a),
922             root->appendNew<Value>(
923                 proc, Trunc, Origin(),
924                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
925
926     CHECK(compileAndRun<int>(proc, b) == (a ^ b));
927 }
928
929 void testBitXorBitXorArgImmImm32(int a, int b, int c)
930 {
931     Procedure proc;
932     BasicBlock* root = proc.addBlock();
933     Value* innerBitXor = root->appendNew<Value>(
934         proc, BitXor, Origin(),
935         root->appendNew<Value>(
936             proc, Trunc, Origin(),
937             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
938         root->appendNew<Const32Value>(proc, Origin(), b));
939     root->appendNew<ControlValue>(
940         proc, Return, Origin(),
941         root->appendNew<Value>(
942             proc, BitXor, Origin(),
943             innerBitXor,
944             root->appendNew<Const32Value>(proc, Origin(), c)));
945
946     CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
947 }
948
949 void testBitXorImmBitXorArgImm32(int a, int b, int c)
950 {
951     Procedure proc;
952     BasicBlock* root = proc.addBlock();
953     Value* innerBitXor = root->appendNew<Value>(
954         proc, BitXor, Origin(),
955         root->appendNew<Value>(
956             proc, Trunc, Origin(),
957             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
958         root->appendNew<Const32Value>(proc, Origin(), c));
959     root->appendNew<ControlValue>(
960         proc, Return, Origin(),
961         root->appendNew<Value>(
962             proc, BitXor, Origin(),
963             root->appendNew<Const32Value>(proc, Origin(), a),
964             innerBitXor));
965
966     CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
967 }
968
969 void testStore(int value)
970 {
971     Procedure proc;
972     BasicBlock* root = proc.addBlock();
973     int slot = 0xbaadbeef;
974     root->appendNew<MemoryValue>(
975         proc, Store, Origin(),
976         root->appendNew<Value>(
977             proc, Trunc, Origin(),
978             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
979         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
980     root->appendNew<ControlValue>(
981         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
982
983     CHECK(!compileAndRun<int>(proc, value));
984     CHECK(slot == value);
985 }
986
987 void testStoreConstant(int value)
988 {
989     Procedure proc;
990     BasicBlock* root = proc.addBlock();
991     int slot = 0xbaadbeef;
992     root->appendNew<MemoryValue>(
993         proc, Store, Origin(),
994         root->appendNew<Const32Value>(proc, Origin(), value),
995         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
996     root->appendNew<ControlValue>(
997         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
998
999     CHECK(!compileAndRun<int>(proc));
1000     CHECK(slot == value);
1001 }
1002
1003 void testStoreConstantPtr(intptr_t value)
1004 {
1005     Procedure proc;
1006     BasicBlock* root = proc.addBlock();
1007     intptr_t slot;
1008     if (is64Bit())
1009         slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
1010     else
1011         slot = 0xbaadbeef;
1012     root->appendNew<MemoryValue>(
1013         proc, Store, Origin(),
1014         root->appendNew<ConstPtrValue>(proc, Origin(), value),
1015         root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
1016     root->appendNew<ControlValue>(
1017         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1018
1019     CHECK(!compileAndRun<int>(proc));
1020     CHECK(slot == value);
1021 }
1022
1023 void testTrunc(int64_t value)
1024 {
1025     Procedure proc;
1026     BasicBlock* root = proc.addBlock();
1027     root->appendNew<ControlValue>(
1028         proc, Return, Origin(),
1029         root->appendNew<Value>(
1030             proc, Trunc, Origin(),
1031             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1032
1033     CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
1034 }
1035
1036 void testAdd1(int value)
1037 {
1038     Procedure proc;
1039     BasicBlock* root = proc.addBlock();
1040     root->appendNew<ControlValue>(
1041         proc, Return, Origin(),
1042         root->appendNew<Value>(
1043             proc, Add, Origin(),
1044             root->appendNew<Value>(
1045                 proc, Trunc, Origin(),
1046                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1047             root->appendNew<Const32Value>(proc, Origin(), 1)));
1048
1049     CHECK(compileAndRun<int>(proc, value) == value + 1);
1050 }
1051
1052 void testAdd1Ptr(intptr_t value)
1053 {
1054     Procedure proc;
1055     BasicBlock* root = proc.addBlock();
1056     root->appendNew<ControlValue>(
1057         proc, Return, Origin(),
1058         root->appendNew<Value>(
1059             proc, Add, Origin(),
1060             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1061             root->appendNew<ConstPtrValue>(proc, Origin(), 1)));
1062
1063     CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
1064 }
1065
1066 void testNeg32(int32_t value)
1067 {
1068     Procedure proc;
1069     BasicBlock* root = proc.addBlock();
1070     root->appendNew<ControlValue>(
1071         proc, Return, Origin(),
1072         root->appendNew<Value>(
1073             proc, Sub, Origin(),
1074             root->appendNew<Const32Value>(proc, Origin(), 0),
1075             root->appendNew<Value>(
1076                 proc, Trunc, Origin(),
1077                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1078
1079     CHECK(compileAndRun<int32_t>(proc, value) == -value);
1080 }
1081
1082 void testNegPtr(intptr_t value)
1083 {
1084     Procedure proc;
1085     BasicBlock* root = proc.addBlock();
1086     root->appendNew<ControlValue>(
1087         proc, Return, Origin(),
1088         root->appendNew<Value>(
1089             proc, Sub, Origin(),
1090             root->appendNew<ConstPtrValue>(proc, Origin(), 0),
1091             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1092
1093     CHECK(compileAndRun<intptr_t>(proc, value) == -value);
1094 }
1095
1096 void testStoreAddLoad(int amount)
1097 {
1098     Procedure proc;
1099     BasicBlock* root = proc.addBlock();
1100     int slot = 37;
1101     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1102     root->appendNew<MemoryValue>(
1103         proc, Store, Origin(),
1104         root->appendNew<Value>(
1105             proc, Add, Origin(),
1106             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1107             root->appendNew<Const32Value>(proc, Origin(), amount)),
1108         slotPtr);
1109     root->appendNew<ControlValue>(
1110         proc, Return, Origin(),
1111         root->appendNew<Const32Value>(proc, Origin(), 0));
1112
1113     CHECK(!compileAndRun<int>(proc));
1114     CHECK(slot == 37 + amount);
1115 }
1116
1117 void testStoreSubLoad(int amount)
1118 {
1119     Procedure proc;
1120     BasicBlock* root = proc.addBlock();
1121     int32_t startValue = std::numeric_limits<int32_t>::min();
1122     int32_t slot = startValue;
1123     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1124     root->appendNew<MemoryValue>(
1125         proc, Store, Origin(),
1126         root->appendNew<Value>(
1127             proc, Sub, Origin(),
1128             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1129             root->appendNew<Value>(
1130                 proc, Trunc, Origin(),
1131                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
1132         slotPtr);
1133     root->appendNew<ControlValue>(
1134         proc, Return, Origin(),
1135         root->appendNew<Const32Value>(proc, Origin(), 0));
1136
1137     CHECK(!compileAndRun<int>(proc, amount));
1138     CHECK(slot == startValue - amount);
1139 }
1140
1141 void testStoreAddLoadInterference(int amount)
1142 {
1143     Procedure proc;
1144     BasicBlock* root = proc.addBlock();
1145     int slot = 37;
1146     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1147     ArgumentRegValue* otherSlotPtr =
1148         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1149     MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr);
1150     root->appendNew<MemoryValue>(
1151         proc, Store, Origin(),
1152         root->appendNew<Const32Value>(proc, Origin(), 666),
1153         otherSlotPtr);
1154     root->appendNew<MemoryValue>(
1155         proc, Store, Origin(),
1156         root->appendNew<Value>(
1157             proc, Add, Origin(),
1158             load, root->appendNew<Const32Value>(proc, Origin(), amount)),
1159         slotPtr);
1160     root->appendNew<ControlValue>(
1161         proc, Return, Origin(),
1162         root->appendNew<Const32Value>(proc, Origin(), 0));
1163
1164     CHECK(!compileAndRun<int>(proc, &slot));
1165     CHECK(slot == 37 + amount);
1166 }
1167
1168 void testStoreAddAndLoad(int amount, int mask)
1169 {
1170     Procedure proc;
1171     BasicBlock* root = proc.addBlock();
1172     int slot = 37;
1173     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1174     root->appendNew<MemoryValue>(
1175         proc, Store, Origin(),
1176         root->appendNew<Value>(
1177             proc, BitAnd, Origin(),
1178             root->appendNew<Value>(
1179                 proc, Add, Origin(),
1180                 root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
1181                 root->appendNew<Const32Value>(proc, Origin(), amount)),
1182             root->appendNew<Const32Value>(proc, Origin(), mask)),
1183         slotPtr);
1184     root->appendNew<ControlValue>(
1185         proc, Return, Origin(),
1186         root->appendNew<Const32Value>(proc, Origin(), 0));
1187
1188     CHECK(!compileAndRun<int>(proc));
1189     CHECK(slot == ((37 + amount) & mask));
1190 }
1191
1192 void testStoreNegLoad32(int32_t value)
1193 {
1194     Procedure proc;
1195     BasicBlock* root = proc.addBlock();
1196
1197     int32_t slot = value;
1198
1199     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1200     
1201     root->appendNew<MemoryValue>(
1202         proc, Store, Origin(),
1203         root->appendNew<Value>(
1204             proc, Sub, Origin(),
1205             root->appendNew<Const32Value>(proc, Origin(), 0),
1206             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr)),
1207         slotPtr);
1208     
1209     root->appendNew<ControlValue>(
1210         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1211
1212     CHECK(!compileAndRun<int32_t>(proc));
1213     CHECK(slot == -value);
1214 }
1215
1216 void testStoreNegLoadPtr(intptr_t value)
1217 {
1218     Procedure proc;
1219     BasicBlock* root = proc.addBlock();
1220
1221     intptr_t slot = value;
1222
1223     ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
1224     
1225     root->appendNew<MemoryValue>(
1226         proc, Store, Origin(),
1227         root->appendNew<Value>(
1228             proc, Sub, Origin(),
1229             root->appendNew<ConstPtrValue>(proc, Origin(), 0),
1230             root->appendNew<MemoryValue>(proc, Load, pointerType(), Origin(), slotPtr)),
1231         slotPtr);
1232     
1233     root->appendNew<ControlValue>(
1234         proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1235
1236     CHECK(!compileAndRun<int32_t>(proc));
1237     CHECK(slot == -value);
1238 }
1239
1240 void testAdd1Uncommuted(int value)
1241 {
1242     Procedure proc;
1243     BasicBlock* root = proc.addBlock();
1244     root->appendNew<ControlValue>(
1245         proc, Return, Origin(),
1246         root->appendNew<Value>(
1247             proc, Add, Origin(),
1248             root->appendNew<Const32Value>(proc, Origin(), 1),
1249             root->appendNew<Value>(
1250                 proc, Trunc, Origin(),
1251                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1252
1253     CHECK(compileAndRun<int>(proc, value) == value + 1);
1254 }
1255
1256 void testLoadOffset()
1257 {
1258     Procedure proc;
1259     BasicBlock* root = proc.addBlock();
1260     int array[] = { 1, 2 };
1261     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1262     root->appendNew<ControlValue>(
1263         proc, Return, Origin(),
1264         root->appendNew<Value>(
1265             proc, Add, Origin(),
1266             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
1267             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
1268
1269     CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
1270 }
1271
1272 void testLoadOffsetNotConstant()
1273 {
1274     Procedure proc;
1275     BasicBlock* root = proc.addBlock();
1276     int array[] = { 1, 2 };
1277     Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1278     root->appendNew<ControlValue>(
1279         proc, Return, Origin(),
1280         root->appendNew<Value>(
1281             proc, Add, Origin(),
1282             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
1283             root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
1284
1285     CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
1286 }
1287
1288 void testLoadOffsetUsingAdd()
1289 {
1290     Procedure proc;
1291     BasicBlock* root = proc.addBlock();
1292     int array[] = { 1, 2 };
1293     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1294     root->appendNew<ControlValue>(
1295         proc, Return, Origin(),
1296         root->appendNew<Value>(
1297             proc, Add, Origin(),
1298             root->appendNew<MemoryValue>(
1299                 proc, Load, Int32, Origin(),
1300                 root->appendNew<Value>(
1301                     proc, Add, Origin(), arrayPtr,
1302                     root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
1303             root->appendNew<MemoryValue>(
1304                 proc, Load, Int32, Origin(),
1305                 root->appendNew<Value>(
1306                     proc, Add, Origin(), arrayPtr,
1307                     root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
1308     
1309     CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
1310 }
1311
1312 void testLoadOffsetUsingAddInterference()
1313 {
1314     Procedure proc;
1315     BasicBlock* root = proc.addBlock();
1316     int array[] = { 1, 2 };
1317     ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
1318     ArgumentRegValue* otherArrayPtr =
1319         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1320     Const32Value* theNumberOfTheBeast = root->appendNew<Const32Value>(proc, Origin(), 666);
1321     MemoryValue* left = root->appendNew<MemoryValue>(
1322         proc, Load, Int32, Origin(),
1323         root->appendNew<Value>(
1324             proc, Add, Origin(), arrayPtr,
1325             root->appendNew<ConstPtrValue>(proc, Origin(), 0)));
1326     MemoryValue* right = root->appendNew<MemoryValue>(
1327         proc, Load, Int32, Origin(),
1328         root->appendNew<Value>(
1329             proc, Add, Origin(), arrayPtr,
1330             root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))));
1331     root->appendNew<MemoryValue>(
1332         proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, 0);
1333     root->appendNew<MemoryValue>(
1334         proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, sizeof(int));
1335     root->appendNew<ControlValue>(
1336         proc, Return, Origin(),
1337         root->appendNew<Value>(
1338             proc, Add, Origin(), left, right));
1339     
1340     CHECK(compileAndRun<int>(proc, &array[0]) == 1 + 2);
1341     CHECK(array[0] == 666);
1342     CHECK(array[1] == 666);
1343 }
1344
1345 void testLoadOffsetUsingAddNotConstant()
1346 {
1347     Procedure proc;
1348     BasicBlock* root = proc.addBlock();
1349     int array[] = { 1, 2 };
1350     Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1351     root->appendNew<ControlValue>(
1352         proc, Return, Origin(),
1353         root->appendNew<Value>(
1354             proc, Add, Origin(),
1355             root->appendNew<MemoryValue>(
1356                 proc, Load, Int32, Origin(),
1357                 root->appendNew<Value>(
1358                     proc, Add, Origin(), arrayPtr,
1359                     root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
1360             root->appendNew<MemoryValue>(
1361                 proc, Load, Int32, Origin(),
1362                 root->appendNew<Value>(
1363                     proc, Add, Origin(), arrayPtr,
1364                     root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
1365     
1366     CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
1367 }
1368
1369 void testFramePointer()
1370 {
1371     Procedure proc;
1372     BasicBlock* root = proc.addBlock();
1373     root->appendNew<ControlValue>(
1374         proc, Return, Origin(),
1375         root->appendNew<Value>(proc, FramePointer, Origin()));
1376
1377     void* fp = compileAndRun<void*>(proc);
1378     CHECK(fp < &proc);
1379     CHECK(fp >= bitwise_cast<char*>(&proc) - 10000);
1380 }
1381
1382 void testStackSlot()
1383 {
1384     Procedure proc;
1385     BasicBlock* root = proc.addBlock();
1386     root->appendNew<ControlValue>(
1387         proc, Return, Origin(),
1388         root->appendNew<StackSlotValue>(proc, Origin(), 1, StackSlotKind::Anonymous));
1389
1390     void* stackSlot = compileAndRun<void*>(proc);
1391     CHECK(stackSlot < &proc);
1392     CHECK(stackSlot >= bitwise_cast<char*>(&proc) - 10000);
1393 }
1394
1395 void testLoadFromFramePointer()
1396 {
1397     Procedure proc;
1398     BasicBlock* root = proc.addBlock();
1399     root->appendNew<ControlValue>(
1400         proc, Return, Origin(),
1401         root->appendNew<MemoryValue>(
1402             proc, Load, pointerType(), Origin(),
1403             root->appendNew<Value>(proc, FramePointer, Origin())));
1404
1405     void* fp = compileAndRun<void*>(proc);
1406     void* myFP = __builtin_frame_address(0);
1407     CHECK(fp <= myFP);
1408     CHECK(fp >= bitwise_cast<char*>(myFP) - 10000);
1409 }
1410
1411 void testStoreLoadStackSlot(int value)
1412 {
1413     Procedure proc;
1414     BasicBlock* root = proc.addBlock();
1415
1416     StackSlotValue* stack = root->appendNew<StackSlotValue>(
1417         proc, Origin(), sizeof(int), StackSlotKind::Anonymous);
1418
1419     root->appendNew<MemoryValue>(
1420         proc, Store, Origin(),
1421         root->appendNew<Value>(
1422             proc, Trunc, Origin(),
1423             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1424         stack);
1425     
1426     root->appendNew<ControlValue>(
1427         proc, Return, Origin(),
1428         root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), stack));
1429
1430     CHECK(compileAndRun<int>(proc, value) == value);
1431 }
1432
1433 void testBranch()
1434 {
1435     Procedure proc;
1436     BasicBlock* root = proc.addBlock();
1437     BasicBlock* thenCase = proc.addBlock();
1438     BasicBlock* elseCase = proc.addBlock();
1439
1440     root->appendNew<ControlValue>(
1441         proc, Branch, Origin(),
1442         root->appendNew<Value>(
1443             proc, Trunc, Origin(),
1444             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1445         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1446
1447     thenCase->appendNew<ControlValue>(
1448         proc, Return, Origin(),
1449         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1450
1451     elseCase->appendNew<ControlValue>(
1452         proc, Return, Origin(),
1453         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1454
1455     auto code = compile(proc);
1456     CHECK(invoke<int>(code, 42) == 1);
1457     CHECK(invoke<int>(code, 0) == 0);
1458 }
1459
1460 void testBranchPtr()
1461 {
1462     Procedure proc;
1463     BasicBlock* root = proc.addBlock();
1464     BasicBlock* thenCase = proc.addBlock();
1465     BasicBlock* elseCase = proc.addBlock();
1466
1467     root->appendNew<ControlValue>(
1468         proc, Branch, Origin(),
1469         root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1470         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1471
1472     thenCase->appendNew<ControlValue>(
1473         proc, Return, Origin(),
1474         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1475
1476     elseCase->appendNew<ControlValue>(
1477         proc, Return, Origin(),
1478         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1479
1480     auto code = compile(proc);
1481     CHECK(invoke<int>(code, static_cast<intptr_t>(42)) == 1);
1482     CHECK(invoke<int>(code, static_cast<intptr_t>(0)) == 0);
1483 }
1484
1485 void testDiamond()
1486 {
1487     Procedure proc;
1488     BasicBlock* root = proc.addBlock();
1489     BasicBlock* thenCase = proc.addBlock();
1490     BasicBlock* elseCase = proc.addBlock();
1491     BasicBlock* done = proc.addBlock();
1492
1493     root->appendNew<ControlValue>(
1494         proc, Branch, Origin(),
1495         root->appendNew<Value>(
1496             proc, Trunc, Origin(),
1497             root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1498         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1499
1500     UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
1501         proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1502     thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
1503
1504     UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
1505         proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1506     elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
1507
1508     Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
1509     thenResult->setPhi(phi);
1510     elseResult->setPhi(phi);
1511     done->appendNew<ControlValue>(proc, Return, Origin(), phi);
1512
1513     auto code = compile(proc);
1514     CHECK(invoke<int>(code, 42) == 1);
1515     CHECK(invoke<int>(code, 0) == 0);
1516 }
1517
1518 void testBranchNotEqual()
1519 {
1520     Procedure proc;
1521     BasicBlock* root = proc.addBlock();
1522     BasicBlock* thenCase = proc.addBlock();
1523     BasicBlock* elseCase = proc.addBlock();
1524
1525     root->appendNew<ControlValue>(
1526         proc, Branch, Origin(),
1527         root->appendNew<Value>(
1528             proc, NotEqual, Origin(),
1529             root->appendNew<Value>(
1530                 proc, Trunc, Origin(),
1531                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1532             root->appendNew<Const32Value>(proc, Origin(), 0)),
1533         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1534
1535     thenCase->appendNew<ControlValue>(
1536         proc, Return, Origin(),
1537         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1538
1539     elseCase->appendNew<ControlValue>(
1540         proc, Return, Origin(),
1541         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1542
1543     auto code = compile(proc);
1544     CHECK(invoke<int>(code, 42) == 1);
1545     CHECK(invoke<int>(code, 0) == 0);
1546 }
1547
1548 void testBranchNotEqualCommute()
1549 {
1550     Procedure proc;
1551     BasicBlock* root = proc.addBlock();
1552     BasicBlock* thenCase = proc.addBlock();
1553     BasicBlock* elseCase = proc.addBlock();
1554
1555     root->appendNew<ControlValue>(
1556         proc, Branch, Origin(),
1557         root->appendNew<Value>(
1558             proc, NotEqual, Origin(),
1559             root->appendNew<Const32Value>(proc, Origin(), 0),
1560             root->appendNew<Value>(
1561                 proc, Trunc, Origin(),
1562                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
1563         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1564
1565     thenCase->appendNew<ControlValue>(
1566         proc, Return, Origin(),
1567         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1568
1569     elseCase->appendNew<ControlValue>(
1570         proc, Return, Origin(),
1571         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1572
1573     auto code = compile(proc);
1574     CHECK(invoke<int>(code, 42) == 1);
1575     CHECK(invoke<int>(code, 0) == 0);
1576 }
1577
1578 void testBranchNotEqualNotEqual()
1579 {
1580     Procedure proc;
1581     BasicBlock* root = proc.addBlock();
1582     BasicBlock* thenCase = proc.addBlock();
1583     BasicBlock* elseCase = proc.addBlock();
1584
1585     root->appendNew<ControlValue>(
1586         proc, Branch, Origin(),
1587         root->appendNew<Value>(
1588             proc, NotEqual, Origin(),
1589             root->appendNew<Value>(
1590                 proc, NotEqual, Origin(),
1591                 root->appendNew<Value>(
1592                     proc, Trunc, Origin(),
1593                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1594                 root->appendNew<Const32Value>(proc, Origin(), 0)),
1595             root->appendNew<Const32Value>(proc, Origin(), 0)),
1596         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1597
1598     thenCase->appendNew<ControlValue>(
1599         proc, Return, Origin(),
1600         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1601
1602     elseCase->appendNew<ControlValue>(
1603         proc, Return, Origin(),
1604         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1605
1606     auto code = compile(proc);
1607     CHECK(invoke<int>(code, 42) == 1);
1608     CHECK(invoke<int>(code, 0) == 0);
1609 }
1610
1611 void testBranchEqual()
1612 {
1613     Procedure proc;
1614     BasicBlock* root = proc.addBlock();
1615     BasicBlock* thenCase = proc.addBlock();
1616     BasicBlock* elseCase = proc.addBlock();
1617
1618     root->appendNew<ControlValue>(
1619         proc, Branch, Origin(),
1620         root->appendNew<Value>(
1621             proc, Equal, Origin(),
1622             root->appendNew<Value>(
1623                 proc, Trunc, Origin(),
1624                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1625             root->appendNew<Const32Value>(proc, Origin(), 0)),
1626         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1627
1628     thenCase->appendNew<ControlValue>(
1629         proc, Return, Origin(),
1630         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
1631
1632     elseCase->appendNew<ControlValue>(
1633         proc, Return, Origin(),
1634         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
1635
1636     auto code = compile(proc);
1637     CHECK(invoke<int>(code, 42) == 1);
1638     CHECK(invoke<int>(code, 0) == 0);
1639 }
1640
1641 void testBranchEqualEqual()
1642 {
1643     Procedure proc;
1644     BasicBlock* root = proc.addBlock();
1645     BasicBlock* thenCase = proc.addBlock();
1646     BasicBlock* elseCase = proc.addBlock();
1647
1648     root->appendNew<ControlValue>(
1649         proc, Branch, Origin(),
1650         root->appendNew<Value>(
1651             proc, Equal, Origin(),
1652             root->appendNew<Value>(
1653                 proc, Equal, Origin(),
1654                 root->appendNew<Value>(
1655                     proc, Trunc, Origin(),
1656                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1657                 root->appendNew<Const32Value>(proc, Origin(), 0)),
1658             root->appendNew<Const32Value>(proc, Origin(), 0)),
1659         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1660
1661     thenCase->appendNew<ControlValue>(
1662         proc, Return, Origin(),
1663         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1664
1665     elseCase->appendNew<ControlValue>(
1666         proc, Return, Origin(),
1667         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1668
1669     auto code = compile(proc);
1670     CHECK(invoke<int>(code, 42) == 1);
1671     CHECK(invoke<int>(code, 0) == 0);
1672 }
1673
1674 void testBranchEqualCommute()
1675 {
1676     Procedure proc;
1677     BasicBlock* root = proc.addBlock();
1678     BasicBlock* thenCase = proc.addBlock();
1679     BasicBlock* elseCase = proc.addBlock();
1680
1681     root->appendNew<ControlValue>(
1682         proc, Branch, Origin(),
1683         root->appendNew<Value>(
1684             proc, Equal, Origin(),
1685             root->appendNew<Const32Value>(proc, Origin(), 0),
1686             root->appendNew<Value>(
1687                 proc, Trunc, Origin(),
1688                 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
1689         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1690
1691     thenCase->appendNew<ControlValue>(
1692         proc, Return, Origin(),
1693         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
1694
1695     elseCase->appendNew<ControlValue>(
1696         proc, Return, Origin(),
1697         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
1698
1699     auto code = compile(proc);
1700     CHECK(invoke<int>(code, 42) == 1);
1701     CHECK(invoke<int>(code, 0) == 0);
1702 }
1703
1704 void testBranchEqualEqual1()
1705 {
1706     Procedure proc;
1707     BasicBlock* root = proc.addBlock();
1708     BasicBlock* thenCase = proc.addBlock();
1709     BasicBlock* elseCase = proc.addBlock();
1710
1711     root->appendNew<ControlValue>(
1712         proc, Branch, Origin(),
1713         root->appendNew<Value>(
1714             proc, Equal, Origin(),
1715             root->appendNew<Value>(
1716                 proc, Equal, Origin(),
1717                 root->appendNew<Value>(
1718                     proc, Trunc, Origin(),
1719                     root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1720                 root->appendNew<Const32Value>(proc, Origin(), 0)),
1721             root->appendNew<Const32Value>(proc, Origin(), 1)),
1722         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1723
1724     thenCase->appendNew<ControlValue>(
1725         proc, Return, Origin(),
1726         thenCase->appendNew<Const32Value>(proc, Origin(), 0));
1727
1728     elseCase->appendNew<ControlValue>(
1729         proc, Return, Origin(),
1730         elseCase->appendNew<Const32Value>(proc, Origin(), 1));
1731
1732     auto code = compile(proc);
1733     CHECK(invoke<int>(code, 42) == 1);
1734     CHECK(invoke<int>(code, 0) == 0);
1735 }
1736
1737 void testBranchFold(int value)
1738 {
1739     Procedure proc;
1740     BasicBlock* root = proc.addBlock();
1741     BasicBlock* thenCase = proc.addBlock();
1742     BasicBlock* elseCase = proc.addBlock();
1743
1744     root->appendNew<ControlValue>(
1745         proc, Branch, Origin(),
1746         root->appendNew<Const32Value>(proc, Origin(), value),
1747         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1748
1749     thenCase->appendNew<ControlValue>(
1750         proc, Return, Origin(),
1751         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1752
1753     elseCase->appendNew<ControlValue>(
1754         proc, Return, Origin(),
1755         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1756
1757     CHECK(compileAndRun<int>(proc) == !!value);
1758 }
1759
1760 void testDiamondFold(int value)
1761 {
1762     Procedure proc;
1763     BasicBlock* root = proc.addBlock();
1764     BasicBlock* thenCase = proc.addBlock();
1765     BasicBlock* elseCase = proc.addBlock();
1766     BasicBlock* done = proc.addBlock();
1767
1768     root->appendNew<ControlValue>(
1769         proc, Branch, Origin(),
1770         root->appendNew<Const32Value>(proc, Origin(), value),
1771         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1772
1773     UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
1774         proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1775     thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
1776
1777     UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
1778         proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1779     elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
1780
1781     Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
1782     thenResult->setPhi(phi);
1783     elseResult->setPhi(phi);
1784     done->appendNew<ControlValue>(proc, Return, Origin(), phi);
1785
1786     CHECK(compileAndRun<int>(proc) == !!value);
1787 }
1788
1789 void testBranchNotEqualFoldPtr(intptr_t value)
1790 {
1791     Procedure proc;
1792     BasicBlock* root = proc.addBlock();
1793     BasicBlock* thenCase = proc.addBlock();
1794     BasicBlock* elseCase = proc.addBlock();
1795
1796     root->appendNew<ControlValue>(
1797         proc, Branch, Origin(),
1798         root->appendNew<Value>(
1799             proc, NotEqual, Origin(),
1800             root->appendNew<ConstPtrValue>(proc, Origin(), value),
1801             root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
1802         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1803
1804     thenCase->appendNew<ControlValue>(
1805         proc, Return, Origin(),
1806         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1807
1808     elseCase->appendNew<ControlValue>(
1809         proc, Return, Origin(),
1810         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1811
1812     CHECK(compileAndRun<int>(proc) == !!value);
1813 }
1814
1815 void testBranchEqualFoldPtr(intptr_t value)
1816 {
1817     Procedure proc;
1818     BasicBlock* root = proc.addBlock();
1819     BasicBlock* thenCase = proc.addBlock();
1820     BasicBlock* elseCase = proc.addBlock();
1821
1822     root->appendNew<ControlValue>(
1823         proc, Branch, Origin(),
1824         root->appendNew<Value>(
1825             proc, Equal, Origin(),
1826             root->appendNew<ConstPtrValue>(proc, Origin(), value),
1827             root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
1828         FrequentedBlock(thenCase), FrequentedBlock(elseCase));
1829
1830     thenCase->appendNew<ControlValue>(
1831         proc, Return, Origin(),
1832         thenCase->appendNew<Const32Value>(proc, Origin(), 1));
1833
1834     elseCase->appendNew<ControlValue>(
1835         proc, Return, Origin(),
1836         elseCase->appendNew<Const32Value>(proc, Origin(), 0));
1837
1838     CHECK(compileAndRun<int>(proc) == !value);
1839 }
1840
1841 void testComplex(unsigned numVars, unsigned numConstructs)
1842 {
1843     double before = monotonicallyIncreasingTimeMS();
1844     
1845     Procedure proc;
1846     BasicBlock* current = proc.addBlock();
1847
1848     Const32Value* one = current->appendNew<Const32Value>(proc, Origin(), 1);
1849
1850     Vector<int32_t> varSlots;
1851     for (unsigned i = numVars; i--;)
1852         varSlots.append(i);
1853
1854     Vector<Value*> vars;
1855     for (int32_t& varSlot : varSlots) {
1856         Value* varSlotPtr = current->appendNew<ConstPtrValue>(proc, Origin(), &varSlot);
1857         vars.append(current->appendNew<MemoryValue>(proc, Load, Int32, Origin(), varSlotPtr));
1858     }
1859
1860     for (unsigned i = 0; i < numConstructs; ++i) {
1861         if (i & 1) {
1862             // Control flow diamond.
1863             unsigned predicateVarIndex = (i >> 1) % numVars;
1864             unsigned thenIncVarIndex = ((i >> 1) + 1) % numVars;
1865             unsigned elseIncVarIndex = ((i >> 1) + 2) % numVars;
1866
1867             BasicBlock* thenBlock = proc.addBlock();
1868             BasicBlock* elseBlock = proc.addBlock();
1869             BasicBlock* continuation = proc.addBlock();
1870
1871             current->appendNew<ControlValue>(
1872                 proc, Branch, Origin(), vars[predicateVarIndex],
1873                 FrequentedBlock(thenBlock), FrequentedBlock(elseBlock));
1874
1875             UpsilonValue* thenThenResult = thenBlock->appendNew<UpsilonValue>(
1876                 proc, Origin(),
1877                 thenBlock->appendNew<Value>(proc, Add, Origin(), vars[thenIncVarIndex], one));
1878             UpsilonValue* thenElseResult = thenBlock->appendNew<UpsilonValue>(
1879                 proc, Origin(), vars[elseIncVarIndex]);
1880             thenBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
1881
1882             UpsilonValue* elseElseResult = elseBlock->appendNew<UpsilonValue>(
1883                 proc, Origin(),
1884                 elseBlock->appendNew<Value>(proc, Add, Origin(), vars[elseIncVarIndex], one));
1885             UpsilonValue* elseThenResult = elseBlock->appendNew<UpsilonValue>(
1886                 proc, Origin(), vars[thenIncVarIndex]);
1887             elseBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
1888
1889             Value* thenPhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
1890             thenThenResult->setPhi(thenPhi);
1891             elseThenResult->setPhi(thenPhi);
1892             vars[thenIncVarIndex] = thenPhi;
1893             
1894             Value* elsePhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
1895             thenElseResult->setPhi(elsePhi);
1896             elseElseResult->setPhi(elsePhi);
1897             vars[elseIncVarIndex] = thenPhi;
1898             
1899             current = continuation;
1900         } else {
1901             // Loop.
1902
1903             BasicBlock* loopEntry = proc.addBlock();
1904             BasicBlock* loopReentry = proc.addBlock();
1905             BasicBlock* loopBody = proc.addBlock();
1906             BasicBlock* loopExit = proc.addBlock();
1907             BasicBlock* loopSkip = proc.addBlock();
1908             BasicBlock* continuation = proc.addBlock();
1909             
1910             Value* startIndex = vars[(i >> 1) % numVars];
1911             Value* startSum = current->appendNew<Const32Value>(proc, Origin(), 0);
1912             current->appendNew<ControlValue>(
1913                 proc, Branch, Origin(), startIndex,
1914                 FrequentedBlock(loopEntry), FrequentedBlock(loopSkip));
1915
1916             UpsilonValue* startIndexForBody = loopEntry->appendNew<UpsilonValue>(
1917                 proc, Origin(), startIndex);
1918             UpsilonValue* startSumForBody = loopEntry->appendNew<UpsilonValue>(
1919                 proc, Origin(), startSum);
1920             loopEntry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
1921
1922             Value* bodyIndex = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
1923             startIndexForBody->setPhi(bodyIndex);
1924             Value* bodySum = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
1925             startSumForBody->setPhi(bodySum);
1926             Value* newBodyIndex = loopBody->appendNew<Value>(proc, Sub, Origin(), bodyIndex, one);
1927             Value* newBodySum = loopBody->appendNew<Value>(
1928                 proc, Add, Origin(),
1929                 bodySum,
1930                 loopBody->appendNew<MemoryValue>(
1931                     proc, Load, Int32, Origin(),
1932                     loopBody->appendNew<Value>(
1933                         proc, Add, Origin(),
1934                         loopBody->appendNew<ConstPtrValue>(proc, Origin(), varSlots.data()),
1935                         loopBody->appendNew<Value>(
1936                             proc, Shl, Origin(),
1937                             loopBody->appendNew<Value>(
1938                                 proc, ZExt32, Origin(),
1939                                 loopBody->appendNew<Value>(
1940                                     proc, BitAnd, Origin(),
1941                                     newBodyIndex,
1942                                     loopBody->appendNew<Const32Value>(
1943                                         proc, Origin(), numVars - 1))),
1944                             loopBody->appendNew<Const32Value>(proc, Origin(), 2)))));
1945             loopBody->appendNew<ControlValue>(
1946                 proc, Branch, Origin(), newBodyIndex,
1947                 FrequentedBlock(loopReentry), FrequentedBlock(loopExit));
1948
1949             loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodyIndex, bodyIndex);
1950             loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodySum, bodySum);
1951             loopReentry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
1952
1953             UpsilonValue* exitSum = loopExit->appendNew<UpsilonValue>(proc, Origin(), newBodySum);
1954             loopExit->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
1955
1956             UpsilonValue* skipSum = loopSkip->appendNew<UpsilonValue>(proc, Origin(), startSum);
1957             loopSkip->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
1958
1959             Value* finalSum = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
1960             exitSum->setPhi(finalSum);
1961             skipSum->setPhi(finalSum);
1962
1963             current = continuation;
1964             vars[((i >> 1) + 1) % numVars] = finalSum;
1965         }
1966     }
1967
1968     current->appendNew<ControlValue>(proc, Return, Origin(), vars[0]);
1969
1970     compile(proc);
1971
1972     double after = monotonicallyIncreasingTimeMS();
1973     dataLog("    That took ", after - before, " ms.\n");
1974 }
1975
1976 void testSimplePatchpoint()
1977 {
1978     Procedure proc;
1979     BasicBlock* root = proc.addBlock();
1980     Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1981     Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1982     PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
1983     patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
1984     patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
1985     patchpoint->setGenerator(
1986         [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
1987             CHECK(params.reps.size() == 3);
1988             CHECK(params.reps[0].isGPR());
1989             CHECK(params.reps[1].isGPR());
1990             CHECK(params.reps[2].isGPR());
1991             jit.move(params.reps[1].gpr(), params.reps[0].gpr());
1992             jit.add32(params.reps[2].gpr(), params.reps[0].gpr());
1993         });
1994     root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
1995
1996     CHECK(compileAndRun<int>(proc, 1, 2) == 3);
1997 }
1998
1999 #define RUN(test) do {                          \
2000         if (!shouldRun(#test))                  \
2001             break;                              \
2002         dataLog(#test ":\n");                   \
2003         test;                                   \
2004         dataLog("    OK!\n");                   \
2005         didRun++;                               \
2006     } while (false);
2007
2008 void run(const char* filter)
2009 {
2010     JSC::initializeThreading();
2011     vm = &VM::create(LargeHeap).leakRef();
2012
2013     auto shouldRun = [&] (const char* testName) -> bool {
2014         return !!strcasestr(testName, filter);
2015     };
2016     unsigned didRun = 0;
2017
2018     RUN(test42());
2019     RUN(testLoad42());
2020     RUN(testArg(43));
2021     RUN(testReturnConst64(5));
2022     RUN(testReturnConst64(-42));
2023
2024     RUN(testAddArgs(1, 1));
2025     RUN(testAddArgs(1, 2));
2026     RUN(testAddArgImm(1, 2));
2027     RUN(testAddArgImm(0, 2));
2028     RUN(testAddArgImm(1, 0));
2029     RUN(testAddImmArg(1, 2));
2030     RUN(testAddImmArg(0, 2));
2031     RUN(testAddImmArg(1, 0));
2032     RUN(testAddArgs32(1, 1));
2033     RUN(testAddArgs32(1, 2));
2034
2035     RUN(testSubArgs(1, 1));
2036     RUN(testSubArgs(1, 2));
2037     RUN(testSubArgs(13, -42));
2038     RUN(testSubArgs(-13, 42));
2039     RUN(testSubArgImm(1, 1));
2040     RUN(testSubArgImm(1, 2));
2041     RUN(testSubArgImm(13, -42));
2042     RUN(testSubArgImm(-13, 42));
2043     RUN(testSubArgImm(42, 0));
2044     RUN(testSubImmArg(1, 1));
2045     RUN(testSubImmArg(1, 2));
2046     RUN(testSubImmArg(13, -42));
2047     RUN(testSubImmArg(-13, 42));
2048
2049     RUN(testSubArgs32(1, 1));
2050     RUN(testSubArgs32(1, 2));
2051     RUN(testSubArgs32(13, -42));
2052     RUN(testSubArgs32(-13, 42));
2053     RUN(testSubArgImm32(1, 1));
2054     RUN(testSubArgImm32(1, 2));
2055     RUN(testSubArgImm32(13, -42));
2056     RUN(testSubArgImm32(-13, 42));
2057     RUN(testSubImmArg32(1, 1));
2058     RUN(testSubImmArg32(1, 2));
2059     RUN(testSubImmArg32(13, -42));
2060     RUN(testSubImmArg32(-13, 42));
2061
2062     RUN(testBitAndArgs(43, 43));
2063     RUN(testBitAndArgs(43, 0));
2064     RUN(testBitAndArgs(10, 3));
2065     RUN(testBitAndArgs(42, 0xffffffffffffffff));
2066     RUN(testBitAndSameArg(43));
2067     RUN(testBitAndSameArg(0));
2068     RUN(testBitAndSameArg(3));
2069     RUN(testBitAndSameArg(0xffffffffffffffff));
2070     RUN(testBitAndImms(43, 43));
2071     RUN(testBitAndImms(43, 0));
2072     RUN(testBitAndImms(10, 3));
2073     RUN(testBitAndImms(42, 0xffffffffffffffff));
2074     RUN(testBitAndArgImm(43, 43));
2075     RUN(testBitAndArgImm(43, 0));
2076     RUN(testBitAndArgImm(10, 3));
2077     RUN(testBitAndArgImm(42, 0xffffffffffffffff));
2078     RUN(testBitAndImmArg(43, 43));
2079     RUN(testBitAndImmArg(43, 0));
2080     RUN(testBitAndImmArg(10, 3));
2081     RUN(testBitAndImmArg(42, 0xffffffffffffffff));
2082     RUN(testBitAndBitAndArgImmImm(2, 7, 3));
2083     RUN(testBitAndBitAndArgImmImm(1, 6, 6));
2084     RUN(testBitAndBitAndArgImmImm(0xffff, 24, 7));
2085     RUN(testBitAndImmBitAndArgImm(7, 2, 3));
2086     RUN(testBitAndImmBitAndArgImm(6, 1, 6));
2087     RUN(testBitAndImmBitAndArgImm(24, 0xffff, 7));
2088     RUN(testBitAndArgs32(43, 43));
2089     RUN(testBitAndArgs32(43, 0));
2090     RUN(testBitAndArgs32(10, 3));
2091     RUN(testBitAndArgs32(42, 0xffffffff));
2092     RUN(testBitAndSameArg32(43));
2093     RUN(testBitAndSameArg32(0));
2094     RUN(testBitAndSameArg32(3));
2095     RUN(testBitAndSameArg32(0xffffffff));
2096     RUN(testBitAndImms32(43, 43));
2097     RUN(testBitAndImms32(43, 0));
2098     RUN(testBitAndImms32(10, 3));
2099     RUN(testBitAndImms32(42, 0xffffffff));
2100     RUN(testBitAndArgImm32(43, 43));
2101     RUN(testBitAndArgImm32(43, 0));
2102     RUN(testBitAndArgImm32(10, 3));
2103     RUN(testBitAndArgImm32(42, 0xffffffff));
2104     RUN(testBitAndImmArg32(43, 43));
2105     RUN(testBitAndImmArg32(43, 0));
2106     RUN(testBitAndImmArg32(10, 3));
2107     RUN(testBitAndImmArg32(42, 0xffffffff));
2108     RUN(testBitAndBitAndArgImmImm32(2, 7, 3));
2109     RUN(testBitAndBitAndArgImmImm32(1, 6, 6));
2110     RUN(testBitAndBitAndArgImmImm32(0xffff, 24, 7));
2111     RUN(testBitAndImmBitAndArgImm32(7, 2, 3));
2112     RUN(testBitAndImmBitAndArgImm32(6, 1, 6));
2113     RUN(testBitAndImmBitAndArgImm32(24, 0xffff, 7));
2114
2115     RUN(testBitOrArgs(43, 43));
2116     RUN(testBitOrArgs(43, 0));
2117     RUN(testBitOrArgs(10, 3));
2118     RUN(testBitOrArgs(42, 0xffffffffffffffff));
2119     RUN(testBitOrSameArg(43));
2120     RUN(testBitOrSameArg(0));
2121     RUN(testBitOrSameArg(3));
2122     RUN(testBitOrSameArg(0xffffffffffffffff));
2123     RUN(testBitOrImms(43, 43));
2124     RUN(testBitOrImms(43, 0));
2125     RUN(testBitOrImms(10, 3));
2126     RUN(testBitOrImms(42, 0xffffffffffffffff));
2127     RUN(testBitOrArgImm(43, 43));
2128     RUN(testBitOrArgImm(43, 0));
2129     RUN(testBitOrArgImm(10, 3));
2130     RUN(testBitOrArgImm(42, 0xffffffffffffffff));
2131     RUN(testBitOrImmArg(43, 43));
2132     RUN(testBitOrImmArg(43, 0));
2133     RUN(testBitOrImmArg(10, 3));
2134     RUN(testBitOrImmArg(42, 0xffffffffffffffff));
2135     RUN(testBitOrBitOrArgImmImm(2, 7, 3));
2136     RUN(testBitOrBitOrArgImmImm(1, 6, 6));
2137     RUN(testBitOrBitOrArgImmImm(0xffff, 24, 7));
2138     RUN(testBitOrImmBitOrArgImm(7, 2, 3));
2139     RUN(testBitOrImmBitOrArgImm(6, 1, 6));
2140     RUN(testBitOrImmBitOrArgImm(24, 0xffff, 7));
2141     RUN(testBitOrArgs32(43, 43));
2142     RUN(testBitOrArgs32(43, 0));
2143     RUN(testBitOrArgs32(10, 3));
2144     RUN(testBitOrArgs32(42, 0xffffffff));
2145     RUN(testBitOrSameArg32(43));
2146     RUN(testBitOrSameArg32(0));
2147     RUN(testBitOrSameArg32(3));
2148     RUN(testBitOrSameArg32(0xffffffff));
2149     RUN(testBitOrImms32(43, 43));
2150     RUN(testBitOrImms32(43, 0));
2151     RUN(testBitOrImms32(10, 3));
2152     RUN(testBitOrImms32(42, 0xffffffff));
2153     RUN(testBitOrArgImm32(43, 43));
2154     RUN(testBitOrArgImm32(43, 0));
2155     RUN(testBitOrArgImm32(10, 3));
2156     RUN(testBitOrArgImm32(42, 0xffffffff));
2157     RUN(testBitOrImmArg32(43, 43));
2158     RUN(testBitOrImmArg32(43, 0));
2159     RUN(testBitOrImmArg32(10, 3));
2160     RUN(testBitOrImmArg32(42, 0xffffffff));
2161     RUN(testBitOrBitOrArgImmImm32(2, 7, 3));
2162     RUN(testBitOrBitOrArgImmImm32(1, 6, 6));
2163     RUN(testBitOrBitOrArgImmImm32(0xffff, 24, 7));
2164     RUN(testBitOrImmBitOrArgImm32(7, 2, 3));
2165     RUN(testBitOrImmBitOrArgImm32(6, 1, 6));
2166     RUN(testBitOrImmBitOrArgImm32(24, 0xffff, 7));
2167
2168     RUN(testBitXorArgs(43, 43));
2169     RUN(testBitXorArgs(43, 0));
2170     RUN(testBitXorArgs(10, 3));
2171     RUN(testBitXorArgs(42, 0xffffffffffffffff));
2172     RUN(testBitXorSameArg(43));
2173     RUN(testBitXorSameArg(0));
2174     RUN(testBitXorSameArg(3));
2175     RUN(testBitXorSameArg(0xffffffffffffffff));
2176     RUN(testBitXorImms(43, 43));
2177     RUN(testBitXorImms(43, 0));
2178     RUN(testBitXorImms(10, 3));
2179     RUN(testBitXorImms(42, 0xffffffffffffffff));
2180     RUN(testBitXorArgImm(43, 43));
2181     RUN(testBitXorArgImm(43, 0));
2182     RUN(testBitXorArgImm(10, 3));
2183     RUN(testBitXorArgImm(42, 0xffffffffffffffff));
2184     RUN(testBitXorImmArg(43, 43));
2185     RUN(testBitXorImmArg(43, 0));
2186     RUN(testBitXorImmArg(10, 3));
2187     RUN(testBitXorImmArg(42, 0xffffffffffffffff));
2188     RUN(testBitXorBitXorArgImmImm(2, 7, 3));
2189     RUN(testBitXorBitXorArgImmImm(1, 6, 6));
2190     RUN(testBitXorBitXorArgImmImm(0xffff, 24, 7));
2191     RUN(testBitXorImmBitXorArgImm(7, 2, 3));
2192     RUN(testBitXorImmBitXorArgImm(6, 1, 6));
2193     RUN(testBitXorImmBitXorArgImm(24, 0xffff, 7));
2194     RUN(testBitXorArgs32(43, 43));
2195     RUN(testBitXorArgs32(43, 0));
2196     RUN(testBitXorArgs32(10, 3));
2197     RUN(testBitXorArgs32(42, 0xffffffff));
2198     RUN(testBitXorSameArg32(43));
2199     RUN(testBitXorSameArg32(0));
2200     RUN(testBitXorSameArg32(3));
2201     RUN(testBitXorSameArg32(0xffffffff));
2202     RUN(testBitXorImms32(43, 43));
2203     RUN(testBitXorImms32(43, 0));
2204     RUN(testBitXorImms32(10, 3));
2205     RUN(testBitXorImms32(42, 0xffffffff));
2206     RUN(testBitXorArgImm32(43, 43));
2207     RUN(testBitXorArgImm32(43, 0));
2208     RUN(testBitXorArgImm32(10, 3));
2209     RUN(testBitXorArgImm32(42, 0xffffffff));
2210     RUN(testBitXorImmArg32(43, 43));
2211     RUN(testBitXorImmArg32(43, 0));
2212     RUN(testBitXorImmArg32(10, 3));
2213     RUN(testBitXorImmArg32(42, 0xffffffff));
2214     RUN(testBitXorBitXorArgImmImm32(2, 7, 3));
2215     RUN(testBitXorBitXorArgImmImm32(1, 6, 6));
2216     RUN(testBitXorBitXorArgImmImm32(0xffff, 24, 7));
2217     RUN(testBitXorImmBitXorArgImm32(7, 2, 3));
2218     RUN(testBitXorImmBitXorArgImm32(6, 1, 6));
2219     RUN(testBitXorImmBitXorArgImm32(24, 0xffff, 7));
2220
2221     RUN(testStore(44));
2222     RUN(testStoreConstant(49));
2223     RUN(testStoreConstantPtr(49));
2224     RUN(testTrunc((static_cast<int64_t>(1) << 40) + 42));
2225     RUN(testAdd1(45));
2226     RUN(testAdd1Ptr(51));
2227     RUN(testAdd1Ptr(bitwise_cast<intptr_t>(vm)));
2228     RUN(testNeg32(52));
2229     RUN(testNegPtr(53));
2230     RUN(testStoreAddLoad(46));
2231     RUN(testStoreSubLoad(46));
2232     RUN(testStoreAddLoadInterference(52));
2233     RUN(testStoreAddAndLoad(47, 0xffff));
2234     RUN(testStoreAddAndLoad(470000, 0xffff));
2235     RUN(testStoreNegLoad32(54));
2236     RUN(testStoreNegLoadPtr(55));
2237     RUN(testAdd1Uncommuted(48));
2238     RUN(testLoadOffset());
2239     RUN(testLoadOffsetNotConstant());
2240     RUN(testLoadOffsetUsingAdd());
2241     RUN(testLoadOffsetUsingAddInterference());
2242     RUN(testLoadOffsetUsingAddNotConstant());
2243     RUN(testFramePointer());
2244     RUN(testStackSlot());
2245     RUN(testLoadFromFramePointer());
2246     RUN(testStoreLoadStackSlot(50));
2247     RUN(testBranch());
2248     RUN(testBranchPtr());
2249     RUN(testDiamond());
2250     RUN(testBranchNotEqual());
2251     RUN(testBranchNotEqualCommute());
2252     RUN(testBranchNotEqualNotEqual());
2253     RUN(testBranchEqual());
2254     RUN(testBranchEqualEqual());
2255     RUN(testBranchEqualCommute());
2256     RUN(testBranchEqualEqual1());
2257     RUN(testBranchFold(42));
2258     RUN(testBranchFold(0));
2259     RUN(testDiamondFold(42));
2260     RUN(testDiamondFold(0));
2261     RUN(testBranchNotEqualFoldPtr(42));
2262     RUN(testBranchNotEqualFoldPtr(0));
2263     RUN(testBranchEqualFoldPtr(42));
2264     RUN(testBranchEqualFoldPtr(0));
2265
2266     RUN(testComplex(64, 128));
2267     RUN(testComplex(64, 256));
2268     RUN(testComplex(64, 384));
2269     RUN(testComplex(4, 128));
2270     RUN(testComplex(4, 256));
2271     RUN(testComplex(4, 384));
2272
2273     RUN(testSimplePatchpoint());
2274
2275     if (!didRun)
2276         usage();
2277 }
2278
2279 } // anonymous namespace
2280
2281 #else // ENABLE(B3_JIT)
2282
2283 static void run(const char*)
2284 {
2285     dataLog("B3 JIT is not enabled.\n");
2286 }
2287
2288 #endif // ENABLE(B3_JIT)
2289
2290 int main(int argc, char** argv)
2291 {
2292     const char* filter = "";
2293     switch (argc) {
2294     case 1:
2295         break;
2296     case 2:
2297         filter = argv[1];
2298         break;
2299     default:
2300         usage();
2301         break;
2302     }
2303     
2304     run(filter);
2305     return 0;
2306 }
2307