2 * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
28 #include "AllowMacroScratchRegisterUsage.h"
29 #include "B3ArgumentRegValue.h"
30 #include "B3BasicBlockInlines.h"
31 #include "B3CCallValue.h"
32 #include "B3Compilation.h"
33 #include "B3ComputeDivisionMagic.h"
34 #include "B3Const32Value.h"
35 #include "B3ConstPtrValue.h"
36 #include "B3ControlValue.h"
37 #include "B3Effects.h"
38 #include "B3MathExtras.h"
39 #include "B3MemoryValue.h"
40 #include "B3Procedure.h"
41 #include "B3SlotBaseValue.h"
42 #include "B3StackSlot.h"
43 #include "B3StackmapGenerationParams.h"
44 #include "B3SwitchValue.h"
45 #include "B3UpsilonValue.h"
46 #include "B3ValueInlines.h"
47 #include "CCallHelpers.h"
48 #include "InitializeThreading.h"
49 #include "JSCInlines.h"
50 #include "LinkBuffer.h"
56 #include <wtf/NumberOfCores.h>
57 #include <wtf/Threading.h>
59 // We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
60 static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
64 dataLog("Usage: testb3 [<filter>]\n");
65 if (hiddenTruthBecauseNoReturnIsStupid())
72 using namespace JSC::B3;
78 // Nothing fancy for now; we just use the existing WTF assertion machinery.
79 #define CHECK(x) do { \
83 WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
89 std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
91 return std::make_unique<Compilation>(*vm, procedure, optLevel);
94 template<typename T, typename... Arguments>
95 T invoke(const Compilation& code, Arguments... arguments)
97 T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(code.code().executableAddress());
98 return function(arguments...);
101 template<typename T, typename... Arguments>
102 T compileAndRun(Procedure& procedure, Arguments... arguments)
104 return invoke<T>(*compile(procedure), arguments...);
107 void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
110 jit.add32(src1, dest);
112 jit.move(src1, dest);
113 jit.add32(src2, dest);
120 BasicBlock* root = proc.addBlock();
121 Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
122 root->appendNew<ControlValue>(proc, Return, Origin(), const42);
124 CHECK(compileAndRun<int>(proc) == 42);
130 BasicBlock* root = proc.addBlock();
132 root->appendNew<ControlValue>(
133 proc, Return, Origin(),
134 root->appendNew<MemoryValue>(
135 proc, Load, Int32, Origin(),
136 root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
138 CHECK(compileAndRun<int>(proc) == 42);
141 void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
145 BasicBlock* root = proc.addBlock();
147 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
148 root->appendNew<ControlValue>(
149 proc, Return, Origin(),
150 root->appendNew<MemoryValue>(
151 proc, Load, Int64, Origin(),
155 char* address = reinterpret_cast<char*>(&x) - offset64;
156 CHECK(compileAndRun<int64_t>(proc, address) == -42);
160 BasicBlock* root = proc.addBlock();
162 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
163 root->appendNew<ControlValue>(
164 proc, Return, Origin(),
165 root->appendNew<MemoryValue>(
166 proc, Load, Int32, Origin(),
170 char* address = reinterpret_cast<char*>(&x) - offset32;
171 CHECK(compileAndRun<int32_t>(proc, address) == -42);
175 void testLoadOffsetImm9Max()
177 testLoadWithOffsetImpl(255, 255);
180 void testLoadOffsetImm9MaxPlusOne()
182 testLoadWithOffsetImpl(256, 256);
185 void testLoadOffsetImm9MaxPlusTwo()
187 testLoadWithOffsetImpl(257, 257);
190 void testLoadOffsetImm9Min()
192 testLoadWithOffsetImpl(-256, -256);
195 void testLoadOffsetImm9MinMinusOne()
197 testLoadWithOffsetImpl(-257, -257);
200 void testLoadOffsetScaledUnsignedImm12Max()
202 testLoadWithOffsetImpl(32760, 16380);
205 void testLoadOffsetScaledUnsignedOverImm12Max()
207 testLoadWithOffsetImpl(32760, 32760);
208 testLoadWithOffsetImpl(32761, 16381);
209 testLoadWithOffsetImpl(32768, 16384);
212 void testArg(int argument)
215 BasicBlock* root = proc.addBlock();
216 root->appendNew<ControlValue>(
217 proc, Return, Origin(),
218 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
220 CHECK(compileAndRun<int>(proc, argument) == argument);
223 void testReturnConst64(int64_t value)
226 BasicBlock* root = proc.addBlock();
227 root->appendNew<ControlValue>(
228 proc, Return, Origin(),
229 root->appendNew<Const64Value>(proc, Origin(), value));
231 CHECK(compileAndRun<int64_t>(proc) == value);
234 void testAddArg(int a)
237 BasicBlock* root = proc.addBlock();
238 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
239 root->appendNew<ControlValue>(
240 proc, Return, Origin(),
241 root->appendNew<Value>(proc, Add, Origin(), value, value));
243 CHECK(compileAndRun<int>(proc, a) == a + a);
246 void testAddArgs(int a, int b)
249 BasicBlock* root = proc.addBlock();
250 root->appendNew<ControlValue>(
251 proc, Return, Origin(),
252 root->appendNew<Value>(
254 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
255 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
257 CHECK(compileAndRun<int>(proc, a, b) == a + b);
260 void testAddArgImm(int a, int b)
263 BasicBlock* root = proc.addBlock();
264 root->appendNew<ControlValue>(
265 proc, Return, Origin(),
266 root->appendNew<Value>(
268 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
269 root->appendNew<Const64Value>(proc, Origin(), b)));
271 CHECK(compileAndRun<int>(proc, a) == a + b);
274 void testAddImmArg(int a, int b)
277 BasicBlock* root = proc.addBlock();
278 root->appendNew<ControlValue>(
279 proc, Return, Origin(),
280 root->appendNew<Value>(
282 root->appendNew<Const64Value>(proc, Origin(), a),
283 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
285 CHECK(compileAndRun<int>(proc, b) == a + b);
288 void testAddArgMem(int64_t a, int64_t b)
291 BasicBlock* root = proc.addBlock();
292 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
293 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
294 Value* result = root->appendNew<Value>(proc, Add, Origin(),
295 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
297 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
298 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
300 int64_t inputOutput = b;
301 CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
302 CHECK(inputOutput == a + b);
305 void testAddMemArg(int64_t a, int64_t b)
308 BasicBlock* root = proc.addBlock();
309 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
310 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
311 Value* result = root->appendNew<Value>(proc, Add, Origin(),
313 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
314 root->appendNew<ControlValue>(proc, Return, Origin(), result);
316 CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
319 void testAddImmMem(int64_t a, int64_t b)
322 BasicBlock* root = proc.addBlock();
323 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
324 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
325 Value* result = root->appendNew<Value>(proc, Add, Origin(),
326 root->appendNew<Const64Value>(proc, Origin(), a),
328 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
329 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
331 int64_t inputOutput = b;
332 CHECK(!compileAndRun<int>(proc, &inputOutput));
333 CHECK(inputOutput == a + b);
336 void testAddArg32(int a)
339 BasicBlock* root = proc.addBlock();
340 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
341 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
342 root->appendNew<ControlValue>(
343 proc, Return, Origin(),
344 root->appendNew<Value>(proc, Add, Origin(), value, value));
346 CHECK(compileAndRun<int>(proc, a) == a + a);
349 void testAddArgs32(int a, int b)
352 BasicBlock* root = proc.addBlock();
353 root->appendNew<ControlValue>(
354 proc, Return, Origin(),
355 root->appendNew<Value>(
357 root->appendNew<Value>(
358 proc, Trunc, Origin(),
359 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
360 root->appendNew<Value>(
361 proc, Trunc, Origin(),
362 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
364 CHECK(compileAndRun<int>(proc, a, b) == a + b);
367 void testAddArgMem32(int32_t a, int32_t b)
370 BasicBlock* root = proc.addBlock();
371 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
372 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
373 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
374 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
375 Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
376 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
377 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
379 int32_t inputOutput = b;
380 CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
381 CHECK(inputOutput == a + b);
384 void testAddMemArg32(int32_t a, int32_t b)
387 BasicBlock* root = proc.addBlock();
388 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
389 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
390 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
391 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
392 Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
393 root->appendNew<ControlValue>(proc, Return, Origin(), result);
395 CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
398 void testAddImmMem32(int32_t a, int32_t b)
401 BasicBlock* root = proc.addBlock();
402 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
403 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
404 Value* result = root->appendNew<Value>(proc, Add, Origin(),
405 root->appendNew<Const32Value>(proc, Origin(), a),
407 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
408 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
410 int32_t inputOutput = b;
411 CHECK(!compileAndRun<int>(proc, &inputOutput));
412 CHECK(inputOutput == a + b);
415 void testAddLoadTwice()
417 auto test = [&] (unsigned optLevel) {
419 BasicBlock* root = proc.addBlock();
421 Value* load = root->appendNew<MemoryValue>(
422 proc, Load, Int32, Origin(),
423 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
424 root->appendNew<ControlValue>(
425 proc, Return, Origin(),
426 root->appendNew<Value>(proc, Add, Origin(), load, load));
428 auto code = compile(proc, optLevel);
429 CHECK(invoke<int32_t>(*code) == 42 * 2);
436 void testAddArgDouble(double a)
439 BasicBlock* root = proc.addBlock();
440 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
441 root->appendNew<ControlValue>(
442 proc, Return, Origin(),
443 root->appendNew<Value>(proc, Add, Origin(), value, value));
445 CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
448 void testAddArgsDouble(double a, double b)
451 BasicBlock* root = proc.addBlock();
452 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
453 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
454 root->appendNew<ControlValue>(
455 proc, Return, Origin(),
456 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
458 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
461 void testAddArgImmDouble(double a, double b)
464 BasicBlock* root = proc.addBlock();
465 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
466 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
467 root->appendNew<ControlValue>(
468 proc, Return, Origin(),
469 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
471 CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
474 void testAddImmArgDouble(double a, double b)
477 BasicBlock* root = proc.addBlock();
478 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
479 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
480 root->appendNew<ControlValue>(
481 proc, Return, Origin(),
482 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
484 CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
487 void testAddImmsDouble(double a, double b)
490 BasicBlock* root = proc.addBlock();
491 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
492 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
493 root->appendNew<ControlValue>(
494 proc, Return, Origin(),
495 root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
497 CHECK(isIdentical(compileAndRun<double>(proc), a + b));
500 void testAddArgFloat(float a)
503 BasicBlock* root = proc.addBlock();
504 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
505 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
506 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
507 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
508 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
509 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
512 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
515 void testAddArgsFloat(float a, float b)
518 BasicBlock* root = proc.addBlock();
519 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
520 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
521 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
522 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
523 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
524 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
525 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
526 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
527 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
529 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
532 void testAddArgImmFloat(float a, float b)
535 BasicBlock* root = proc.addBlock();
536 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
537 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
538 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
539 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
540 Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
541 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
542 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
544 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
547 void testAddImmArgFloat(float a, float b)
550 BasicBlock* root = proc.addBlock();
551 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
552 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
553 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
554 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
555 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
556 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
557 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
559 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
562 void testAddImmsFloat(float a, float b)
565 BasicBlock* root = proc.addBlock();
566 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
567 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
568 Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
569 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
570 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
572 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
575 void testAddArgFloatWithUselessDoubleConversion(float a)
578 BasicBlock* root = proc.addBlock();
579 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
580 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
581 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
582 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
583 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
584 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
585 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
586 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
588 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
591 void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
594 BasicBlock* root = proc.addBlock();
595 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
596 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
597 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
598 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
599 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
600 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
601 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
602 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
603 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
604 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
605 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
606 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
608 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
611 void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
614 BasicBlock* root = proc.addBlock();
615 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
616 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
617 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
618 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
619 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
620 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
621 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
622 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
623 Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
624 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
625 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
626 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
627 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
628 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
631 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
632 CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
635 void testMulArg(int a)
638 BasicBlock* root = proc.addBlock();
639 Value* value = root->appendNew<Value>(
640 proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
641 root->appendNew<ControlValue>(
642 proc, Return, Origin(),
643 root->appendNew<Value>(proc, Mul, Origin(), value, value));
645 CHECK(compileAndRun<int>(proc, a) == a * a);
648 void testMulArgStore(int a)
651 BasicBlock* root = proc.addBlock();
656 Value* value = root->appendNew<Value>(
657 proc, Trunc, Origin(),
658 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
659 Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
661 root->appendNew<MemoryValue>(
662 proc, Store, Origin(), value,
663 root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot));
664 root->appendNew<MemoryValue>(
665 proc, Store, Origin(), mul,
666 root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot));
668 root->appendNew<ControlValue>(
669 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
671 CHECK(!compileAndRun<int>(proc, a));
672 CHECK(mulSlot == a * a);
673 CHECK(valueSlot == a);
676 void testMulAddArg(int a)
679 BasicBlock* root = proc.addBlock();
680 Value* value = root->appendNew<Value>(
681 proc, Trunc, Origin(),
682 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
683 root->appendNew<ControlValue>(
684 proc, Return, Origin(),
685 root->appendNew<Value>(
687 root->appendNew<Value>(proc, Mul, Origin(), value, value),
690 CHECK(compileAndRun<int>(proc, a) == a * a + a);
693 void testMulArgs(int a, int b)
696 BasicBlock* root = proc.addBlock();
697 root->appendNew<ControlValue>(
698 proc, Return, Origin(),
699 root->appendNew<Value>(
701 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
702 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
704 CHECK(compileAndRun<int>(proc, a, b) == a * b);
707 void testMulArgImm(int64_t a, int64_t b)
710 BasicBlock* root = proc.addBlock();
711 root->appendNew<ControlValue>(
712 proc, Return, Origin(),
713 root->appendNew<Value>(
715 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
716 root->appendNew<Const64Value>(proc, Origin(), b)));
718 CHECK(compileAndRun<int64_t>(proc, a) == a * b);
721 void testMulImmArg(int a, int b)
724 BasicBlock* root = proc.addBlock();
725 root->appendNew<ControlValue>(
726 proc, Return, Origin(),
727 root->appendNew<Value>(
729 root->appendNew<Const64Value>(proc, Origin(), a),
730 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
732 CHECK(compileAndRun<int>(proc, b) == a * b);
735 void testMulArgs32(int a, int b)
738 BasicBlock* root = proc.addBlock();
739 root->appendNew<ControlValue>(
740 proc, Return, Origin(),
741 root->appendNew<Value>(
743 root->appendNew<Value>(
744 proc, Trunc, Origin(),
745 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
746 root->appendNew<Value>(
747 proc, Trunc, Origin(),
748 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
750 CHECK(compileAndRun<int>(proc, a, b) == a * b);
753 void testMulLoadTwice()
755 auto test = [&] (unsigned optLevel) {
757 BasicBlock* root = proc.addBlock();
759 Value* load = root->appendNew<MemoryValue>(
760 proc, Load, Int32, Origin(),
761 root->appendNew<ConstPtrValue>(proc, Origin(), &value));
762 root->appendNew<ControlValue>(
763 proc, Return, Origin(),
764 root->appendNew<Value>(proc, Mul, Origin(), load, load));
766 auto code = compile(proc, optLevel);
767 CHECK(invoke<int32_t>(*code) == 42 * 42);
774 void testMulArgDouble(double a)
777 BasicBlock* root = proc.addBlock();
778 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
779 root->appendNew<ControlValue>(
780 proc, Return, Origin(),
781 root->appendNew<Value>(proc, Mul, Origin(), value, value));
783 CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
786 void testMulArgsDouble(double a, double b)
789 BasicBlock* root = proc.addBlock();
790 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
791 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
792 root->appendNew<ControlValue>(
793 proc, Return, Origin(),
794 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
796 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
799 void testMulArgImmDouble(double a, double b)
802 BasicBlock* root = proc.addBlock();
803 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
804 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
805 root->appendNew<ControlValue>(
806 proc, Return, Origin(),
807 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
809 CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
812 void testMulImmArgDouble(double a, double b)
815 BasicBlock* root = proc.addBlock();
816 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
817 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
818 root->appendNew<ControlValue>(
819 proc, Return, Origin(),
820 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
822 CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
825 void testMulImmsDouble(double a, double b)
828 BasicBlock* root = proc.addBlock();
829 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
830 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
831 root->appendNew<ControlValue>(
832 proc, Return, Origin(),
833 root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
835 CHECK(isIdentical(compileAndRun<double>(proc), a * b));
838 void testMulArgFloat(float a)
841 BasicBlock* root = proc.addBlock();
842 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
843 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
844 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
845 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
846 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
847 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
850 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
853 void testMulArgsFloat(float a, float b)
856 BasicBlock* root = proc.addBlock();
857 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
858 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
859 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
860 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
861 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
862 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
863 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
864 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
865 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
867 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
870 void testMulArgImmFloat(float a, float b)
873 BasicBlock* root = proc.addBlock();
874 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
875 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
876 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
877 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
878 Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
879 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
880 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
882 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
885 void testMulImmArgFloat(float a, float b)
888 BasicBlock* root = proc.addBlock();
889 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
890 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
891 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
892 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
893 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
894 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
895 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
897 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
900 void testMulImmsFloat(float a, float b)
903 BasicBlock* root = proc.addBlock();
904 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
905 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
906 Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
907 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
908 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
910 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
913 void testMulArgFloatWithUselessDoubleConversion(float a)
916 BasicBlock* root = proc.addBlock();
917 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
918 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
919 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
920 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
921 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
922 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
923 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
924 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
926 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
929 void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
932 BasicBlock* root = proc.addBlock();
933 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
934 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
935 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
936 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
937 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
938 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
939 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
940 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
941 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
942 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
943 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
944 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
946 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
949 void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
952 BasicBlock* root = proc.addBlock();
953 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
954 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
955 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
956 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
957 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
958 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
959 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
960 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
961 Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
962 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
963 Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
964 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
965 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
966 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
969 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
970 CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
973 void testDivArgDouble(double a)
976 BasicBlock* root = proc.addBlock();
977 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
978 root->appendNew<ControlValue>(
979 proc, Return, Origin(),
980 root->appendNew<Value>(proc, Div, Origin(), value, value));
982 CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
985 void testDivArgsDouble(double a, double b)
988 BasicBlock* root = proc.addBlock();
989 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
990 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
991 root->appendNew<ControlValue>(
992 proc, Return, Origin(),
993 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
995 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
998 void testDivArgImmDouble(double a, double b)
1001 BasicBlock* root = proc.addBlock();
1002 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1003 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1004 root->appendNew<ControlValue>(
1005 proc, Return, Origin(),
1006 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1008 CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
1011 void testDivImmArgDouble(double a, double b)
1014 BasicBlock* root = proc.addBlock();
1015 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1016 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1017 root->appendNew<ControlValue>(
1018 proc, Return, Origin(),
1019 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1021 CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
1024 void testDivImmsDouble(double a, double b)
1027 BasicBlock* root = proc.addBlock();
1028 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1029 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1030 root->appendNew<ControlValue>(
1031 proc, Return, Origin(),
1032 root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
1034 CHECK(isIdentical(compileAndRun<double>(proc), a / b));
1037 void testDivArgFloat(float a)
1040 BasicBlock* root = proc.addBlock();
1041 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1042 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1043 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1044 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
1045 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1046 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1049 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1052 void testDivArgsFloat(float a, float b)
1055 BasicBlock* root = proc.addBlock();
1056 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1057 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1058 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1059 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1060 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1061 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1062 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
1063 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1064 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1066 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1069 void testDivArgImmFloat(float a, float b)
1072 BasicBlock* root = proc.addBlock();
1073 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1074 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1075 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1076 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1077 Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
1078 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1079 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1081 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
1084 void testDivImmArgFloat(float a, float b)
1087 BasicBlock* root = proc.addBlock();
1088 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1089 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1090 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1091 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1092 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
1093 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1094 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1096 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1099 void testDivImmsFloat(float a, float b)
1102 BasicBlock* root = proc.addBlock();
1103 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1104 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1105 Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
1106 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1107 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1109 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
1112 void testModArgDouble(double a)
1115 BasicBlock* root = proc.addBlock();
1116 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1117 root->appendNew<ControlValue>(
1118 proc, Return, Origin(),
1119 root->appendNew<Value>(proc, Mod, Origin(), value, value));
1121 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
1124 void testModArgsDouble(double a, double b)
1127 BasicBlock* root = proc.addBlock();
1128 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1129 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1130 root->appendNew<ControlValue>(
1131 proc, Return, Origin(),
1132 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1134 CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
1137 void testModArgImmDouble(double a, double b)
1140 BasicBlock* root = proc.addBlock();
1141 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1142 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1143 root->appendNew<ControlValue>(
1144 proc, Return, Origin(),
1145 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1147 CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
1150 void testModImmArgDouble(double a, double b)
1153 BasicBlock* root = proc.addBlock();
1154 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1155 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1156 root->appendNew<ControlValue>(
1157 proc, Return, Origin(),
1158 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1160 CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
1163 void testModImmsDouble(double a, double b)
1166 BasicBlock* root = proc.addBlock();
1167 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1168 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1169 root->appendNew<ControlValue>(
1170 proc, Return, Origin(),
1171 root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
1173 CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
1176 void testModArgFloat(float a)
1179 BasicBlock* root = proc.addBlock();
1180 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1181 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1182 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1183 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
1184 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1185 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1188 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
1191 void testModArgsFloat(float a, float b)
1194 BasicBlock* root = proc.addBlock();
1195 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1196 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1197 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1198 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1199 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1200 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1201 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
1202 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1203 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1205 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1208 void testModArgImmFloat(float a, float b)
1211 BasicBlock* root = proc.addBlock();
1212 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1213 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1214 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1215 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1216 Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
1217 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1218 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1220 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1223 void testModImmArgFloat(float a, float b)
1226 BasicBlock* root = proc.addBlock();
1227 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1228 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1229 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1230 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1231 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
1232 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1233 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1235 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1238 void testModImmsFloat(float a, float b)
1241 BasicBlock* root = proc.addBlock();
1242 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1243 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1244 Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
1245 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1246 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1248 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
1251 void testDivArgFloatWithUselessDoubleConversion(float a)
1254 BasicBlock* root = proc.addBlock();
1255 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1256 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1257 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1258 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1259 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
1260 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1261 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1262 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1264 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
1267 void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
1270 BasicBlock* root = proc.addBlock();
1271 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1272 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1273 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1274 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1275 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1276 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1277 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1278 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1279 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1280 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1281 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1282 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1284 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
1287 void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
1290 BasicBlock* root = proc.addBlock();
1291 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1292 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1293 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1294 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1295 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1296 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1297 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1298 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1299 Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
1300 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1301 Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1302 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
1303 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1304 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1307 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
1308 CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
1311 void testSubArg(int a)
1314 BasicBlock* root = proc.addBlock();
1315 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1316 root->appendNew<ControlValue>(
1317 proc, Return, Origin(),
1318 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1320 CHECK(!compileAndRun<int>(proc, a));
1323 void testSubArgs(int a, int b)
1326 BasicBlock* root = proc.addBlock();
1327 root->appendNew<ControlValue>(
1328 proc, Return, Origin(),
1329 root->appendNew<Value>(
1330 proc, Sub, Origin(),
1331 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1332 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1334 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1337 void testSubArgImm(int64_t a, int64_t b)
1340 BasicBlock* root = proc.addBlock();
1341 root->appendNew<ControlValue>(
1342 proc, Return, Origin(),
1343 root->appendNew<Value>(
1344 proc, Sub, Origin(),
1345 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1346 root->appendNew<Const64Value>(proc, Origin(), b)));
1348 CHECK(compileAndRun<int64_t>(proc, a) == a - b);
1351 void testNegValueSubOne(int a)
1354 BasicBlock* root = proc.addBlock();
1355 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1356 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1357 root->appendNew<Const64Value>(proc, Origin(), 0),
1359 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1361 root->appendNew<Const64Value>(proc, Origin(), 1));
1362 root->appendNew<ControlValue>(proc, Return, Origin(), negArgumentMinusOne);
1363 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1366 void testSubImmArg(int a, int b)
1369 BasicBlock* root = proc.addBlock();
1370 root->appendNew<ControlValue>(
1371 proc, Return, Origin(),
1372 root->appendNew<Value>(
1373 proc, Sub, Origin(),
1374 root->appendNew<Const64Value>(proc, Origin(), a),
1375 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1377 CHECK(compileAndRun<int>(proc, b) == a - b);
1380 void testSubArgMem(int64_t a, int64_t b)
1383 BasicBlock* root = proc.addBlock();
1384 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1385 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1386 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1387 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1389 root->appendNew<ControlValue>(proc, Return, Origin(), result);
1391 CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
1394 void testSubMemArg(int64_t a, int64_t b)
1397 BasicBlock* root = proc.addBlock();
1398 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1399 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1400 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1402 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1403 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1404 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1406 int64_t inputOutput = a;
1407 CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
1408 CHECK(inputOutput == a - b);
1411 void testSubImmMem(int64_t a, int64_t b)
1414 BasicBlock* root = proc.addBlock();
1415 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1416 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1417 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1418 root->appendNew<Const64Value>(proc, Origin(), a),
1420 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1421 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1423 int64_t inputOutput = b;
1424 CHECK(!compileAndRun<int>(proc, &inputOutput));
1425 CHECK(inputOutput == a - b);
1428 void testSubMemImm(int64_t a, int64_t b)
1431 BasicBlock* root = proc.addBlock();
1432 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1433 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
1434 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1436 root->appendNew<Const64Value>(proc, Origin(), b));
1437 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1438 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1440 int64_t inputOutput = a;
1441 CHECK(!compileAndRun<int>(proc, &inputOutput));
1442 CHECK(inputOutput == a - b);
1446 void testSubArgs32(int a, int b)
1449 BasicBlock* root = proc.addBlock();
1450 root->appendNew<ControlValue>(
1451 proc, Return, Origin(),
1452 root->appendNew<Value>(
1453 proc, Sub, Origin(),
1454 root->appendNew<Value>(
1455 proc, Trunc, Origin(),
1456 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1457 root->appendNew<Value>(
1458 proc, Trunc, Origin(),
1459 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1461 CHECK(compileAndRun<int>(proc, a, b) == a - b);
1464 void testSubArgImm32(int a, int b)
1467 BasicBlock* root = proc.addBlock();
1468 root->appendNew<ControlValue>(
1469 proc, Return, Origin(),
1470 root->appendNew<Value>(
1471 proc, Sub, Origin(),
1472 root->appendNew<Value>(
1473 proc, Trunc, Origin(),
1474 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1475 root->appendNew<Const32Value>(proc, Origin(), b)));
1477 CHECK(compileAndRun<int>(proc, a) == a - b);
1480 void testSubImmArg32(int a, int b)
1483 BasicBlock* root = proc.addBlock();
1484 root->appendNew<ControlValue>(
1485 proc, Return, Origin(),
1486 root->appendNew<Value>(
1487 proc, Sub, Origin(),
1488 root->appendNew<Const32Value>(proc, Origin(), a),
1489 root->appendNew<Value>(
1490 proc, Trunc, Origin(),
1491 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1493 CHECK(compileAndRun<int>(proc, b) == a - b);
1496 void testSubMemArg32(int32_t a, int32_t b)
1499 BasicBlock* root = proc.addBlock();
1500 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1501 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1502 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1503 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1504 Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
1505 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1506 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1508 int32_t inputOutput = a;
1509 CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
1510 CHECK(inputOutput == a - b);
1513 void testSubArgMem32(int32_t a, int32_t b)
1516 BasicBlock* root = proc.addBlock();
1517 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
1518 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1519 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1520 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1521 Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
1522 root->appendNew<ControlValue>(proc, Return, Origin(), result);
1524 CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
1527 void testSubImmMem32(int32_t a, int32_t b)
1530 BasicBlock* root = proc.addBlock();
1531 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1532 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1533 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1534 root->appendNew<Const32Value>(proc, Origin(), a),
1536 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1537 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1539 int32_t inputOutput = b;
1540 CHECK(!compileAndRun<int>(proc, &inputOutput));
1541 CHECK(inputOutput == a - b);
1544 void testSubMemImm32(int32_t a, int32_t b)
1547 BasicBlock* root = proc.addBlock();
1548 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1549 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
1550 Value* result = root->appendNew<Value>(proc, Sub, Origin(),
1552 root->appendNew<Const32Value>(proc, Origin(), b));
1553 root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
1554 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
1556 int32_t inputOutput = a;
1557 CHECK(!compileAndRun<int>(proc, &inputOutput));
1558 CHECK(inputOutput == a - b);
1561 void testNegValueSubOne32(int a)
1564 BasicBlock* root = proc.addBlock();
1565 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1566 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1567 Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
1568 root->appendNew<Const32Value>(proc, Origin(), 0),
1570 Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
1572 root->appendNew<Const32Value>(proc, Origin(), 1));
1573 root->appendNew<ControlValue>(proc, Return, Origin(), negArgumentMinusOne);
1574 CHECK(compileAndRun<int>(proc, a) == -a - 1);
1577 void testSubArgDouble(double a)
1580 BasicBlock* root = proc.addBlock();
1581 Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1582 root->appendNew<ControlValue>(
1583 proc, Return, Origin(),
1584 root->appendNew<Value>(proc, Sub, Origin(), value, value));
1586 CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
1589 void testSubArgsDouble(double a, double b)
1592 BasicBlock* root = proc.addBlock();
1593 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1594 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
1595 root->appendNew<ControlValue>(
1596 proc, Return, Origin(),
1597 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
1599 CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
1602 void testSubArgImmDouble(double a, double b)
1605 BasicBlock* root = proc.addBlock();
1606 Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1607 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1608 root->appendNew<ControlValue>(
1609 proc, Return, Origin(),
1610 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
1612 CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
1615 void testSubImmArgDouble(double a, double b)
1618 BasicBlock* root = proc.addBlock();
1619 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1620 Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
1621 root->appendNew<ControlValue>(
1622 proc, Return, Origin(),
1623 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
1625 CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
1628 void testSubImmsDouble(double a, double b)
1631 BasicBlock* root = proc.addBlock();
1632 Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
1633 Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
1634 root->appendNew<ControlValue>(
1635 proc, Return, Origin(),
1636 root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
1638 CHECK(isIdentical(compileAndRun<double>(proc), a - b));
1641 void testSubArgFloat(float a)
1644 BasicBlock* root = proc.addBlock();
1645 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1646 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1647 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1648 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
1649 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1650 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1653 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
1656 void testSubArgsFloat(float a, float b)
1659 BasicBlock* root = proc.addBlock();
1660 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1661 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1662 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1663 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1664 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1665 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1666 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
1667 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1668 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1670 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
1673 void testSubArgImmFloat(float a, float b)
1676 BasicBlock* root = proc.addBlock();
1677 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1678 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1679 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1680 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1681 Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
1682 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1683 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1685 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
1688 void testSubImmArgFloat(float a, float b)
1691 BasicBlock* root = proc.addBlock();
1692 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
1693 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1694 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
1695 Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1696 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
1697 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1698 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1700 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
1703 void testSubImmsFloat(float a, float b)
1706 BasicBlock* root = proc.addBlock();
1707 Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
1708 Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
1709 Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
1710 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
1711 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1713 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
1716 void testSubArgFloatWithUselessDoubleConversion(float a)
1719 BasicBlock* root = proc.addBlock();
1720 Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
1721 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1722 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
1723 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
1724 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
1725 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1726 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1727 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1729 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
1732 void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
1735 BasicBlock* root = proc.addBlock();
1736 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1737 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1738 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1739 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1740 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1741 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1742 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1743 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1744 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
1745 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1746 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1747 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1749 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
1752 void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
1755 BasicBlock* root = proc.addBlock();
1756 Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1757 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1758 Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
1759 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
1760 Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
1761 Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
1762 Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
1763 Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
1764 Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
1765 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
1766 Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
1767 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
1768 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
1769 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
1772 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
1773 CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
1776 void testBitAndArgs(int64_t a, int64_t b)
1779 BasicBlock* root = proc.addBlock();
1780 root->appendNew<ControlValue>(
1781 proc, Return, Origin(),
1782 root->appendNew<Value>(
1783 proc, BitAnd, Origin(),
1784 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1785 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
1787 CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
1790 void testBitAndSameArg(int64_t a)
1793 BasicBlock* root = proc.addBlock();
1794 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
1795 root->appendNew<ControlValue>(
1796 proc, Return, Origin(),
1797 root->appendNew<Value>(
1798 proc, BitAnd, Origin(),
1802 CHECK(compileAndRun<int64_t>(proc, a) == a);
1805 void testBitAndImms(int64_t a, int64_t b)
1808 BasicBlock* root = proc.addBlock();
1809 root->appendNew<ControlValue>(
1810 proc, Return, Origin(),
1811 root->appendNew<Value>(
1812 proc, BitAnd, Origin(),
1813 root->appendNew<Const64Value>(proc, Origin(), a),
1814 root->appendNew<Const64Value>(proc, Origin(), b)));
1816 CHECK(compileAndRun<int64_t>(proc) == (a & b));
1819 void testBitAndArgImm(int64_t a, int64_t b)
1822 BasicBlock* root = proc.addBlock();
1823 root->appendNew<ControlValue>(
1824 proc, Return, Origin(),
1825 root->appendNew<Value>(
1826 proc, BitAnd, Origin(),
1827 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1828 root->appendNew<Const64Value>(proc, Origin(), b)));
1830 CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
1833 void testBitAndImmArg(int64_t a, int64_t b)
1836 BasicBlock* root = proc.addBlock();
1837 root->appendNew<ControlValue>(
1838 proc, Return, Origin(),
1839 root->appendNew<Value>(
1840 proc, BitAnd, Origin(),
1841 root->appendNew<Const64Value>(proc, Origin(), a),
1842 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
1844 CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
1847 void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
1850 BasicBlock* root = proc.addBlock();
1851 Value* innerBitAnd = root->appendNew<Value>(
1852 proc, BitAnd, Origin(),
1853 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1854 root->appendNew<Const64Value>(proc, Origin(), b));
1855 root->appendNew<ControlValue>(
1856 proc, Return, Origin(),
1857 root->appendNew<Value>(
1858 proc, BitAnd, Origin(),
1860 root->appendNew<Const64Value>(proc, Origin(), c)));
1862 CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
1865 void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
1868 BasicBlock* root = proc.addBlock();
1869 Value* innerBitAnd = root->appendNew<Value>(
1870 proc, BitAnd, Origin(),
1871 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
1872 root->appendNew<Const64Value>(proc, Origin(), c));
1873 root->appendNew<ControlValue>(
1874 proc, Return, Origin(),
1875 root->appendNew<Value>(
1876 proc, BitAnd, Origin(),
1877 root->appendNew<Const64Value>(proc, Origin(), a),
1880 CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
1883 void testBitAndArgs32(int a, int b)
1886 BasicBlock* root = proc.addBlock();
1887 root->appendNew<ControlValue>(
1888 proc, Return, Origin(),
1889 root->appendNew<Value>(
1890 proc, BitAnd, Origin(),
1891 root->appendNew<Value>(
1892 proc, Trunc, Origin(),
1893 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1894 root->appendNew<Value>(
1895 proc, Trunc, Origin(),
1896 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
1898 CHECK(compileAndRun<int>(proc, a, b) == (a & b));
1901 void testBitAndSameArg32(int a)
1904 BasicBlock* root = proc.addBlock();
1905 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
1906 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
1907 root->appendNew<ControlValue>(
1908 proc, Return, Origin(),
1909 root->appendNew<Value>(
1910 proc, BitAnd, Origin(),
1914 CHECK(compileAndRun<int>(proc, a) == a);
1917 void testBitAndImms32(int a, int b)
1920 BasicBlock* root = proc.addBlock();
1921 root->appendNew<ControlValue>(
1922 proc, Return, Origin(),
1923 root->appendNew<Value>(
1924 proc, BitAnd, Origin(),
1925 root->appendNew<Const32Value>(proc, Origin(), a),
1926 root->appendNew<Const32Value>(proc, Origin(), b)));
1928 CHECK(compileAndRun<int>(proc) == (a & b));
1931 void testBitAndArgImm32(int a, int b)
1934 BasicBlock* root = proc.addBlock();
1935 root->appendNew<ControlValue>(
1936 proc, Return, Origin(),
1937 root->appendNew<Value>(
1938 proc, BitAnd, Origin(),
1939 root->appendNew<Value>(
1940 proc, Trunc, Origin(),
1941 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1942 root->appendNew<Const32Value>(proc, Origin(), b)));
1944 CHECK(compileAndRun<int>(proc, a) == (a & b));
1947 void testBitAndImmArg32(int a, int b)
1950 BasicBlock* root = proc.addBlock();
1951 root->appendNew<ControlValue>(
1952 proc, Return, Origin(),
1953 root->appendNew<Value>(
1954 proc, BitAnd, Origin(),
1955 root->appendNew<Const32Value>(proc, Origin(), a),
1956 root->appendNew<Value>(
1957 proc, Trunc, Origin(),
1958 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
1960 CHECK(compileAndRun<int>(proc, b) == (a & b));
1963 void testBitAndBitAndArgImmImm32(int a, int b, int c)
1966 BasicBlock* root = proc.addBlock();
1967 Value* innerBitAnd = root->appendNew<Value>(
1968 proc, BitAnd, Origin(),
1969 root->appendNew<Value>(
1970 proc, Trunc, Origin(),
1971 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1972 root->appendNew<Const32Value>(proc, Origin(), b));
1973 root->appendNew<ControlValue>(
1974 proc, Return, Origin(),
1975 root->appendNew<Value>(
1976 proc, BitAnd, Origin(),
1978 root->appendNew<Const32Value>(proc, Origin(), c)));
1980 CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
1983 void testBitAndImmBitAndArgImm32(int a, int b, int c)
1986 BasicBlock* root = proc.addBlock();
1987 Value* innerBitAnd = root->appendNew<Value>(
1988 proc, BitAnd, Origin(),
1989 root->appendNew<Value>(
1990 proc, Trunc, Origin(),
1991 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
1992 root->appendNew<Const32Value>(proc, Origin(), c));
1993 root->appendNew<ControlValue>(
1994 proc, Return, Origin(),
1995 root->appendNew<Value>(
1996 proc, BitAnd, Origin(),
1997 root->appendNew<Const32Value>(proc, Origin(), a),
2000 CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
2003 void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
2006 BasicBlock* root = proc.addBlock();
2007 Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2008 Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
2009 Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
2010 Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
2011 root->appendNew<Const32Value>(proc, Origin(), 0x5),
2013 Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
2014 root->appendNew<Const32Value>(proc, Origin(), 0x1),
2016 Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
2017 root->appendNew<Const64Value>(proc, Origin(), 42),
2018 root->appendNew<Const64Value>(proc, Origin(), -5));
2020 root->appendNew<ControlValue>(proc, Return, Origin(), select);
2022 int64_t expected = (a == b) ? -5 : 42;
2023 CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
2026 double bitAndDouble(double a, double b)
2028 return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
2031 void testBitAndArgDouble(double a)
2034 BasicBlock* root = proc.addBlock();
2035 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2036 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2037 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2039 CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
2042 void testBitAndArgsDouble(double a, double b)
2045 BasicBlock* root = proc.addBlock();
2046 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2047 Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
2048 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2049 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2051 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2054 void testBitAndArgImmDouble(double a, double b)
2057 BasicBlock* root = proc.addBlock();
2058 Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
2059 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2060 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2061 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2063 CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
2066 void testBitAndImmsDouble(double a, double b)
2069 BasicBlock* root = proc.addBlock();
2070 Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
2071 Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
2072 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2073 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2075 CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
2078 float bitAndFloat(float a, float b)
2080 return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
2083 void testBitAndArgFloat(float a)
2086 BasicBlock* root = proc.addBlock();
2087 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2088 root->appendNew<Value>(proc, Trunc, Origin(),
2089 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2090 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
2091 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2093 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
2096 void testBitAndArgsFloat(float a, float b)
2099 BasicBlock* root = proc.addBlock();
2100 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2101 root->appendNew<Value>(proc, Trunc, Origin(),
2102 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2103 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2104 root->appendNew<Value>(proc, Trunc, Origin(),
2105 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2106 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2107 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2109 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2112 void testBitAndArgImmFloat(float a, float b)
2115 BasicBlock* root = proc.addBlock();
2116 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2117 root->appendNew<Value>(proc, Trunc, Origin(),
2118 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2119 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2120 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2121 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2123 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
2126 void testBitAndImmsFloat(float a, float b)
2129 BasicBlock* root = proc.addBlock();
2130 Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
2131 Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
2132 Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
2133 root->appendNew<ControlValue>(proc, Return, Origin(), result);
2135 CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
2138 void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
2141 BasicBlock* root = proc.addBlock();
2142 Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2143 root->appendNew<Value>(proc, Trunc, Origin(),
2144 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2145 Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
2146 root->appendNew<Value>(proc, Trunc, Origin(),
2147 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2148 Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
2149 Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
2150 Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
2151 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
2152 root->appendNew<ControlValue>(proc, Return, Origin(), floatResult);
2156 float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
2157 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
2160 void testBitOrArgs(int64_t a, int64_t b)
2163 BasicBlock* root = proc.addBlock();
2164 root->appendNew<ControlValue>(
2165 proc, Return, Origin(),
2166 root->appendNew<Value>(
2167 proc, BitOr, Origin(),
2168 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2169 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2171 CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
2174 void testBitOrSameArg(int64_t a)
2177 BasicBlock* root = proc.addBlock();
2178 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2179 root->appendNew<ControlValue>(
2180 proc, Return, Origin(),
2181 root->appendNew<Value>(
2182 proc, BitOr, Origin(),
2186 CHECK(compileAndRun<int64_t>(proc, a) == a);
2189 void testBitOrImms(int64_t a, int64_t b)
2192 BasicBlock* root = proc.addBlock();
2193 root->appendNew<ControlValue>(
2194 proc, Return, Origin(),
2195 root->appendNew<Value>(
2196 proc, BitOr, Origin(),
2197 root->appendNew<Const64Value>(proc, Origin(), a),
2198 root->appendNew<Const64Value>(proc, Origin(), b)));
2200 CHECK(compileAndRun<int64_t>(proc) == (a | b));
2203 void testBitOrArgImm(int64_t a, int64_t b)
2206 BasicBlock* root = proc.addBlock();
2207 root->appendNew<ControlValue>(
2208 proc, Return, Origin(),
2209 root->appendNew<Value>(
2210 proc, BitOr, Origin(),
2211 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2212 root->appendNew<Const64Value>(proc, Origin(), b)));
2214 CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
2217 void testBitOrImmArg(int64_t a, int64_t b)
2220 BasicBlock* root = proc.addBlock();
2221 root->appendNew<ControlValue>(
2222 proc, Return, Origin(),
2223 root->appendNew<Value>(
2224 proc, BitOr, Origin(),
2225 root->appendNew<Const64Value>(proc, Origin(), a),
2226 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2228 CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
2231 void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
2234 BasicBlock* root = proc.addBlock();
2235 Value* innerBitOr = root->appendNew<Value>(
2236 proc, BitOr, Origin(),
2237 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2238 root->appendNew<Const64Value>(proc, Origin(), b));
2239 root->appendNew<ControlValue>(
2240 proc, Return, Origin(),
2241 root->appendNew<Value>(
2242 proc, BitOr, Origin(),
2244 root->appendNew<Const64Value>(proc, Origin(), c)));
2246 CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
2249 void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
2252 BasicBlock* root = proc.addBlock();
2253 Value* innerBitOr = root->appendNew<Value>(
2254 proc, BitOr, Origin(),
2255 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2256 root->appendNew<Const64Value>(proc, Origin(), c));
2257 root->appendNew<ControlValue>(
2258 proc, Return, Origin(),
2259 root->appendNew<Value>(
2260 proc, BitOr, Origin(),
2261 root->appendNew<Const64Value>(proc, Origin(), a),
2264 CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
2267 void testBitOrArgs32(int a, int b)
2270 BasicBlock* root = proc.addBlock();
2271 root->appendNew<ControlValue>(
2272 proc, Return, Origin(),
2273 root->appendNew<Value>(
2274 proc, BitOr, Origin(),
2275 root->appendNew<Value>(
2276 proc, Trunc, Origin(),
2277 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2278 root->appendNew<Value>(
2279 proc, Trunc, Origin(),
2280 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2282 CHECK(compileAndRun<int>(proc, a, b) == (a | b));
2285 void testBitOrSameArg32(int a)
2288 BasicBlock* root = proc.addBlock();
2289 Value* argument = root->appendNew<Value>(
2290 proc, Trunc, Origin(),
2291 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2292 root->appendNew<ControlValue>(
2293 proc, Return, Origin(),
2294 root->appendNew<Value>(
2295 proc, BitOr, Origin(),
2299 CHECK(compileAndRun<int>(proc, a) == a);
2302 void testBitOrImms32(int a, int b)
2305 BasicBlock* root = proc.addBlock();
2306 root->appendNew<ControlValue>(
2307 proc, Return, Origin(),
2308 root->appendNew<Value>(
2309 proc, BitOr, Origin(),
2310 root->appendNew<Const32Value>(proc, Origin(), a),
2311 root->appendNew<Const32Value>(proc, Origin(), b)));
2313 CHECK(compileAndRun<int>(proc) == (a | b));
2316 void testBitOrArgImm32(int a, int b)
2319 BasicBlock* root = proc.addBlock();
2320 root->appendNew<ControlValue>(
2321 proc, Return, Origin(),
2322 root->appendNew<Value>(
2323 proc, BitOr, Origin(),
2324 root->appendNew<Value>(
2325 proc, Trunc, Origin(),
2326 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2327 root->appendNew<Const32Value>(proc, Origin(), b)));
2329 CHECK(compileAndRun<int>(proc, a) == (a | b));
2332 void testBitOrImmArg32(int a, int b)
2335 BasicBlock* root = proc.addBlock();
2336 root->appendNew<ControlValue>(
2337 proc, Return, Origin(),
2338 root->appendNew<Value>(
2339 proc, BitOr, Origin(),
2340 root->appendNew<Const32Value>(proc, Origin(), a),
2341 root->appendNew<Value>(
2342 proc, Trunc, Origin(),
2343 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2345 CHECK(compileAndRun<int>(proc, b) == (a | b));
2348 void testBitOrBitOrArgImmImm32(int a, int b, int c)
2351 BasicBlock* root = proc.addBlock();
2352 Value* innerBitOr = root->appendNew<Value>(
2353 proc, BitOr, Origin(),
2354 root->appendNew<Value>(
2355 proc, Trunc, Origin(),
2356 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2357 root->appendNew<Const32Value>(proc, Origin(), b));
2358 root->appendNew<ControlValue>(
2359 proc, Return, Origin(),
2360 root->appendNew<Value>(
2361 proc, BitOr, Origin(),
2363 root->appendNew<Const32Value>(proc, Origin(), c)));
2365 CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
2368 void testBitOrImmBitOrArgImm32(int a, int b, int c)
2371 BasicBlock* root = proc.addBlock();
2372 Value* innerBitOr = root->appendNew<Value>(
2373 proc, BitOr, Origin(),
2374 root->appendNew<Value>(
2375 proc, Trunc, Origin(),
2376 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2377 root->appendNew<Const32Value>(proc, Origin(), c));
2378 root->appendNew<ControlValue>(
2379 proc, Return, Origin(),
2380 root->appendNew<Value>(
2381 proc, BitOr, Origin(),
2382 root->appendNew<Const32Value>(proc, Origin(), a),
2385 CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
2388 void testBitXorArgs(int64_t a, int64_t b)
2391 BasicBlock* root = proc.addBlock();
2392 root->appendNew<ControlValue>(
2393 proc, Return, Origin(),
2394 root->appendNew<Value>(
2395 proc, BitXor, Origin(),
2396 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2397 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
2399 CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
2402 void testBitXorSameArg(int64_t a)
2405 BasicBlock* root = proc.addBlock();
2406 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2407 root->appendNew<ControlValue>(
2408 proc, Return, Origin(),
2409 root->appendNew<Value>(
2410 proc, BitXor, Origin(),
2414 CHECK(!compileAndRun<int64_t>(proc, a));
2417 void testBitXorImms(int64_t a, int64_t b)
2420 BasicBlock* root = proc.addBlock();
2421 root->appendNew<ControlValue>(
2422 proc, Return, Origin(),
2423 root->appendNew<Value>(
2424 proc, BitXor, Origin(),
2425 root->appendNew<Const64Value>(proc, Origin(), a),
2426 root->appendNew<Const64Value>(proc, Origin(), b)));
2428 CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
2431 void testBitXorArgImm(int64_t a, int64_t b)
2434 BasicBlock* root = proc.addBlock();
2435 root->appendNew<ControlValue>(
2436 proc, Return, Origin(),
2437 root->appendNew<Value>(
2438 proc, BitXor, Origin(),
2439 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2440 root->appendNew<Const64Value>(proc, Origin(), b)));
2442 CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
2445 void testBitXorImmArg(int64_t a, int64_t b)
2448 BasicBlock* root = proc.addBlock();
2449 root->appendNew<ControlValue>(
2450 proc, Return, Origin(),
2451 root->appendNew<Value>(
2452 proc, BitXor, Origin(),
2453 root->appendNew<Const64Value>(proc, Origin(), a),
2454 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2456 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
2459 void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
2462 BasicBlock* root = proc.addBlock();
2463 Value* innerBitXor = root->appendNew<Value>(
2464 proc, BitXor, Origin(),
2465 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2466 root->appendNew<Const64Value>(proc, Origin(), b));
2467 root->appendNew<ControlValue>(
2468 proc, Return, Origin(),
2469 root->appendNew<Value>(
2470 proc, BitXor, Origin(),
2472 root->appendNew<Const64Value>(proc, Origin(), c)));
2474 CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
2477 void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
2480 BasicBlock* root = proc.addBlock();
2481 Value* innerBitXor = root->appendNew<Value>(
2482 proc, BitXor, Origin(),
2483 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2484 root->appendNew<Const64Value>(proc, Origin(), c));
2485 root->appendNew<ControlValue>(
2486 proc, Return, Origin(),
2487 root->appendNew<Value>(
2488 proc, BitXor, Origin(),
2489 root->appendNew<Const64Value>(proc, Origin(), a),
2492 CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
2495 void testBitXorArgs32(int a, int b)
2498 BasicBlock* root = proc.addBlock();
2499 root->appendNew<ControlValue>(
2500 proc, Return, Origin(),
2501 root->appendNew<Value>(
2502 proc, BitXor, Origin(),
2503 root->appendNew<Value>(
2504 proc, Trunc, Origin(),
2505 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2506 root->appendNew<Value>(
2507 proc, Trunc, Origin(),
2508 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2510 CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
2513 void testBitXorSameArg32(int a)
2516 BasicBlock* root = proc.addBlock();
2517 Value* argument = root->appendNew<Value>(
2518 proc, Trunc, Origin(),
2519 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2520 root->appendNew<ControlValue>(
2521 proc, Return, Origin(),
2522 root->appendNew<Value>(
2523 proc, BitXor, Origin(),
2527 CHECK(!compileAndRun<int>(proc, a));
2530 void testBitXorImms32(int a, int b)
2533 BasicBlock* root = proc.addBlock();
2534 root->appendNew<ControlValue>(
2535 proc, Return, Origin(),
2536 root->appendNew<Value>(
2537 proc, BitXor, Origin(),
2538 root->appendNew<Const32Value>(proc, Origin(), a),
2539 root->appendNew<Const32Value>(proc, Origin(), b)));
2541 CHECK(compileAndRun<int>(proc) == (a ^ b));
2544 void testBitXorArgImm32(int a, int b)
2547 BasicBlock* root = proc.addBlock();
2548 root->appendNew<ControlValue>(
2549 proc, Return, Origin(),
2550 root->appendNew<Value>(
2551 proc, BitXor, Origin(),
2552 root->appendNew<Value>(
2553 proc, Trunc, Origin(),
2554 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2555 root->appendNew<Const32Value>(proc, Origin(), b)));
2557 CHECK(compileAndRun<int>(proc, a) == (a ^ b));
2560 void testBitXorImmArg32(int a, int b)
2563 BasicBlock* root = proc.addBlock();
2564 root->appendNew<ControlValue>(
2565 proc, Return, Origin(),
2566 root->appendNew<Value>(
2567 proc, BitXor, Origin(),
2568 root->appendNew<Const32Value>(proc, Origin(), a),
2569 root->appendNew<Value>(
2570 proc, Trunc, Origin(),
2571 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
2573 CHECK(compileAndRun<int>(proc, b) == (a ^ b));
2576 void testBitXorBitXorArgImmImm32(int a, int b, int c)
2579 BasicBlock* root = proc.addBlock();
2580 Value* innerBitXor = root->appendNew<Value>(
2581 proc, BitXor, Origin(),
2582 root->appendNew<Value>(
2583 proc, Trunc, Origin(),
2584 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2585 root->appendNew<Const32Value>(proc, Origin(), b));
2586 root->appendNew<ControlValue>(
2587 proc, Return, Origin(),
2588 root->appendNew<Value>(
2589 proc, BitXor, Origin(),
2591 root->appendNew<Const32Value>(proc, Origin(), c)));
2593 CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
2596 void testBitXorImmBitXorArgImm32(int a, int b, int c)
2599 BasicBlock* root = proc.addBlock();
2600 Value* innerBitXor = root->appendNew<Value>(
2601 proc, BitXor, Origin(),
2602 root->appendNew<Value>(
2603 proc, Trunc, Origin(),
2604 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2605 root->appendNew<Const32Value>(proc, Origin(), c));
2606 root->appendNew<ControlValue>(
2607 proc, Return, Origin(),
2608 root->appendNew<Value>(
2609 proc, BitXor, Origin(),
2610 root->appendNew<Const32Value>(proc, Origin(), a),
2613 CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
2616 void testBitNotArg(int64_t a)
2619 BasicBlock* root = proc.addBlock();
2620 root->appendNew<ControlValue>(
2621 proc, Return, Origin(),
2622 root->appendNew<Value>(
2623 proc, BitXor, Origin(),
2624 root->appendNew<Const64Value>(proc, Origin(), -1),
2625 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
2627 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
2630 void testBitNotImm(int64_t a)
2633 BasicBlock* root = proc.addBlock();
2634 root->appendNew<ControlValue>(
2635 proc, Return, Origin(),
2636 root->appendNew<Value>(
2637 proc, BitXor, Origin(),
2638 root->appendNew<Const64Value>(proc, Origin(), -1),
2639 root->appendNew<Const64Value>(proc, Origin(), a)));
2641 CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
2644 void testBitNotMem(int64_t a)
2647 BasicBlock* root = proc.addBlock();
2648 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2649 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
2650 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
2651 root->appendNew<Const64Value>(proc, Origin(), -1),
2653 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
2654 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2657 compileAndRun<int32_t>(proc, &input);
2658 CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
2661 void testBitNotArg32(int32_t a)
2664 BasicBlock* root = proc.addBlock();
2665 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
2666 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2667 root->appendNew<ControlValue>(
2668 proc, Return, Origin(),
2669 root->appendNew<Value>(proc, BitXor, Origin(),
2670 root->appendNew<Const32Value>(proc, Origin(), -1),
2672 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
2675 void testBitNotImm32(int32_t a)
2678 BasicBlock* root = proc.addBlock();
2679 root->appendNew<ControlValue>(
2680 proc, Return, Origin(),
2681 root->appendNew<Value>(
2682 proc, BitXor, Origin(),
2683 root->appendNew<Const32Value>(proc, Origin(), -1),
2684 root->appendNew<Const32Value>(proc, Origin(), a)));
2686 CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
2689 void testBitNotMem32(int32_t a)
2692 BasicBlock* root = proc.addBlock();
2693 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
2694 MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
2695 Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
2696 root->appendNew<Const32Value>(proc, Origin(), -1),
2698 root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
2699 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
2702 compileAndRun<int32_t>(proc, &input);
2703 CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
2706 void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
2709 BasicBlock* root = proc.addBlock();
2710 BasicBlock* thenCase = proc.addBlock();
2711 BasicBlock* elseCase = proc.addBlock();
2713 Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
2714 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2715 Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
2716 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
2717 Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
2718 Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
2719 root->appendNew<Const32Value>(proc, Origin(), -1),
2722 root->appendNew<ControlValue>(
2723 proc, Branch, Origin(),
2725 FrequentedBlock(thenCase), FrequentedBlock(elseCase));
2727 thenCase->appendNew<ControlValue>(
2728 proc, Return, Origin(),
2729 thenCase->appendNew<Const32Value>(proc, Origin(), 42));
2731 elseCase->appendNew<ControlValue>(
2732 proc, Return, Origin(),
2733 elseCase->appendNew<Const32Value>(proc, Origin(), -42));
2735 int32_t expectedValue = (a != b) ? 42 : -42;
2736 CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
2739 void testShlArgs(int64_t a, int64_t b)
2742 BasicBlock* root = proc.addBlock();
2743 root->appendNew<ControlValue>(
2744 proc, Return, Origin(),
2745 root->appendNew<Value>(
2746 proc, Shl, Origin(),
2747 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2748 root->appendNew<Value>(
2749 proc, Trunc, Origin(),
2750 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2752 CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
2755 void testShlImms(int64_t a, int64_t b)
2758 BasicBlock* root = proc.addBlock();
2759 root->appendNew<ControlValue>(
2760 proc, Return, Origin(),
2761 root->appendNew<Value>(
2762 proc, Shl, Origin(),
2763 root->appendNew<Const64Value>(proc, Origin(), a),
2764 root->appendNew<Const32Value>(proc, Origin(), b)));
2766 CHECK(compileAndRun<int64_t>(proc) == (a << b));
2769 void testShlArgImm(int64_t a, int64_t b)
2772 BasicBlock* root = proc.addBlock();
2773 root->appendNew<ControlValue>(
2774 proc, Return, Origin(),
2775 root->appendNew<Value>(
2776 proc, Shl, Origin(),
2777 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2778 root->appendNew<Const32Value>(proc, Origin(), b)));
2780 CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
2783 void testShlArg32(int32_t a)
2786 BasicBlock* root = proc.addBlock();
2787 Value* value = root->appendNew<Value>(
2788 proc, Trunc, Origin(),
2789 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2790 root->appendNew<ControlValue>(
2791 proc, Return, Origin(),
2792 root->appendNew<Value>(proc, Shl, Origin(), value, value));
2794 CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
2797 void testShlArgs32(int32_t a, int32_t b)
2800 BasicBlock* root = proc.addBlock();
2801 root->appendNew<ControlValue>(
2802 proc, Return, Origin(),
2803 root->appendNew<Value>(
2804 proc, Shl, Origin(),
2805 root->appendNew<Value>(
2806 proc, Trunc, Origin(),
2807 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2808 root->appendNew<Value>(
2809 proc, Trunc, Origin(),
2810 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2812 CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
2815 void testShlImms32(int32_t a, int32_t b)
2818 BasicBlock* root = proc.addBlock();
2819 root->appendNew<ControlValue>(
2820 proc, Return, Origin(),
2821 root->appendNew<Value>(
2822 proc, Shl, Origin(),
2823 root->appendNew<Const32Value>(proc, Origin(), a),
2824 root->appendNew<Const32Value>(proc, Origin(), b)));
2826 CHECK(compileAndRun<int32_t>(proc) == (a << b));
2829 void testShlArgImm32(int32_t a, int32_t b)
2832 BasicBlock* root = proc.addBlock();
2833 root->appendNew<ControlValue>(
2834 proc, Return, Origin(),
2835 root->appendNew<Value>(
2836 proc, Shl, Origin(),
2837 root->appendNew<Value>(
2838 proc, Trunc, Origin(),
2839 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2840 root->appendNew<Const32Value>(proc, Origin(), b)));
2842 CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
2845 void testSShrArgs(int64_t a, int64_t b)
2848 BasicBlock* root = proc.addBlock();
2849 root->appendNew<ControlValue>(
2850 proc, Return, Origin(),
2851 root->appendNew<Value>(
2852 proc, SShr, Origin(),
2853 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2854 root->appendNew<Value>(
2855 proc, Trunc, Origin(),
2856 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2858 CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
2861 void testSShrImms(int64_t a, int64_t b)
2864 BasicBlock* root = proc.addBlock();
2865 root->appendNew<ControlValue>(
2866 proc, Return, Origin(),
2867 root->appendNew<Value>(
2868 proc, SShr, Origin(),
2869 root->appendNew<Const64Value>(proc, Origin(), a),
2870 root->appendNew<Const32Value>(proc, Origin(), b)));
2872 CHECK(compileAndRun<int64_t>(proc) == (a >> b));
2875 void testSShrArgImm(int64_t a, int64_t b)
2878 BasicBlock* root = proc.addBlock();
2879 root->appendNew<ControlValue>(
2880 proc, Return, Origin(),
2881 root->appendNew<Value>(
2882 proc, SShr, Origin(),
2883 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2884 root->appendNew<Const32Value>(proc, Origin(), b)));
2886 CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
2889 void testSShrArg32(int32_t a)
2892 BasicBlock* root = proc.addBlock();
2893 Value* value = root->appendNew<Value>(
2894 proc, Trunc, Origin(),
2895 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
2896 root->appendNew<ControlValue>(
2897 proc, Return, Origin(),
2898 root->appendNew<Value>(proc, SShr, Origin(), value, value));
2900 CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
2903 void testSShrArgs32(int32_t a, int32_t b)
2906 BasicBlock* root = proc.addBlock();
2907 root->appendNew<ControlValue>(
2908 proc, Return, Origin(),
2909 root->appendNew<Value>(
2910 proc, SShr, Origin(),
2911 root->appendNew<Value>(
2912 proc, Trunc, Origin(),
2913 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2914 root->appendNew<Value>(
2915 proc, Trunc, Origin(),
2916 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2918 CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
2921 void testSShrImms32(int32_t a, int32_t b)
2924 BasicBlock* root = proc.addBlock();
2925 root->appendNew<ControlValue>(
2926 proc, Return, Origin(),
2927 root->appendNew<Value>(
2928 proc, SShr, Origin(),
2929 root->appendNew<Const32Value>(proc, Origin(), a),
2930 root->appendNew<Const32Value>(proc, Origin(), b)));
2932 CHECK(compileAndRun<int32_t>(proc) == (a >> b));
2935 void testSShrArgImm32(int32_t a, int32_t b)
2938 BasicBlock* root = proc.addBlock();
2939 root->appendNew<ControlValue>(
2940 proc, Return, Origin(),
2941 root->appendNew<Value>(
2942 proc, SShr, Origin(),
2943 root->appendNew<Value>(
2944 proc, Trunc, Origin(),
2945 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
2946 root->appendNew<Const32Value>(proc, Origin(), b)));
2948 CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
2951 void testZShrArgs(uint64_t a, uint64_t b)
2954 BasicBlock* root = proc.addBlock();
2955 root->appendNew<ControlValue>(
2956 proc, Return, Origin(),
2957 root->appendNew<Value>(
2958 proc, ZShr, Origin(),
2959 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2960 root->appendNew<Value>(
2961 proc, Trunc, Origin(),
2962 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
2964 CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
2967 void testZShrImms(uint64_t a, uint64_t b)
2970 BasicBlock* root = proc.addBlock();
2971 root->appendNew<ControlValue>(
2972 proc, Return, Origin(),
2973 root->appendNew<Value>(
2974 proc, ZShr, Origin(),
2975 root->appendNew<Const64Value>(proc, Origin(), a),
2976 root->appendNew<Const32Value>(proc, Origin(), b)));
2978 CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
2981 void testZShrArgImm(uint64_t a, uint64_t b)
2984 BasicBlock* root = proc.addBlock();
2985 root->appendNew<ControlValue>(
2986 proc, Return, Origin(),
2987 root->appendNew<Value>(
2988 proc, ZShr, Origin(),
2989 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
2990 root->appendNew<Const32Value>(proc, Origin(), b)));
2992 CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
2995 void testZShrArg32(uint32_t a)
2998 BasicBlock* root = proc.addBlock();
2999 Value* value = root->appendNew<Value>(
3000 proc, Trunc, Origin(),
3001 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3002 root->appendNew<ControlValue>(
3003 proc, Return, Origin(),
3004 root->appendNew<Value>(proc, ZShr, Origin(), value, value));
3006 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
3009 void testZShrArgs32(uint32_t a, uint32_t b)
3012 BasicBlock* root = proc.addBlock();
3013 root->appendNew<ControlValue>(
3014 proc, Return, Origin(),
3015 root->appendNew<Value>(
3016 proc, ZShr, Origin(),
3017 root->appendNew<Value>(
3018 proc, Trunc, Origin(),
3019 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3020 root->appendNew<Value>(
3021 proc, Trunc, Origin(),
3022 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
3024 CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
3027 void testZShrImms32(uint32_t a, uint32_t b)
3030 BasicBlock* root = proc.addBlock();
3031 root->appendNew<ControlValue>(
3032 proc, Return, Origin(),
3033 root->appendNew<Value>(
3034 proc, ZShr, Origin(),
3035 root->appendNew<Const32Value>(proc, Origin(), a),
3036 root->appendNew<Const32Value>(proc, Origin(), b)));
3038 CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
3041 void testZShrArgImm32(uint32_t a, uint32_t b)
3044 BasicBlock* root = proc.addBlock();
3045 root->appendNew<ControlValue>(
3046 proc, Return, Origin(),
3047 root->appendNew<Value>(
3048 proc, ZShr, Origin(),
3049 root->appendNew<Value>(
3050 proc, Trunc, Origin(),
3051 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3052 root->appendNew<Const32Value>(proc, Origin(), b)));
3054 CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
3057 template<typename IntegerType>
3058 static unsigned countLeadingZero(IntegerType value)
3060 unsigned bitCount = sizeof(IntegerType) * 8;
3064 unsigned counter = 0;
3065 while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
3072 void testClzArg64(int64_t a)
3075 BasicBlock* root = proc.addBlock();
3076 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3077 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3078 root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
3079 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3082 void testClzMem64(int64_t a)
3085 BasicBlock* root = proc.addBlock();
3086 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3087 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3088 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3089 root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
3090 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3093 void testClzArg32(int32_t a)
3096 BasicBlock* root = proc.addBlock();
3097 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3098 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3099 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
3100 root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
3101 CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
3104 void testClzMem32(int32_t a)
3107 BasicBlock* root = proc.addBlock();
3108 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3109 MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3110 Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
3111 root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
3112 CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
3115 void testAbsArg(double a)
3118 BasicBlock* root = proc.addBlock();
3119 root->appendNew<ControlValue>(
3120 proc, Return, Origin(),
3121 root->appendNew<Value>(
3122 proc, Abs, Origin(),
3123 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3125 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3128 void testAbsImm(double a)
3131 BasicBlock* root = proc.addBlock();
3132 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3133 root->appendNew<ControlValue>(
3134 proc, Return, Origin(),
3135 root->appendNew<Value>(proc, Abs, Origin(), argument));
3137 CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
3140 void testAbsMem(double a)
3143 BasicBlock* root = proc.addBlock();
3144 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3145 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3146 root->appendNew<ControlValue>(
3147 proc, Return, Origin(),
3148 root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
3150 CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
3153 void testAbsAbsArg(double a)
3156 BasicBlock* root = proc.addBlock();
3157 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
3158 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3159 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3160 root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs);
3162 CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
3165 void testAbsBitwiseCastArg(double a)
3168 BasicBlock* root = proc.addBlock();
3169 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3170 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3171 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3172 root->appendNew<ControlValue>(proc, Return, Origin(), absValue);
3174 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
3177 void testBitwiseCastAbsBitwiseCastArg(double a)
3180 BasicBlock* root = proc.addBlock();
3181 Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3182 Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
3183 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
3184 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3186 root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64);
3188 int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
3189 CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
3192 void testAbsArg(float a)
3195 BasicBlock* root = proc.addBlock();
3196 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3197 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3198 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3199 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3200 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3201 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3203 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3206 void testAbsImm(float a)
3209 BasicBlock* root = proc.addBlock();
3210 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3211 Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
3212 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3213 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3215 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3218 void testAbsMem(float a)
3221 BasicBlock* root = proc.addBlock();
3222 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3223 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3224 Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
3225 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3226 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3228 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3231 void testAbsAbsArg(float a)
3234 BasicBlock* root = proc.addBlock();
3235 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3236 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3237 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3238 Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
3239 Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
3240 root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs);
3242 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3245 void testAbsBitwiseCastArg(float a)
3248 BasicBlock* root = proc.addBlock();
3249 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3250 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3251 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3252 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3253 root->appendNew<ControlValue>(proc, Return, Origin(), absValue);
3255 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
3258 void testBitwiseCastAbsBitwiseCastArg(float a)
3261 BasicBlock* root = proc.addBlock();
3262 Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
3263 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3264 Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
3265 Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
3266 Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
3268 root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64);
3270 int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
3271 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
3274 void testAbsArgWithUselessDoubleConversion(float a)
3277 BasicBlock* root = proc.addBlock();
3278 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3279 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3280 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3281 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3282 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3283 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3284 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3285 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3287 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3290 void testAbsArgWithEffectfulDoubleConversion(float a)
3293 BasicBlock* root = proc.addBlock();
3294 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3295 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3296 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3297 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3298 Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
3299 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3300 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3301 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3302 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3303 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3306 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
3307 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
3308 CHECK(isIdentical(effect, fabs(a)));
3311 void testCeilArg(double a)
3314 BasicBlock* root = proc.addBlock();
3315 root->appendNew<ControlValue>(
3316 proc, Return, Origin(),
3317 root->appendNew<Value>(
3318 proc, Ceil, Origin(),
3319 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3321 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3324 void testCeilImm(double a)
3327 BasicBlock* root = proc.addBlock();
3328 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3329 root->appendNew<ControlValue>(
3330 proc, Return, Origin(),
3331 root->appendNew<Value>(proc, Ceil, Origin(), argument));
3333 CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
3336 void testCeilMem(double a)
3339 BasicBlock* root = proc.addBlock();
3340 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3341 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3342 root->appendNew<ControlValue>(
3343 proc, Return, Origin(),
3344 root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
3346 CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
3349 void testCeilCeilArg(double a)
3352 BasicBlock* root = proc.addBlock();
3353 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
3354 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
3355 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
3356 root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil);
3358 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
3361 void testCeilIToD64(int64_t a)
3364 BasicBlock* root = proc.addBlock();
3365 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3366 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3368 root->appendNew<ControlValue>(
3369 proc, Return, Origin(),
3370 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3372 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3375 void testCeilIToD32(int64_t a)
3378 BasicBlock* root = proc.addBlock();
3379 Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
3380 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3381 Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
3383 root->appendNew<ControlValue>(
3384 proc, Return, Origin(),
3385 root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
3387 CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
3390 void testCeilArg(float a)
3393 BasicBlock* root = proc.addBlock();
3394 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3395 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3396 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3397 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3398 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3399 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3401 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3404 void testCeilImm(float a)
3407 BasicBlock* root = proc.addBlock();
3408 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3409 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3410 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3411 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3413 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3416 void testCeilMem(float a)
3419 BasicBlock* root = proc.addBlock();
3420 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3421 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3422 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
3423 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3424 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3426 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
3429 void testCeilCeilArg(float a)
3432 BasicBlock* root = proc.addBlock();
3433 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3434 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3435 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3436 Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
3437 Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
3438 root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil);
3440 CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
3443 void testCeilArgWithUselessDoubleConversion(float a)
3446 BasicBlock* root = proc.addBlock();
3447 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3448 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3449 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3450 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3451 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
3452 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3453 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3454 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3456 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
3459 void testCeilArgWithEffectfulDoubleConversion(float a)
3462 BasicBlock* root = proc.addBlock();
3463 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3464 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3465 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3466 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3467 Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
3468 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3469 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3470 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3471 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3472 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3475 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
3476 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
3477 CHECK(isIdentical(effect, ceilf(a)));
3480 void testSqrtArg(double a)
3483 BasicBlock* root = proc.addBlock();
3484 root->appendNew<ControlValue>(
3485 proc, Return, Origin(),
3486 root->appendNew<Value>(
3487 proc, Sqrt, Origin(),
3488 root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
3490 CHECK(isIdentical(compileAndRun<double>(proc, a), sqrt(a)));
3493 void testSqrtImm(double a)
3496 BasicBlock* root = proc.addBlock();
3497 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
3498 root->appendNew<ControlValue>(
3499 proc, Return, Origin(),
3500 root->appendNew<Value>(proc, Sqrt, Origin(), argument));
3502 CHECK(isIdentical(compileAndRun<double>(proc), sqrt(a)));
3505 void testSqrtMem(double a)
3508 BasicBlock* root = proc.addBlock();
3509 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3510 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3511 root->appendNew<ControlValue>(
3512 proc, Return, Origin(),
3513 root->appendNew<Value>(proc, Sqrt, Origin(), loadDouble));
3515 CHECK(isIdentical(compileAndRun<double>(proc, &a), sqrt(a)));
3518 void testSqrtArg(float a)
3521 BasicBlock* root = proc.addBlock();
3522 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3523 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3524 Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3525 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
3526 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3527 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3529 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
3532 void testSqrtImm(float a)
3535 BasicBlock* root = proc.addBlock();
3536 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
3537 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
3538 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3539 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3541 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
3544 void testSqrtMem(float a)
3547 BasicBlock* root = proc.addBlock();
3548 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3549 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3550 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), loadFloat);
3551 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
3552 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3554 CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
3557 void testSqrtArgWithUselessDoubleConversion(float a)
3560 BasicBlock* root = proc.addBlock();
3561 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3562 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3563 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3564 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3565 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
3566 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3567 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3568 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3570 CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
3573 void testSqrtArgWithEffectfulDoubleConversion(float a)
3576 BasicBlock* root = proc.addBlock();
3577 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3578 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3579 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3580 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3581 Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
3582 Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
3583 Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
3584 Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3585 root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
3586 root->appendNew<ControlValue>(proc, Return, Origin(), result32);
3589 int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
3590 CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
3591 CHECK(isIdentical(effect, sqrt(a)));
3594 void testDoubleArgToInt64BitwiseCast(double value)
3597 BasicBlock* root = proc.addBlock();
3598 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
3600 root->appendNew<ControlValue>(
3601 proc, Return, Origin(),
3602 root->appendNew<Value>(
3603 proc, BitwiseCast, Origin(), argument));
3605 CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
3608 void testDoubleImmToInt64BitwiseCast(double value)
3611 BasicBlock* root = proc.addBlock();
3612 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
3614 root->appendNew<ControlValue>(
3615 proc, Return, Origin(),
3616 root->appendNew<Value>(
3617 proc, BitwiseCast, Origin(), argument));
3619 CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
3622 void testTwoBitwiseCastOnDouble(double value)
3625 BasicBlock* root = proc.addBlock();
3626 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
3627 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
3628 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
3629 root->appendNew<ControlValue>(proc, Return, Origin(), second);
3631 CHECK(isIdentical(compileAndRun<double>(proc, value), value));
3634 void testBitwiseCastOnDoubleInMemory(double value)
3637 BasicBlock* root = proc.addBlock();
3638 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3639 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3640 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
3641 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3643 CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
3646 void testBitwiseCastOnDoubleInMemoryIndexed(double value)
3649 BasicBlock* root = proc.addBlock();
3650 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3651 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3652 Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
3654 root->appendNew<Const32Value>(proc, Origin(), 3));
3655 Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
3656 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3657 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
3658 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3660 CHECK(isIdentical(compileAndRun<int64_t>(proc, &value, 0), bitwise_cast<int64_t>(value)));
3663 void testInt64BArgToDoubleBitwiseCast(int64_t value)
3666 BasicBlock* root = proc.addBlock();
3667 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3669 root->appendNew<ControlValue>(
3670 proc, Return, Origin(),
3671 root->appendNew<Value>(
3672 proc, BitwiseCast, Origin(), argument));
3674 CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
3677 void testInt64BImmToDoubleBitwiseCast(int64_t value)
3680 BasicBlock* root = proc.addBlock();
3681 Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
3683 root->appendNew<ControlValue>(
3684 proc, Return, Origin(),
3685 root->appendNew<Value>(
3686 proc, BitwiseCast, Origin(), argument));
3688 CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
3691 void testTwoBitwiseCastOnInt64(int64_t value)
3694 BasicBlock* root = proc.addBlock();
3695 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3696 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
3697 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
3698 root->appendNew<ControlValue>(proc, Return, Origin(), second);
3700 CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
3703 void testBitwiseCastOnInt64InMemory(int64_t value)
3706 BasicBlock* root = proc.addBlock();
3707 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3708 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3709 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
3710 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3712 CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
3715 void testBitwiseCastOnInt64InMemoryIndexed(int64_t value)
3718 BasicBlock* root = proc.addBlock();
3719 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3720 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3721 Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
3723 root->appendNew<Const32Value>(proc, Origin(), 3));
3724 Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
3725 MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
3726 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
3727 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3729 CHECK(isIdentical(compileAndRun<double>(proc, &value, 0), bitwise_cast<double>(value)));
3732 void testFloatImmToInt32BitwiseCast(float value)
3735 BasicBlock* root = proc.addBlock();
3736 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
3738 root->appendNew<ControlValue>(
3739 proc, Return, Origin(),
3740 root->appendNew<Value>(
3741 proc, BitwiseCast, Origin(), argument));
3743 CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(value)));
3746 void testBitwiseCastOnFloatInMemory(float value)
3749 BasicBlock* root = proc.addBlock();
3750 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3751 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3752 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
3753 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3755 CHECK(isIdentical(compileAndRun<int32_t>(proc, &value), bitwise_cast<int32_t>(value)));
3758 void testInt32BArgToFloatBitwiseCast(int32_t value)
3761 BasicBlock* root = proc.addBlock();
3762 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3764 root->appendNew<ControlValue>(
3765 proc, Return, Origin(),
3766 root->appendNew<Value>(
3767 proc, BitwiseCast, Origin(), argument));
3769 CHECK(isIdentical(compileAndRun<float>(proc, value), bitwise_cast<float>(value)));
3772 void testInt32BImmToFloatBitwiseCast(int32_t value)
3775 BasicBlock* root = proc.addBlock();
3776 Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
3778 root->appendNew<ControlValue>(
3779 proc, Return, Origin(),
3780 root->appendNew<Value>(
3781 proc, BitwiseCast, Origin(), argument));
3783 CHECK(isIdentical(compileAndRun<float>(proc), bitwise_cast<float>(value)));
3786 void testTwoBitwiseCastOnInt32(int32_t value)
3789 BasicBlock* root = proc.addBlock();
3790 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3791 Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
3792 Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
3793 root->appendNew<ControlValue>(proc, Return, Origin(), second);
3795 CHECK(isIdentical(compileAndRun<int32_t>(proc, value), value));
3798 void testBitwiseCastOnInt32InMemory(int32_t value)
3801 BasicBlock* root = proc.addBlock();
3802 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3803 MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
3804 Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
3805 root->appendNew<ControlValue>(proc, Return, Origin(), cast);
3807 CHECK(isIdentical(compileAndRun<float>(proc, &value), bitwise_cast<float>(value)));
3810 void testConvertDoubleToFloatArg(double value)
3813 BasicBlock* root = proc.addBlock();
3814 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
3815 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
3816 root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
3818 CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
3821 void testConvertDoubleToFloatImm(double value)
3824 BasicBlock* root = proc.addBlock();
3825 Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
3826 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
3827 root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
3829 CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
3832 void testConvertDoubleToFloatMem(double value)
3835 BasicBlock* root = proc.addBlock();
3836 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3837 MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3838 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
3839 root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
3841 CHECK(isIdentical(compileAndRun<float>(proc, &value), static_cast<float>(value)));
3844 void testConvertFloatToDoubleArg(float value)
3847 BasicBlock* root = proc.addBlock();
3848 Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
3849 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3850 Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
3851 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
3852 root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
3854 CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(value)), static_cast<double>(value)));
3857 void testConvertFloatToDoubleImm(float value)
3860 BasicBlock* root = proc.addBlock();
3861 Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
3862 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument);
3863 root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
3865 CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
3868 void testConvertFloatToDoubleMem(float value)
3871 BasicBlock* root = proc.addBlock();
3872 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3873 MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
3874 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
3875 root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
3877 CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(value)));
3880 void testConvertDoubleToFloatToDoubleToFloat(double value)
3883 BasicBlock* root = proc.addBlock();
3884 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
3885 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
3886 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
3887 Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
3888 root->appendNew<ControlValue>(proc, Return, Origin(), asFloatAgain);
3890 CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
3893 void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value)
3896 BasicBlock* root = proc.addBlock();
3897 Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3898 Value* dst = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
3899 MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), src);
3900 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
3901 Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
3902 root->appendNew<MemoryValue>(proc, Store, Origin(), asFloatAgain, dst);
3904 root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3906 float input = value;
3908 CHECK(!compileAndRun<int64_t>(proc, &input, &output));
3909 CHECK(isIdentical(input, output));
3912 void testFroundArg(double value)
3915 BasicBlock* root = proc.addBlock();
3916 Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
3917 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
3918 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
3919 root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
3921 CHECK(isIdentical(compileAndRun<double>(proc, value), static_cast<double>(static_cast<float>(value))));
3924 void testFroundMem(double value)
3927 BasicBlock* root = proc.addBlock();
3928 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
3929 MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
3930 Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
3931 Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
3932 root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
3934 CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(static_cast<float>(value))));
3937 void testStore32(int value)
3940 BasicBlock* root = proc.addBlock();
3941 int slot = 0xbaadbeef;
3942 root->appendNew<MemoryValue>(
3943 proc, Store, Origin(),
3944 root->appendNew<Value>(
3945 proc, Trunc, Origin(),
3946 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
3947 root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
3948 root->appendNew<ControlValue>(
3949 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3951 CHECK(!compileAndRun<int>(proc, value));
3952 CHECK(slot == value);
3955 void testStoreConstant(int value)
3958 BasicBlock* root = proc.addBlock();
3959 int slot = 0xbaadbeef;
3960 root->appendNew<MemoryValue>(
3961 proc, Store, Origin(),
3962 root->appendNew<Const32Value>(proc, Origin(), value),
3963 root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
3964 root->appendNew<ControlValue>(
3965 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3967 CHECK(!compileAndRun<int>(proc));
3968 CHECK(slot == value);
3971 void testStoreConstantPtr(intptr_t value)
3974 BasicBlock* root = proc.addBlock();
3977 slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
3980 root->appendNew<MemoryValue>(
3981 proc, Store, Origin(),
3982 root->appendNew<ConstPtrValue>(proc, Origin(), value),
3983 root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
3984 root->appendNew<ControlValue>(
3985 proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
3987 CHECK(!compileAndRun<int>(proc));
3988 CHECK(slot == value);
3991 void testStore8Arg()
3993 { // Direct addressing.
3995 BasicBlock* root = proc.addBlock();
3997 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
3998 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
3999 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
4001 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
4002 root->appendNew<ControlValue>(proc, Return, Origin(), value);
4005 CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
4006 CHECK(storage == 42);
4009 { // Indexed addressing.
4011 BasicBlock* root = proc.addBlock();
4013 Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
4014 root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
4015 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
4016 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
4017 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
4019 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
4020 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
4022 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
4023 root->appendNew<ControlValue>(proc, Return, Origin(), value);
4026 CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
4027 CHECK(storage == 42);
4031 void testStore8Imm()
4033 { // Direct addressing.
4035 BasicBlock* root = proc.addBlock();
4037 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
4038 Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
4040 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
4041 root->appendNew<ControlValue>(proc, Return, Origin(), value);
4044 CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
4045 CHECK(storage == 42);
4048 { // Indexed addressing.
4050 BasicBlock* root = proc.addBlock();
4052 Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
4053 Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
4054 Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
4055 Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
4057 Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
4058 Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
4060 root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
4061 root->appendNew<ControlValue>(proc, Return, Origin(), value);
4064 CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
4065 CHECK(storage == 42);
4069 void testStorePartial8BitRegisterOnX86()