summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/b3/testb3.cpp
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/b3/testb3.cpp
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/b3/testb3.cpp')
-rw-r--r--Source/JavaScriptCore/b3/testb3.cpp12845
1 files changed, 0 insertions, 12845 deletions
diff --git a/Source/JavaScriptCore/b3/testb3.cpp b/Source/JavaScriptCore/b3/testb3.cpp
deleted file mode 100644
index c9313cb03..000000000
--- a/Source/JavaScriptCore/b3/testb3.cpp
+++ /dev/null
@@ -1,12845 +0,0 @@
-/*
- * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#include "AllowMacroScratchRegisterUsage.h"
-#include "B3ArgumentRegValue.h"
-#include "B3BasicBlockInlines.h"
-#include "B3CCallValue.h"
-#include "B3Compilation.h"
-#include "B3ComputeDivisionMagic.h"
-#include "B3Const32Value.h"
-#include "B3ConstPtrValue.h"
-#include "B3ControlValue.h"
-#include "B3Effects.h"
-#include "B3MathExtras.h"
-#include "B3MemoryValue.h"
-#include "B3Procedure.h"
-#include "B3SlotBaseValue.h"
-#include "B3StackSlot.h"
-#include "B3StackmapGenerationParams.h"
-#include "B3SwitchValue.h"
-#include "B3UpsilonValue.h"
-#include "B3ValueInlines.h"
-#include "CCallHelpers.h"
-#include "InitializeThreading.h"
-#include "JSCInlines.h"
-#include "LinkBuffer.h"
-#include "PureNaN.h"
-#include "VM.h"
-#include <cmath>
-#include <string>
-#include <wtf/Lock.h>
-#include <wtf/NumberOfCores.h>
-#include <wtf/Threading.h>
-
-// We don't have a NO_RETURN_DUE_TO_EXIT, nor should we. That's ridiculous.
-static bool hiddenTruthBecauseNoReturnIsStupid() { return true; }
-
-static void usage()
-{
- dataLog("Usage: testb3 [<filter>]\n");
- if (hiddenTruthBecauseNoReturnIsStupid())
- exit(1);
-}
-
-#if ENABLE(B3_JIT)
-
-using namespace JSC;
-using namespace JSC::B3;
-
-namespace {
-
-StaticLock crashLock;
-
-// Nothing fancy for now; we just use the existing WTF assertion machinery.
-#define CHECK(x) do { \
- if (!!(x)) \
- break; \
- crashLock.lock(); \
- WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #x); \
- CRASH(); \
- } while (false)
-
-VM* vm;
-
-std::unique_ptr<Compilation> compile(Procedure& procedure, unsigned optLevel = 1)
-{
- return std::make_unique<Compilation>(*vm, procedure, optLevel);
-}
-
-template<typename T, typename... Arguments>
-T invoke(const Compilation& code, Arguments... arguments)
-{
- T (*function)(Arguments...) = bitwise_cast<T(*)(Arguments...)>(code.code().executableAddress());
- return function(arguments...);
-}
-
-template<typename T, typename... Arguments>
-T compileAndRun(Procedure& procedure, Arguments... arguments)
-{
- return invoke<T>(*compile(procedure), arguments...);
-}
-
-template<typename Type>
-struct Operand {
- const char* name;
- Type value;
-};
-
-typedef Operand<int64_t> Int64Operand;
-typedef Operand<int32_t> Int32Operand;
-
-template<typename FloatType>
-void populateWithInterestingValues(Vector<Operand<FloatType>>& operands)
-{
- operands.append({ "0.", static_cast<FloatType>(0.) });
- operands.append({ "-0.", static_cast<FloatType>(-0.) });
- operands.append({ "0.4", static_cast<FloatType>(0.5) });
- operands.append({ "-0.4", static_cast<FloatType>(-0.5) });
- operands.append({ "0.5", static_cast<FloatType>(0.5) });
- operands.append({ "-0.5", static_cast<FloatType>(-0.5) });
- operands.append({ "0.6", static_cast<FloatType>(0.5) });
- operands.append({ "-0.6", static_cast<FloatType>(-0.5) });
- operands.append({ "1.", static_cast<FloatType>(1.) });
- operands.append({ "-1.", static_cast<FloatType>(-1.) });
- operands.append({ "2.", static_cast<FloatType>(2.) });
- operands.append({ "-2.", static_cast<FloatType>(-2.) });
- operands.append({ "M_PI", static_cast<FloatType>(M_PI) });
- operands.append({ "-M_PI", static_cast<FloatType>(-M_PI) });
- operands.append({ "min", std::numeric_limits<FloatType>::min() });
- operands.append({ "max", std::numeric_limits<FloatType>::max() });
- operands.append({ "lowest", std::numeric_limits<FloatType>::lowest() });
- operands.append({ "epsilon", std::numeric_limits<FloatType>::epsilon() });
- operands.append({ "infiniti", std::numeric_limits<FloatType>::infinity() });
- operands.append({ "-infiniti", - std::numeric_limits<FloatType>::infinity() });
- operands.append({ "PNaN", static_cast<FloatType>(PNaN) });
-}
-
-template<typename FloatType>
-Vector<Operand<FloatType>> floatingPointOperands()
-{
- Vector<Operand<FloatType>> operands;
- populateWithInterestingValues(operands);
- return operands;
-};
-
-static Vector<Int64Operand> int64Operands()
-{
- Vector<Int64Operand> operands;
- operands.append({ "1", 1 });
- operands.append({ "-1", -1 });
- operands.append({ "42", 42 });
- operands.append({ "-42", -42 });
- operands.append({ "int64-max", std::numeric_limits<int64_t>::max() });
- operands.append({ "int64-min", std::numeric_limits<int64_t>::min() });
- operands.append({ "int32-max", std::numeric_limits<int32_t>::max() });
- operands.append({ "int32-min", std::numeric_limits<int32_t>::min() });
-
- return operands;
-}
-
-static Vector<Int32Operand> int32Operands()
-{
- Vector<Int32Operand> operands({
- { "0", 0 },
- { "1", 1 },
- { "-1", -1 },
- { "42", 42 },
- { "-42", -42 },
- { "int32-max", std::numeric_limits<int32_t>::max() },
- { "int32-min", std::numeric_limits<int32_t>::min() }
- });
- return operands;
-}
-
-void add32(CCallHelpers& jit, GPRReg src1, GPRReg src2, GPRReg dest)
-{
- if (src2 == dest)
- jit.add32(src1, dest);
- else {
- jit.move(src1, dest);
- jit.add32(src2, dest);
- }
-}
-
-void test42()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* const42 = root->appendNew<Const32Value>(proc, Origin(), 42);
- root->appendNew<ControlValue>(proc, Return, Origin(), const42);
-
- CHECK(compileAndRun<int>(proc) == 42);
-}
-
-void testLoad42()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int x = 42;
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &x)));
-
- CHECK(compileAndRun<int>(proc) == 42);
-}
-
-void testLoadWithOffsetImpl(int32_t offset64, int32_t offset32)
-{
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int64_t x = -42;
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int64, Origin(),
- base,
- offset64));
-
- char* address = reinterpret_cast<char*>(&x) - offset64;
- CHECK(compileAndRun<int64_t>(proc, address) == -42);
- }
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int32_t x = -42;
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- base,
- offset32));
-
- char* address = reinterpret_cast<char*>(&x) - offset32;
- CHECK(compileAndRun<int32_t>(proc, address) == -42);
- }
-}
-
-void testLoadOffsetImm9Max()
-{
- testLoadWithOffsetImpl(255, 255);
-}
-
-void testLoadOffsetImm9MaxPlusOne()
-{
- testLoadWithOffsetImpl(256, 256);
-}
-
-void testLoadOffsetImm9MaxPlusTwo()
-{
- testLoadWithOffsetImpl(257, 257);
-}
-
-void testLoadOffsetImm9Min()
-{
- testLoadWithOffsetImpl(-256, -256);
-}
-
-void testLoadOffsetImm9MinMinusOne()
-{
- testLoadWithOffsetImpl(-257, -257);
-}
-
-void testLoadOffsetScaledUnsignedImm12Max()
-{
- testLoadWithOffsetImpl(32760, 16380);
-}
-
-void testLoadOffsetScaledUnsignedOverImm12Max()
-{
- testLoadWithOffsetImpl(32760, 32760);
- testLoadWithOffsetImpl(32761, 16381);
- testLoadWithOffsetImpl(32768, 16384);
-}
-
-void testArg(int argument)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
-
- CHECK(compileAndRun<int>(proc, argument) == argument);
-}
-
-void testReturnConst64(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), value));
-
- CHECK(compileAndRun<int64_t>(proc) == value);
-}
-
-void testAddArg(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), value, value));
-
- CHECK(compileAndRun<int>(proc, a) == a + a);
-}
-
-void testAddArgs(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int>(proc, a, b) == a + b);
-}
-
-void testAddArgImm(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc, a) == a + b);
-}
-
-void testAddImmArg(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int>(proc, b) == a + b);
-}
-
-void testAddArgMem(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Add, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t inputOutput = b;
- CHECK(!compileAndRun<int64_t>(proc, a, &inputOutput));
- CHECK(inputOutput == a + b);
-}
-
-void testAddMemArg(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Add, Origin(),
- load,
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, &a, b) == a + b);
-}
-
-void testAddImmMem(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Add, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t inputOutput = b;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a + b);
-}
-
-void testAddArg32(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), value, value));
-
- CHECK(compileAndRun<int>(proc, a) == a + a);
-}
-
-void testAddArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == a + b);
-}
-
-void testAddArgMem32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* result = root->appendNew<Value>(proc, Add, Origin(), argument, load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t inputOutput = b;
- CHECK(!compileAndRun<int32_t>(proc, a, &inputOutput));
- CHECK(inputOutput == a + b);
-}
-
-void testAddMemArg32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* result = root->appendNew<Value>(proc, Add, Origin(), load, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, &a, b) == a + b);
-}
-
-void testAddImmMem32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Add, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t inputOutput = b;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a + b);
-}
-
-void testAddArgZeroImmZDef()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* constZero = root->appendNew<Const32Value>(proc, Origin(), 0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- arg,
- constZero));
-
- auto code = compile(proc, 0);
- CHECK(invoke<int64_t>(*code, 0x0123456789abcdef) == 0x89abcdef);
-}
-
-void testAddLoadTwice()
-{
- auto test = [&] (unsigned optLevel) {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int32_t value = 42;
- Value* load = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &value));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), load, load));
-
- auto code = compile(proc, optLevel);
- CHECK(invoke<int32_t>(*code) == 42 * 2);
- };
-
- test(0);
- test(1);
-}
-
-void testAddArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), value, value));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a + a));
-}
-
-void testAddArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), a + b));
-}
-
-void testAddArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a + b));
-}
-
-void testAddImmArgDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, b), a + b));
-}
-
-void testAddImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Add, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc), a + b));
-}
-
-void testAddArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
-}
-
-void testAddArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue1, floatValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
-}
-
-void testAddArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), floatValue, constValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + b)));
-}
-
-void testAddImmArgFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
-}
-
-void testAddImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), constValue1, constValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a + b)));
-}
-
-void testAddArgFloatWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble, asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a + a)));
-}
-
-void testAddArgsFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a + b)));
-}
-
-void testAddArgsFloatWithEffectfulDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a + b)));
- CHECK(isIdentical(effect, static_cast<double>(a) + static_cast<double>(b)));
-}
-
-void testMulArg(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(), root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), value, value));
-
- CHECK(compileAndRun<int>(proc, a) == a * a);
-}
-
-void testMulArgStore(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- int mulSlot;
- int valueSlot;
-
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* mul = root->appendNew<Value>(proc, Mul, Origin(), value, value);
-
- root->appendNew<MemoryValue>(
- proc, Store, Origin(), value,
- root->appendNew<ConstPtrValue>(proc, Origin(), &valueSlot));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(), mul,
- root->appendNew<ConstPtrValue>(proc, Origin(), &mulSlot));
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, a));
- CHECK(mulSlot == a * a);
- CHECK(valueSlot == a);
-}
-
-void testMulAddArg(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), value, value),
- value));
-
- CHECK(compileAndRun<int>(proc, a) == a * a + a);
-}
-
-void testMulArgs(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Mul, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int>(proc, a, b) == a * b);
-}
-
-void testMulArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Mul, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == a * b);
-}
-
-void testMulImmArg(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Mul, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int>(proc, b) == a * b);
-}
-
-void testMulArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Mul, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == a * b);
-}
-
-void testMulLoadTwice()
-{
- auto test = [&] (unsigned optLevel) {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int32_t value = 42;
- Value* load = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &value));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), load, load));
-
- auto code = compile(proc, optLevel);
- CHECK(invoke<int32_t>(*code) == 42 * 42);
- };
-
- test(0);
- test(1);
-}
-
-void testMulAddArgsLeft()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int64Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
- }
- }
- }
-}
-
-void testMulAddArgsRight()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
- Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int64Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
- }
- }
- }
-}
-
-void testMulAddArgsLeft32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* added = root->appendNew<Value>(proc, Add, Origin(), multiplied, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int32Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value + c.value);
- }
- }
- }
-}
-
-void testMulAddArgsRight32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
- Value* added = root->appendNew<Value>(proc, Add, Origin(), arg0, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int32Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value + b.value * c.value);
- }
- }
- }
-}
-
-void testMulSubArgsLeft()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int64Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
- }
- }
- }
-}
-
-void testMulSubArgsRight()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int64Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int64_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
- }
- }
- }
-}
-
-void testMulSubArgsLeft32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), multiplied, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int32Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value * b.value - c.value);
- }
- }
- }
-}
-
-void testMulSubArgsRight32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg1, arg2);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), arg0, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int32Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- for (auto c : testValues) {
- CHECK(invoke<int32_t>(*code, a.value, b.value, c.value) == a.value - b.value * c.value);
- }
- }
- }
-}
-
-void testMulNegArgs()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* zero = root->appendNew<Const64Value>(proc, Origin(), 0);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int64Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- CHECK(invoke<int64_t>(*code, a.value, b.value) == -(a.value * b.value));
- }
- }
-}
-
-void testMulNegArgs32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* multiplied = root->appendNew<Value>(proc, Mul, Origin(), arg0, arg1);
- Value* zero = root->appendNew<Const32Value>(proc, Origin(), 0);
- Value* added = root->appendNew<Value>(proc, Sub, Origin(), zero, multiplied);
- root->appendNew<ControlValue>(proc, Return, Origin(), added);
-
- auto code = compile(proc);
-
- auto testValues = int32Operands();
- for (auto a : testValues) {
- for (auto b : testValues) {
- CHECK(invoke<int32_t>(*code, a.value, b.value) == -(a.value * b.value));
- }
- }
-}
-
-void testMulArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), value, value));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a * a));
-}
-
-void testMulArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), a * b));
-}
-
-void testMulArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a * b));
-}
-
-void testMulImmArgDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, b), a * b));
-}
-
-void testMulImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mul, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc), a * b));
-}
-
-void testMulArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
-}
-
-void testMulArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue1, floatValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
-}
-
-void testMulArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), floatValue, constValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * b)));
-}
-
-void testMulImmArgFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
-}
-
-void testMulImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), constValue1, constValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a * b)));
-}
-
-void testMulArgFloatWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble, asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a * a)));
-}
-
-void testMulArgsFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a * b)));
-}
-
-void testMulArgsFloatWithEffectfulDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Mul, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* doubleMulress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleMulress);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a * b)));
- CHECK(isIdentical(effect, static_cast<double>(a) * static_cast<double>(b)));
-}
-
-void testDivArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Div, Origin(), value, value));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a / a));
-}
-
-void testDivArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), a / b));
-}
-
-void testDivArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a / b));
-}
-
-void testDivImmArgDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, b), a / b));
-}
-
-void testDivImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Div, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc), a / b));
-}
-
-void testDivArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
-}
-
-void testDivArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue1, floatValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
-}
-
-void testDivArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), floatValue, constValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / b)));
-}
-
-void testDivImmArgFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
-}
-
-void testDivImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), constValue1, constValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a / b)));
-}
-
-void testModArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mod, Origin(), value, value));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, a)));
-}
-
-void testModArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), fmod(a, b)));
-}
-
-void testModArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), fmod(a, b)));
-}
-
-void testModImmArgDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, b), fmod(a, b)));
-}
-
-void testModImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Mod, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc), fmod(a, b)));
-}
-
-void testModArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, a)))));
-}
-
-void testModArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue1, floatValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- 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)))));
-}
-
-void testModArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), floatValue, constValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
-}
-
-void testModImmArgFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
-}
-
-void testModImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), constValue1, constValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(static_cast<float>(fmod(a, b)))));
-}
-
-void testDivArgFloatWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble, asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a / a)));
-}
-
-void testDivArgsFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a / b)));
-}
-
-void testDivArgsFloatWithEffectfulDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Div, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* doubleDivress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleDivress);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a / b)));
- CHECK(isIdentical(effect, static_cast<double>(a) / static_cast<double>(b)));
-}
-
-void testSubArg(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), value, value));
-
- CHECK(!compileAndRun<int>(proc, a));
-}
-
-void testSubArgs(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int>(proc, a, b) == a - b);
-}
-
-void testSubArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == a - b);
-}
-
-void testNegValueSubOne(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), 0),
- argument);
- Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
- negArgument,
- root->appendNew<Const64Value>(proc, Origin(), 1));
- root->appendNew<ControlValue>(proc, Return, Origin(), negArgumentMinusOne);
- CHECK(compileAndRun<int>(proc, a) == -a - 1);
-}
-
-void testSubImmArg(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int>(proc, b) == a - b);
-}
-
-void testSubArgMem(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- load);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, a, &b) == a - b);
-}
-
-void testSubMemArg(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- load,
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t inputOutput = a;
- CHECK(!compileAndRun<int64_t>(proc, &inputOutput, b));
- CHECK(inputOutput == a - b);
-}
-
-void testSubImmMem(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t inputOutput = b;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a - b);
-}
-
-void testSubMemImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- load,
- root->appendNew<Const64Value>(proc, Origin(), b));
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t inputOutput = a;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a - b);
-}
-
-
-void testSubArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == a - b);
-}
-
-void testSubArgImm32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc, a) == a - b);
-}
-
-void testSubImmArg32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int>(proc, b) == a - b);
-}
-
-void testSubMemArg32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), load, argument);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t inputOutput = a;
- CHECK(!compileAndRun<int32_t>(proc, &inputOutput, b));
- CHECK(inputOutput == a - b);
-}
-
-void testSubArgMem32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), argument, load);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, a, &b) == a - b);
-}
-
-void testSubImmMem32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t inputOutput = b;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a - b);
-}
-
-void testSubMemImm32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(),
- load,
- root->appendNew<Const32Value>(proc, Origin(), b));
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t inputOutput = a;
- CHECK(!compileAndRun<int>(proc, &inputOutput));
- CHECK(inputOutput == a - b);
-}
-
-void testNegValueSubOne32(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* negArgument = root->appendNew<Value>(proc, Sub, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- argument);
- Value* negArgumentMinusOne = root->appendNew<Value>(proc, Sub, Origin(),
- negArgument,
- root->appendNew<Const32Value>(proc, Origin(), 1));
- root->appendNew<ControlValue>(proc, Return, Origin(), negArgumentMinusOne);
- CHECK(compileAndRun<int>(proc, a) == -a - 1);
-}
-
-void testSubArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), value, value));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a - a));
-}
-
-void testSubArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), a - b));
-}
-
-void testSubArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), a - b));
-}
-
-void testSubImmArgDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc, b), a - b));
-}
-
-void testSubImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* valueA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* valueB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sub, Origin(), valueA, valueB));
-
- CHECK(isIdentical(compileAndRun<double>(proc), a - b));
-}
-
-void testSubArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
-}
-
-void testSubArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue1, floatValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
-}
-
-void testSubArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), floatValue, constValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - b)));
-}
-
-void testSubImmArgFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* constValue = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue, floatValue);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
-}
-
-void testSubImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* constValue1 = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* constValue2 = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), constValue1, constValue2);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(a - b)));
-}
-
-void testSubArgFloatWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentInt32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble, asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(a - a)));
-}
-
-void testSubArgsFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitwise_cast<int32_t>(a - b)));
-}
-
-void testSubArgsFloatWithEffectfulDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* asDouble1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* asDouble2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), asDouble1, asDouble2);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* doubleSubress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleSubress);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), &effect), bitwise_cast<int32_t>(a - b)));
- CHECK(isIdentical(effect, static_cast<double>(a) - static_cast<double>(b)));
-}
-
-void testBitAndArgs(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int64_t>(proc, a, b) == (a & b));
-}
-
-void testBitAndSameArg(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- argument,
- argument));
-
- CHECK(compileAndRun<int64_t>(proc, a) == a);
-}
-
-void testBitAndImms(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc) == (a & b));
-}
-
-void testBitAndArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == (a & b));
-}
-
-void testBitAndImmArg(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a & b));
-}
-
-void testBitAndBitAndArgImmImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitAnd = root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- innerBitAnd,
- root->appendNew<Const64Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == ((a & b) & c));
-}
-
-void testBitAndImmBitAndArgImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitAnd = root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- innerBitAnd));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a & (b & c)));
-}
-
-void testBitAndArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == (a & b));
-}
-
-void testBitAndSameArg32(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- argument,
- argument));
-
- CHECK(compileAndRun<int>(proc, a) == a);
-}
-
-void testBitAndImms32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc) == (a & b));
-}
-
-void testBitAndArgImm32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc, a) == (a & b));
-}
-
-void testBitAndImmArg32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int>(proc, b) == (a & b));
-}
-
-void testBitAndBitAndArgImmImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitAnd = root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- innerBitAnd,
- root->appendNew<Const32Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int>(proc, a) == ((a & b) & c));
-}
-
-void testBitAndImmBitAndArgImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitAnd = root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- innerBitAnd));
-
- CHECK(compileAndRun<int>(proc, b) == (a & (b & c)));
-}
-
-void testBitAndWithMaskReturnsBooleans(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* equal = root->appendNew<Value>(proc, Equal, Origin(), arg0, arg1);
- Value* maskedEqual = root->appendNew<Value>(proc, BitAnd, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0x5),
- equal);
- Value* inverted = root->appendNew<Value>(proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0x1),
- maskedEqual);
- Value* select = root->appendNew<Value>(proc, Select, Origin(), inverted,
- root->appendNew<Const64Value>(proc, Origin(), 42),
- root->appendNew<Const64Value>(proc, Origin(), -5));
-
- root->appendNew<ControlValue>(proc, Return, Origin(), select);
-
- int64_t expected = (a == b) ? -5 : 42;
- CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
-}
-
-double bitAndDouble(double a, double b)
-{
- return bitwise_cast<double>(bitwise_cast<uint64_t>(a) & bitwise_cast<uint64_t>(b));
-}
-
-void testBitAndArgDouble(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), bitAndDouble(a, a)));
-}
-
-void testBitAndArgsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
-}
-
-void testBitAndArgImmDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a, b), bitAndDouble(a, b)));
-}
-
-void testBitAndImmsDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<double>(proc), bitAndDouble(a, b)));
-}
-
-float bitAndFloat(float a, float b)
-{
- return bitwise_cast<float>(bitwise_cast<uint32_t>(a) & bitwise_cast<uint32_t>(b));
-}
-
-void testBitAndArgFloat(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), bitAndFloat(a, a)));
-}
-
-void testBitAndArgsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
-}
-
-void testBitAndArgImmFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), bitAndFloat(a, b)));
-}
-
-void testBitAndImmsFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
- Value* result = root->appendNew<Value>(proc, BitAnd, Origin(), argumentA, argumentB);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(isIdentical(compileAndRun<float>(proc), bitAndFloat(a, b)));
-}
-
-void testBitAndArgsFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentA = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* argumentB = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* argumentAasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentA);
- Value* argumentBasDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argumentB);
- Value* doubleResult = root->appendNew<Value>(proc, BitAnd, Origin(), argumentAasDouble, argumentBasDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), doubleResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), floatResult);
-
- double doubleA = a;
- double doubleB = b;
- float expected = static_cast<float>(bitAndDouble(doubleA, doubleB));
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), expected));
-}
-
-void testBitOrArgs(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int64_t>(proc, a, b) == (a | b));
-}
-
-void testBitOrSameArg(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- argument,
- argument));
-
- CHECK(compileAndRun<int64_t>(proc, a) == a);
-}
-
-void testBitOrImms(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc) == (a | b));
-}
-
-void testBitOrArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == (a | b));
-}
-
-void testBitOrImmArg(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a | b));
-}
-
-void testBitOrBitOrArgImmImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitOr = root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- innerBitOr,
- root->appendNew<Const64Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == ((a | b) | c));
-}
-
-void testBitOrImmBitOrArgImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitOr = root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- innerBitOr));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a | (b | c)));
-}
-
-void testBitOrArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == (a | b));
-}
-
-void testBitOrSameArg32(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- argument,
- argument));
-
- CHECK(compileAndRun<int>(proc, a) == a);
-}
-
-void testBitOrImms32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc) == (a | b));
-}
-
-void testBitOrArgImm32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc, a) == (a | b));
-}
-
-void testBitOrImmArg32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int>(proc, b) == (a | b));
-}
-
-void testBitOrBitOrArgImmImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitOr = root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- innerBitOr,
- root->appendNew<Const32Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int>(proc, a) == ((a | b) | c));
-}
-
-void testBitOrImmBitOrArgImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitOr = root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- innerBitOr));
-
- CHECK(compileAndRun<int>(proc, b) == (a | (b | c)));
-}
-
-void testBitXorArgs(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int64_t>(proc, a, b) == (a ^ b));
-}
-
-void testBitXorSameArg(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- argument,
- argument));
-
- CHECK(!compileAndRun<int64_t>(proc, a));
-}
-
-void testBitXorImms(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc) == (a ^ b));
-}
-
-void testBitXorArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == (a ^ b));
-}
-
-void testBitXorImmArg(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a ^ b));
-}
-
-void testBitXorBitXorArgImmImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitXor = root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- innerBitXor,
- root->appendNew<Const64Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == ((a ^ b) ^ c));
-}
-
-void testBitXorImmBitXorArgImm(int64_t a, int64_t b, int64_t c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitXor = root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- innerBitXor));
-
- CHECK(compileAndRun<int64_t>(proc, b) == (a ^ (b ^ c)));
-}
-
-void testBitXorArgs32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, a, b) == (a ^ b));
-}
-
-void testBitXorSameArg32(int a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- argument,
- argument));
-
- CHECK(!compileAndRun<int>(proc, a));
-}
-
-void testBitXorImms32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc) == (a ^ b));
-}
-
-void testBitXorArgImm32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int>(proc, a) == (a ^ b));
-}
-
-void testBitXorImmArg32(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int>(proc, b) == (a ^ b));
-}
-
-void testBitXorBitXorArgImmImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitXor = root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- innerBitXor,
- root->appendNew<Const32Value>(proc, Origin(), c)));
-
- CHECK(compileAndRun<int>(proc, a) == ((a ^ b) ^ c));
-}
-
-void testBitXorImmBitXorArgImm32(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* innerBitXor = root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), c));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- innerBitXor));
-
- CHECK(compileAndRun<int>(proc, b) == (a ^ (b ^ c)));
-}
-
-void testBitNotArg(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), -1),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
-}
-
-void testBitNotImm(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), -1),
- root->appendNew<Const64Value>(proc, Origin(), a)));
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, a), static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
-}
-
-void testBitNotMem(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), -1),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int64_t input = a;
- compileAndRun<int32_t>(proc, &input);
- CHECK(isIdentical(input, static_cast<int64_t>((static_cast<uint64_t>(a) ^ 0xffffffffffffffff))));
-}
-
-void testBitNotArg32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), -1),
- argument));
- CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
-}
-
-void testBitNotImm32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), -1),
- root->appendNew<Const32Value>(proc, Origin(), a)));
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, a), static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
-}
-
-void testBitNotMem32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* notLoad = root->appendNew<Value>(proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), -1),
- load);
- root->appendNew<MemoryValue>(proc, Store, Origin(), notLoad, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- int32_t input = a;
- compileAndRun<int32_t>(proc, &input);
- CHECK(isIdentical(input, static_cast<int32_t>((static_cast<uint32_t>(a) ^ 0xffffffff))));
-}
-
-void testBitNotOnBooleanAndBranch32(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* arg1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* argsAreEqual = root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2);
- Value* argsAreNotEqual = root->appendNew<Value>(proc, BitXor, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), -1),
- argsAreEqual);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- argsAreNotEqual,
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -42));
-
- int32_t expectedValue = (a != b) ? 42 : -42;
- CHECK(compileAndRun<int32_t>(proc, a, b) == expectedValue);
-}
-
-void testShlArgs(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int64_t>(proc, a, b) == (a << b));
-}
-
-void testShlImms(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc) == (a << b));
-}
-
-void testShlArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == (a << b));
-}
-
-void testShlArg32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Shl, Origin(), value, value));
-
- CHECK(compileAndRun<int32_t>(proc, a) == (a << a));
-}
-
-void testShlArgs32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int32_t>(proc, a, b) == (a << b));
-}
-
-void testShlImms32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int32_t>(proc) == (a << b));
-}
-
-void testShlArgImm32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int32_t>(proc, a) == (a << b));
-}
-
-void testSShrArgs(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int64_t>(proc, a, b) == (a >> b));
-}
-
-void testSShrImms(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc) == (a >> b));
-}
-
-void testSShrArgImm(int64_t a, int64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int64_t>(proc, a) == (a >> b));
-}
-
-void testSShrArg32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, SShr, Origin(), value, value));
-
- CHECK(compileAndRun<int32_t>(proc, a) == (a >> (a & 31)));
-}
-
-void testSShrArgs32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int32_t>(proc, a, b) == (a >> b));
-}
-
-void testSShrImms32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int32_t>(proc) == (a >> b));
-}
-
-void testSShrArgImm32(int32_t a, int32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<int32_t>(proc, a) == (a >> b));
-}
-
-void testZShrArgs(uint64_t a, uint64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<uint64_t>(proc, a, b) == (a >> b));
-}
-
-void testZShrImms(uint64_t a, uint64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<uint64_t>(proc) == (a >> b));
-}
-
-void testZShrArgImm(uint64_t a, uint64_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<uint64_t>(proc, a) == (a >> b));
-}
-
-void testZShrArg32(uint32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* value = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, ZShr, Origin(), value, value));
-
- CHECK(compileAndRun<uint32_t>(proc, a) == (a >> (a & 31)));
-}
-
-void testZShrArgs32(uint32_t a, uint32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<uint32_t>(proc, a, b) == (a >> b));
-}
-
-void testZShrImms32(uint32_t a, uint32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), a),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<uint32_t>(proc) == (a >> b));
-}
-
-void testZShrArgImm32(uint32_t a, uint32_t b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), b)));
-
- CHECK(compileAndRun<uint32_t>(proc, a) == (a >> b));
-}
-
-template<typename IntegerType>
-static unsigned countLeadingZero(IntegerType value)
-{
- unsigned bitCount = sizeof(IntegerType) * 8;
- if (!value)
- return bitCount;
-
- unsigned counter = 0;
- while (!(static_cast<uint64_t>(value) & (1l << (bitCount - 1)))) {
- value <<= 1;
- ++counter;
- }
- return counter;
-}
-
-void testClzArg64(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
- CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
-}
-
-void testClzMem64(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
- root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
- CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
-}
-
-void testClzArg32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
- CHECK(compileAndRun<unsigned>(proc, a) == countLeadingZero(a));
-}
-
-void testClzMem32(int32_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* value = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* clzValue = root->appendNew<Value>(proc, Clz, Origin(), value);
- root->appendNew<ControlValue>(proc, Return, Origin(), clzValue);
- CHECK(compileAndRun<unsigned>(proc, &a) == countLeadingZero(a));
-}
-
-void testAbsArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Abs, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
-}
-
-void testAbsImm(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Abs, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc), fabs(a)));
-}
-
-void testAbsMem(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Abs, Origin(), loadDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, &a), fabs(a)));
-}
-
-void testAbsAbsArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), fabs(a)));
-}
-
-void testAbsBitwiseCastArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
- Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), absValue);
-
- CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int64_t>(a)), fabs(a)));
-}
-
-void testBitwiseCastAbsBitwiseCastArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentAsInt64 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argumentAsDouble = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt64);
- Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsDouble);
- Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64);
-
- int64_t expectedResult = bitwise_cast<int64_t>(fabs(a));
- CHECK(isIdentical(compileAndRun<int64_t>(proc, bitwise_cast<int64_t>(a)), expectedResult));
-}
-
-void testAbsArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
-}
-
-void testAbsImm(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Abs, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
-}
-
-void testAbsMem(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Abs, Origin(), loadFloat);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
-}
-
-void testAbsAbsArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* firstAbs = root->appendNew<Value>(proc, Abs, Origin(), argument);
- Value* secondAbs = root->appendNew<Value>(proc, Abs, Origin(), firstAbs);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondAbs);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
-}
-
-void testAbsBitwiseCastArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
- Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), absValue);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), static_cast<float>(fabs(a))));
-}
-
-void testBitwiseCastAbsBitwiseCastArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argumentAsInt32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentAsfloat = root->appendNew<Value>(proc, BitwiseCast, Origin(), argumentAsInt32);
- Value* absValue = root->appendNew<Value>(proc, Abs, Origin(), argumentAsfloat);
- Value* resultAsInt64 = root->appendNew<Value>(proc, BitwiseCast, Origin(), absValue);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), resultAsInt64);
-
- int32_t expectedResult = bitwise_cast<int32_t>(static_cast<float>(fabs(a)));
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), expectedResult));
-}
-
-void testAbsArgWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
-}
-
-void testAbsArgWithEffectfulDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Abs, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
- CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(fabs(a)))));
- CHECK(isIdentical(effect, fabs(a)));
-}
-
-void testCeilArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Ceil, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
-}
-
-void testCeilImm(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Ceil, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc), ceil(a)));
-}
-
-void testCeilMem(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Ceil, Origin(), loadDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, &a), ceil(a)));
-}
-
-void testCeilCeilArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
-}
-
-void testFloorCeilArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
- root->appendNew<ControlValue>(proc, Return, Origin(), wrappingFloor);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(a)));
-}
-
-void testCeilIToD64(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
-}
-
-void testCeilIToD32(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Ceil, Origin(), argumentAsDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), ceil(static_cast<double>(a))));
-}
-
-void testCeilArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
-}
-
-void testCeilImm(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Ceil, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
-}
-
-void testCeilMem(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Ceil, Origin(), loadFloat);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(ceilf(a))));
-}
-
-void testCeilCeilArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
- Value* secondCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstCeil);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondCeil);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
-}
-
-void testFloorCeilArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* firstCeil = root->appendNew<Value>(proc, Ceil, Origin(), argument);
- Value* wrappingFloor = root->appendNew<Value>(proc, Floor, Origin(), firstCeil);
- root->appendNew<ControlValue>(proc, Return, Origin(), wrappingFloor);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), ceilf(a)));
-}
-
-void testCeilArgWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(ceilf(a))));
-}
-
-void testCeilArgWithEffectfulDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Ceil, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
- CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(ceilf(a))));
- CHECK(isIdentical(effect, ceilf(a)));
-}
-
-void testFloorArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Floor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
-}
-
-void testFloorImm(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Floor, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc), floor(a)));
-}
-
-void testFloorMem(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Floor, Origin(), loadDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, &a), floor(a)));
-}
-
-void testFloorFloorArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondFloor);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
-}
-
-void testCeilFloorArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
- root->appendNew<ControlValue>(proc, Return, Origin(), wrappingCeil);
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), floor(a)));
-}
-
-void testFloorIToD64(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
-}
-
-void testFloorIToD32(int64_t a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentAsDouble = root->appendNew<Value>(proc, IToD, Origin(), argument);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Floor, Origin(), argumentAsDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), floor(static_cast<double>(a))));
-}
-
-void testFloorArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
-}
-
-void testFloorImm(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Floor, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
-}
-
-void testFloorMem(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Floor, Origin(), loadFloat);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(floorf(a))));
-}
-
-void testFloorFloorArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
- Value* secondFloor = root->appendNew<Value>(proc, Floor, Origin(), firstFloor);
- root->appendNew<ControlValue>(proc, Return, Origin(), secondFloor);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
-}
-
-void testCeilFloorArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* firstFloor = root->appendNew<Value>(proc, Floor, Origin(), argument);
- Value* wrappingCeil = root->appendNew<Value>(proc, Ceil, Origin(), firstFloor);
- root->appendNew<ControlValue>(proc, Return, Origin(), wrappingCeil);
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a)), floorf(a)));
-}
-
-void testFloorArgWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(floorf(a))));
-}
-
-void testFloorArgWithEffectfulDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Floor, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
- CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(floorf(a))));
- CHECK(isIdentical(effect, floorf(a)));
-}
-
-void testSqrtArg(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sqrt, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0)));
-
- CHECK(isIdentical(compileAndRun<double>(proc, a), sqrt(a)));
-}
-
-void testSqrtImm(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sqrt, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc), sqrt(a)));
-}
-
-void testSqrtMem(double a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Sqrt, Origin(), loadDouble));
-
- CHECK(isIdentical(compileAndRun<double>(proc, &a), sqrt(a)));
-}
-
-void testSqrtArg(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
-}
-
-void testSqrtImm(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), argument);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
-}
-
-void testSqrtMem(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), loadFloat);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), result);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, &a), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
-}
-
-void testSqrtArgWithUselessDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a)), bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
-}
-
-void testSqrtArgWithEffectfulDoubleConversion(float a)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- Value* result = root->appendNew<Value>(proc, Sqrt, Origin(), asDouble);
- Value* floatResult = root->appendNew<Value>(proc, DoubleToFloat, Origin(), result);
- Value* result32 = root->appendNew<Value>(proc, BitwiseCast, Origin(), floatResult);
- Value* doubleAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<MemoryValue>(proc, Store, Origin(), result, doubleAddress);
- root->appendNew<ControlValue>(proc, Return, Origin(), result32);
-
- double effect = 0;
- int32_t resultValue = compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), &effect);
- CHECK(isIdentical(resultValue, bitwise_cast<int32_t>(static_cast<float>(sqrt(a)))));
- CHECK(isIdentical(effect, sqrt(a)));
-}
-
-void testDoubleArgToInt64BitwiseCast(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, value), bitwise_cast<int64_t>(value)));
-}
-
-void testDoubleImmToInt64BitwiseCast(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc), bitwise_cast<int64_t>(value)));
-}
-
-void testTwoBitwiseCastOnDouble(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
- Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
- root->appendNew<ControlValue>(proc, Return, Origin(), second);
-
- CHECK(isIdentical(compileAndRun<double>(proc, value), value));
-}
-
-void testBitwiseCastOnDoubleInMemory(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, &value), bitwise_cast<int64_t>(value)));
-}
-
-void testBitwiseCastOnDoubleInMemoryIndexed(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
- offset,
- root->appendNew<Const32Value>(proc, Origin(), 3));
- Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, &value, 0), bitwise_cast<int64_t>(value)));
-}
-
-void testInt64BArgToDoubleBitwiseCast(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc, value), bitwise_cast<double>(value)));
-}
-
-void testInt64BImmToDoubleBitwiseCast(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<double>(proc), bitwise_cast<double>(value)));
-}
-
-void testTwoBitwiseCastOnInt64(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
- Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
- root->appendNew<ControlValue>(proc, Return, Origin(), second);
-
- CHECK(isIdentical(compileAndRun<int64_t>(proc, value), value));
-}
-
-void testBitwiseCastOnInt64InMemory(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<double>(proc, &value), bitwise_cast<double>(value)));
-}
-
-void testBitwiseCastOnInt64InMemoryIndexed(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* scaledOffset = root->appendNew<Value>(proc, Shl, Origin(),
- offset,
- root->appendNew<Const32Value>(proc, Origin(), 3));
- Value* address = root->appendNew<Value>(proc, Add, Origin(), base, scaledOffset);
- MemoryValue* loadDouble = root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<double>(proc, &value, 0), bitwise_cast<double>(value)));
-}
-
-void testFloatImmToInt32BitwiseCast(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc), bitwise_cast<int32_t>(value)));
-}
-
-void testBitwiseCastOnFloatInMemory(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, &value), bitwise_cast<int32_t>(value)));
-}
-
-void testInt32BArgToFloatBitwiseCast(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<float>(proc, value), bitwise_cast<float>(value)));
-}
-
-void testInt32BImmToFloatBitwiseCast(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<Const64Value>(proc, Origin(), value);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitwiseCast, Origin(), argument));
-
- CHECK(isIdentical(compileAndRun<float>(proc), bitwise_cast<float>(value)));
-}
-
-void testTwoBitwiseCastOnInt32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* first = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument);
- Value* second = root->appendNew<Value>(proc, BitwiseCast, Origin(), first);
- root->appendNew<ControlValue>(proc, Return, Origin(), second);
-
- CHECK(isIdentical(compileAndRun<int32_t>(proc, value), value));
-}
-
-void testBitwiseCastOnInt32InMemory(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadFloat = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), address);
- Value* cast = root->appendNew<Value>(proc, BitwiseCast, Origin(), loadFloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), cast);
-
- CHECK(isIdentical(compileAndRun<float>(proc, &value), bitwise_cast<float>(value)));
-}
-
-void testConvertDoubleToFloatArg(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
-
- CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
-}
-
-void testConvertDoubleToFloatImm(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstDoubleValue>(proc, Origin(), value);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
-
- CHECK(isIdentical(compileAndRun<float>(proc), static_cast<float>(value)));
-}
-
-void testConvertDoubleToFloatMem(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), asFloat);
-
- CHECK(isIdentical(compileAndRun<float>(proc, &value), static_cast<float>(value)));
-}
-
-void testConvertFloatToDoubleArg(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* floatValue = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument32);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue);
- root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
-
- CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(value)), static_cast<double>(value)));
-}
-
-void testConvertFloatToDoubleImm(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ConstFloatValue>(proc, Origin(), value);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
-
- CHECK(isIdentical(compileAndRun<double>(proc), static_cast<double>(value)));
-}
-
-void testConvertFloatToDoubleMem(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), address);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
-
- CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(value)));
-}
-
-void testConvertDoubleToFloatToDoubleToFloat(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
- Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
- root->appendNew<ControlValue>(proc, Return, Origin(), asFloatAgain);
-
- CHECK(isIdentical(compileAndRun<float>(proc, value), static_cast<float>(value)));
-}
-
-void testLoadFloatConvertDoubleConvertFloatStoreFloat(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* src = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* dst = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- MemoryValue* loadedFloat = root->appendNew<MemoryValue>(proc, Load, Float, Origin(), src);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), loadedFloat);
- Value* asFloatAgain = root->appendNew<Value>(proc, DoubleToFloat, Origin(), asDouble);
- root->appendNew<MemoryValue>(proc, Store, Origin(), asFloatAgain, dst);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- float input = value;
- float output = 0.;
- CHECK(!compileAndRun<int64_t>(proc, &input, &output));
- CHECK(isIdentical(input, output));
-}
-
-void testFroundArg(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
-
- CHECK(isIdentical(compileAndRun<double>(proc, value), static_cast<double>(static_cast<float>(value))));
-}
-
-void testFroundMem(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* loadedDouble = root->appendNew<MemoryValue>(proc, Load, Double, Origin(), address);
- Value* asFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), loadedDouble);
- Value* asDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), asFloat);
- root->appendNew<ControlValue>(proc, Return, Origin(), asDouble);
-
- CHECK(isIdentical(compileAndRun<double>(proc, &value), static_cast<double>(static_cast<float>(value))));
-}
-
-void testStore32(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 0xbaadbeef;
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, value));
- CHECK(slot == value);
-}
-
-void testStoreConstant(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 0xbaadbeef;
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value),
- root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == value);
-}
-
-void testStoreConstantPtr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- intptr_t slot;
- if (is64Bit())
- slot = (static_cast<intptr_t>(0xbaadbeef) << 32) + static_cast<intptr_t>(0xbaadbeef);
- else
- slot = 0xbaadbeef;
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), value),
- root->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == value);
-}
-
-void testStore8Arg()
-{
- { // Direct addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
-
- root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int8_t storage = 0;
- CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
- CHECK(storage == 42);
- }
-
- { // Indexed addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
-
- Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
- Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
-
- root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int8_t storage = 0;
- CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
- CHECK(storage == 42);
- }
-}
-
-void testStore8Imm()
-{
- { // Direct addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int8_t storage = 0;
- CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
- CHECK(storage == 42);
- }
-
- { // Indexed addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
-
- Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
- Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
-
- root->appendNew<MemoryValue>(proc, Store8, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int8_t storage = 0;
- CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
- CHECK(storage == 42);
- }
-}
-
-void testStorePartial8BitRegisterOnX86()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- // We want to have this in ECX.
- Value* returnValue = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- // We want this suck in EDX.
- Value* whereToStore = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
-
- // The patch point is there to help us force the hand of the compiler.
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
-
- // For the value above to be materialized and give the allocator
- // a stronger insentive to name those register the way we need.
- patchpoint->append(ConstrainedValue(returnValue, ValueRep(GPRInfo::regT3)));
- patchpoint->append(ConstrainedValue(whereToStore, ValueRep(GPRInfo::regT2)));
-
- // We'll produce EDI.
- patchpoint->resultConstraint = ValueRep::reg(GPRInfo::regT6);
-
- // Give the allocator a good reason not to use any other register.
- RegisterSet clobberSet = RegisterSet::allGPRs();
- clobberSet.exclude(RegisterSet::stackRegisters());
- clobberSet.exclude(RegisterSet::reservedHardwareRegisters());
- clobberSet.clear(GPRInfo::regT3);
- clobberSet.clear(GPRInfo::regT2);
- clobberSet.clear(GPRInfo::regT6);
- patchpoint->clobberLate(clobberSet);
-
- // Set EDI.
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.xor64(params[0].gpr(), params[0].gpr());
- });
-
- // If everything went well, we should have the big number in eax,
- // patchpoint == EDI and whereToStore = EDX.
- // Since EDI == 5, and AH = 5 on 8 bit store, this would go wrong
- // if we use X86 partial registers.
- root->appendNew<MemoryValue>(proc, Store8, Origin(), patchpoint, whereToStore);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), returnValue);
-
- int8_t storage = 0xff;
- CHECK(compileAndRun<int64_t>(proc, 0x12345678abcdef12, &storage) == 0x12345678abcdef12);
- CHECK(!storage);
-}
-
-void testStore16Arg()
-{
- { // Direct addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
-
- root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int16_t storage = -1;
- CHECK(compileAndRun<int64_t>(proc, 42, &storage) == 42);
- CHECK(storage == 42);
- }
-
- { // Indexed addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
- Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
-
- Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
- Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
-
- root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int16_t storage = -1;
- CHECK(compileAndRun<int64_t>(proc, 42, &storage, 1) == 42);
- CHECK(storage == 42);
- }
-}
-
-void testStore16Imm()
-{
- { // Direct addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
- Value* address = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int16_t storage = -1;
- CHECK(compileAndRun<int64_t>(proc, &storage) == 42);
- CHECK(storage == 42);
- }
-
- { // Indexed addressing.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* value = root->appendNew<Const32Value>(proc, Origin(), 42);
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* displacement = root->appendNew<Const64Value>(proc, Origin(), -1);
-
- Value* baseDisplacement = root->appendNew<Value>(proc, Add, Origin(), displacement, base);
- Value* address = root->appendNew<Value>(proc, Add, Origin(), baseDisplacement, offset);
-
- root->appendNew<MemoryValue>(proc, Store16, Origin(), value, address);
- root->appendNew<ControlValue>(proc, Return, Origin(), value);
-
- int16_t storage = -1;
- CHECK(compileAndRun<int64_t>(proc, &storage, 1) == 42);
- CHECK(storage == 42);
- }
-}
-
-void testTrunc(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<int>(proc, value) == static_cast<int>(value));
-}
-
-void testAdd1(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- CHECK(compileAndRun<int>(proc, value) == value + 1);
-}
-
-void testAdd1Ptr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ConstPtrValue>(proc, Origin(), 1)));
-
- CHECK(compileAndRun<intptr_t>(proc, value) == value + 1);
-}
-
-void testNeg32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == -value);
-}
-
-void testNegPtr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), 0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(compileAndRun<intptr_t>(proc, value) == -value);
-}
-
-void testStoreAddLoad32(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm32(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad8(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int8_t slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store8, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm8(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int8_t slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store8, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad16(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int16_t slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store16, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm16(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int16_t slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store16, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad64(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int64_t slot = 37000000000ll;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), slotPtr),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37000000000ll + amount);
-}
-
-void testStoreAddLoadImm64(int64_t amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int64_t slot = 370000000000ll;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), slotPtr),
- root->appendNew<Const64Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 370000000000ll + amount);
-}
-
-void testStoreAddLoad32Index(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- int* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm32Index(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- int* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad8Index(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int8_t slot = 37;
- int8_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store8, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm8Index(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int8_t slot = 37;
- int8_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store8, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad16Index(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int16_t slot = 37;
- int16_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store16, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoadImm16Index(int amount, B3::Opcode loadOpcode)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int16_t slot = 37;
- int16_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store16, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, loadOpcode, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddLoad64Index(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int64_t slot = 37000000000ll;
- int64_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), slotPtr),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == 37000000000ll + amount);
-}
-
-void testStoreAddLoadImm64Index(int64_t amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int64_t slot = 370000000000ll;
- int64_t* ptr = &slot;
- intptr_t zero = 0;
- Value* slotPtr = root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &ptr)),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &zero)));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int64, Origin(), slotPtr),
- root->appendNew<Const64Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == 370000000000ll + amount);
-}
-
-void testStoreSubLoad(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int32_t startValue = std::numeric_limits<int32_t>::min();
- int32_t slot = startValue;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, amount));
- CHECK(slot == startValue - amount);
-}
-
-void testStoreAddLoadInterference(int amount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- ArgumentRegValue* otherSlotPtr =
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- MemoryValue* load = root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 666),
- otherSlotPtr);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- load, root->appendNew<Const32Value>(proc, Origin(), amount)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc, &slot));
- CHECK(slot == 37 + amount);
-}
-
-void testStoreAddAndLoad(int amount, int mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slot = 37;
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr),
- root->appendNew<Const32Value>(proc, Origin(), amount)),
- root->appendNew<Const32Value>(proc, Origin(), mask)),
- slotPtr);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
- CHECK(slot == ((37 + amount) & mask));
-}
-
-void testStoreNegLoad32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- int32_t slot = value;
-
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
-
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), slotPtr)),
- slotPtr);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int32_t>(proc));
- CHECK(slot == -value);
-}
-
-void testStoreNegLoadPtr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- intptr_t slot = value;
-
- ConstPtrValue* slotPtr = root->appendNew<ConstPtrValue>(proc, Origin(), &slot);
-
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Sub, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), 0),
- root->appendNew<MemoryValue>(proc, Load, pointerType(), Origin(), slotPtr)),
- slotPtr);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int32_t>(proc));
- CHECK(slot == -value);
-}
-
-void testAdd1Uncommuted(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 1),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int>(proc, value) == value + 1);
-}
-
-void testLoadOffset()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int array[] = { 1, 2 };
- ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
-
- CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
-}
-
-void testLoadOffsetNotConstant()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int array[] = { 1, 2 };
- Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, 0),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), arrayPtr, sizeof(int))));
-
- CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
-}
-
-void testLoadOffsetUsingAdd()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int array[] = { 1, 2 };
- ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
-
- CHECK(compileAndRun<int>(proc) == array[0] + array[1]);
-}
-
-void testLoadOffsetUsingAddInterference()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int array[] = { 1, 2 };
- ConstPtrValue* arrayPtr = root->appendNew<ConstPtrValue>(proc, Origin(), array);
- ArgumentRegValue* otherArrayPtr =
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Const32Value* theNumberOfTheBeast = root->appendNew<Const32Value>(proc, Origin(), 666);
- MemoryValue* left = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), 0)));
- MemoryValue* right = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))));
- root->appendNew<MemoryValue>(
- proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, 0);
- root->appendNew<MemoryValue>(
- proc, Store, Origin(), theNumberOfTheBeast, otherArrayPtr, sizeof(int));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), left, right));
-
- CHECK(compileAndRun<int>(proc, &array[0]) == 1 + 2);
- CHECK(array[0] == 666);
- CHECK(array[1] == 666);
-}
-
-void testLoadOffsetUsingAddNotConstant()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int array[] = { 1, 2 };
- Value* arrayPtr = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), 0))),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(), arrayPtr,
- root->appendNew<ConstPtrValue>(proc, Origin(), sizeof(int))))));
-
- CHECK(compileAndRun<int>(proc, &array[0]) == array[0] + array[1]);
-}
-
-void testLoadAddrShift(unsigned shift)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- int slots[2];
-
- // Figure out which slot to use while having proper alignment for the shift.
- int* slot;
- uintptr_t arg;
- for (unsigned i = sizeof(slots)/sizeof(slots[0]); i--;) {
- slot = slots + i;
- arg = bitwise_cast<uintptr_t>(slot) >> shift;
- if (bitwise_cast<int*>(arg << shift) == slot)
- break;
- }
-
- *slot = 8675309;
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), shift))));
-
- CHECK(compileAndRun<int>(proc, arg) == 8675309);
-}
-
-void testFramePointer()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, FramePointer, Origin()));
-
- void* fp = compileAndRun<void*>(proc);
- CHECK(fp < &proc);
- CHECK(fp >= bitwise_cast<char*>(&proc) - 10000);
-}
-
-void testOverrideFramePointer()
-{
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- // Add a stack slot to make the frame non trivial.
- root->appendNew<SlotBaseValue>(proc, Origin(), proc.addStackSlot(8));
-
- // Sub on x86 UseDef the source. If FP is not protected correctly, it will be overridden since it is the last visible use.
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* fp = root->appendNew<Value>(proc, FramePointer, Origin());
- Value* result = root->appendNew<Value>(proc, Sub, Origin(), fp, offset);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- CHECK(compileAndRun<int64_t>(proc, 1));
- }
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<SlotBaseValue>(proc, Origin(), proc.addStackSlot(8));
-
- Value* offset = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* fp = root->appendNew<Value>(proc, FramePointer, Origin());
- Value* offsetFP = root->appendNew<Value>(proc, BitAnd, Origin(), offset, fp);
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* offsetArg = root->appendNew<Value>(proc, Add, Origin(), offset, arg);
- Value* result = root->appendNew<Value>(proc, Add, Origin(), offsetArg, offsetFP);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- CHECK(compileAndRun<int64_t>(proc, 1, 2));
- }
-}
-
-void testStackSlot()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<SlotBaseValue>(proc, Origin(), proc.addStackSlot(1)));
-
- void* stackSlot = compileAndRun<void*>(proc);
- CHECK(stackSlot < &proc);
- CHECK(stackSlot >= bitwise_cast<char*>(&proc) - 10000);
-}
-
-void testLoadFromFramePointer()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<Value>(proc, FramePointer, Origin())));
-
- void* fp = compileAndRun<void*>(proc);
- void* myFP = __builtin_frame_address(0);
- CHECK(fp <= myFP);
- CHECK(fp >= bitwise_cast<char*>(myFP) - 10000);
-}
-
-void testStoreLoadStackSlot(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- SlotBaseValue* stack =
- root->appendNew<SlotBaseValue>(proc, Origin(), proc.addStackSlot(sizeof(int)));
-
- root->appendNew<MemoryValue>(
- proc, Store, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- stack);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(proc, Load, Int32, Origin(), stack));
-
- CHECK(compileAndRun<int>(proc, value) == value);
-}
-
-template<typename LoadedType, typename EffectiveType>
-EffectiveType modelLoad(EffectiveType value)
-{
- union {
- EffectiveType original;
- LoadedType loaded;
- } u;
-
- u.original = value;
- if (std::is_signed<LoadedType>::value)
- return static_cast<EffectiveType>(u.loaded);
- return static_cast<EffectiveType>(static_cast<typename std::make_unsigned<EffectiveType>::type>(u.loaded));
-}
-
-template<>
-float modelLoad<float, float>(float value) { return value; }
-
-template<>
-double modelLoad<double, double>(double value) { return value; }
-
-template<B3::Type type, typename CType, typename InputType>
-void testLoad(B3::Opcode opcode, InputType value)
-{
- // Simple load from an absolute address.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, opcode, type, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &value)));
-
- CHECK(isIdentical(compileAndRun<CType>(proc), modelLoad<CType>(value)));
- }
-
- // Simple load from an address in a register.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, opcode, type, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
-
- CHECK(isIdentical(compileAndRun<CType>(proc, &value), modelLoad<CType>(value)));
- }
-
- // Simple load from an address in a register, at an offset.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, opcode, type, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- sizeof(InputType)));
-
- CHECK(isIdentical(compileAndRun<CType>(proc, &value - 1), modelLoad<CType>(value)));
- }
-
- // Load from a simple base-index with various scales.
- for (unsigned logScale = 0; logScale <= 3; ++logScale) {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, opcode, type, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<Const32Value>(proc, Origin(), logScale)))));
-
- CHECK(isIdentical(compileAndRun<CType>(proc, &value - 2, (sizeof(InputType) * 2) >> logScale), modelLoad<CType>(value)));
- }
-
- // Load from a simple base-index with various scales, but commuted.
- for (unsigned logScale = 0; logScale <= 3; ++logScale) {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(
- proc, opcode, type, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<Const32Value>(proc, Origin(), logScale)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(isIdentical(compileAndRun<CType>(proc, &value - 2, (sizeof(InputType) * 2) >> logScale), modelLoad<CType>(value)));
- }
-}
-
-template<typename T>
-void testLoad(B3::Opcode opcode, int32_t value)
-{
- return testLoad<Int32, T>(opcode, value);
-}
-
-template<B3::Type type, typename T>
-void testLoad(T value)
-{
- return testLoad<type, T>(Load, value);
-}
-
-void testStoreFloat(double input)
-{
- // Simple store from an address in a register.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentAsFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
-
- Value* destinationAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<MemoryValue>(proc, Store, Origin(), argumentAsFloat, destinationAddress);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- float output = 0.;
- CHECK(!compileAndRun<int64_t>(proc, input, &output));
- CHECK(isIdentical(static_cast<float>(input), output));
- }
-
- // Simple indexed store.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentAsFloat = root->appendNew<Value>(proc, DoubleToFloat, Origin(), argument);
-
- Value* destinationBaseAddress = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* index = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* scaledIndex = root->appendNew<Value>(
- proc, Shl, Origin(),
- index,
- root->appendNew<Const32Value>(proc, Origin(), 2));
- Value* destinationAddress = root->appendNew<Value>(proc, Add, Origin(), scaledIndex, destinationBaseAddress);
-
- root->appendNew<MemoryValue>(proc, Store, Origin(), argumentAsFloat, destinationAddress);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- float output = 0.;
- CHECK(!compileAndRun<int64_t>(proc, input, &output - 1, 1));
- CHECK(isIdentical(static_cast<float>(input), output));
- }
-}
-
-void testSpillGP()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Vector<Value*> sources;
- sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
-
- for (unsigned i = 0; i < 30; ++i) {
- sources.append(
- root->appendNew<Value>(proc, Add, Origin(), sources[sources.size() - 1], sources[sources.size() - 2])
- );
- }
-
- Value* total = root->appendNew<Const64Value>(proc, Origin(), 0);
- for (Value* value : sources)
- total = root->appendNew<Value>(proc, Add, Origin(), total, value);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), total);
- compileAndRun<int>(proc, 1, 2);
-}
-
-void testSpillFP()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Vector<Value*> sources;
- sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0));
- sources.append(root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1));
-
- for (unsigned i = 0; i < 30; ++i) {
- sources.append(
- root->appendNew<Value>(proc, Add, Origin(), sources[sources.size() - 1], sources[sources.size() - 2])
- );
- }
-
- Value* total = root->appendNew<ConstDoubleValue>(proc, Origin(), 0.);
- for (Value* value : sources)
- total = root->appendNew<Value>(proc, Add, Origin(), total, value);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), total);
- compileAndRun<double>(proc, 1.1, 2.5);
-}
-
-void testInt32ToDoublePartialRegisterStall()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* loop = proc.addBlock();
- BasicBlock* done = proc.addBlock();
-
- // Head.
- Value* total = root->appendNew<ConstDoubleValue>(proc, Origin(), 0.);
- Value* counter = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- UpsilonValue* originalTotal = root->appendNew<UpsilonValue>(proc, Origin(), total);
- UpsilonValue* originalCounter = root->appendNew<UpsilonValue>(proc, Origin(), counter);
- root->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loop));
-
- // Loop.
- Value* loopCounter = loop->appendNew<Value>(proc, Phi, Int64, Origin());
- Value* loopTotal = loop->appendNew<Value>(proc, Phi, Double, Origin());
- originalCounter->setPhi(loopCounter);
- originalTotal->setPhi(loopTotal);
-
- Value* truncatedCounter = loop->appendNew<Value>(proc, Trunc, Origin(), loopCounter);
- Value* doubleCounter = loop->appendNew<Value>(proc, IToD, Origin(), truncatedCounter);
- Value* updatedTotal = loop->appendNew<Value>(proc, Add, Origin(), doubleCounter, loopTotal);
- UpsilonValue* updatedTotalUpsilon = loop->appendNew<UpsilonValue>(proc, Origin(), updatedTotal);
- updatedTotalUpsilon->setPhi(loopTotal);
-
- Value* decCounter = loop->appendNew<Value>(proc, Sub, Origin(), loopCounter, loop->appendNew<Const64Value>(proc, Origin(), 1));
- UpsilonValue* decCounterUpsilon = loop->appendNew<UpsilonValue>(proc, Origin(), decCounter);
- decCounterUpsilon->setPhi(loopCounter);
- loop->appendNew<ControlValue>(
- proc, Branch, Origin(),
- decCounter,
- FrequentedBlock(loop), FrequentedBlock(done));
-
- // Tail.
- done->appendNew<ControlValue>(proc, Return, Origin(), updatedTotal);
- CHECK(isIdentical(compileAndRun<double>(proc, 100000), 5000050000.));
-}
-
-void testInt32ToDoublePartialRegisterWithoutStall()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* loop = proc.addBlock();
- BasicBlock* done = proc.addBlock();
-
- // Head.
- Value* total = root->appendNew<ConstDoubleValue>(proc, Origin(), 0.);
- Value* counter = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- UpsilonValue* originalTotal = root->appendNew<UpsilonValue>(proc, Origin(), total);
- UpsilonValue* originalCounter = root->appendNew<UpsilonValue>(proc, Origin(), counter);
- uint64_t forPaddingInput;
- Value* forPaddingInputAddress = root->appendNew<ConstPtrValue>(proc, Origin(), &forPaddingInput);
- uint64_t forPaddingOutput;
- Value* forPaddingOutputAddress = root->appendNew<ConstPtrValue>(proc, Origin(), &forPaddingOutput);
- root->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loop));
-
- // Loop.
- Value* loopCounter = loop->appendNew<Value>(proc, Phi, Int64, Origin());
- Value* loopTotal = loop->appendNew<Value>(proc, Phi, Double, Origin());
- originalCounter->setPhi(loopCounter);
- originalTotal->setPhi(loopTotal);
-
- Value* truncatedCounter = loop->appendNew<Value>(proc, Trunc, Origin(), loopCounter);
- Value* doubleCounter = loop->appendNew<Value>(proc, IToD, Origin(), truncatedCounter);
- Value* updatedTotal = loop->appendNew<Value>(proc, Add, Origin(), doubleCounter, loopTotal);
-
- // Add enough padding instructions to avoid a stall.
- Value* loadPadding = loop->appendNew<MemoryValue>(proc, Load, Int64, Origin(), forPaddingInputAddress);
- Value* padding = loop->appendNew<Value>(proc, BitXor, Origin(), loadPadding, loopCounter);
- padding = loop->appendNew<Value>(proc, Add, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, BitOr, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, Sub, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, BitXor, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, Add, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, BitOr, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, Sub, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, BitXor, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, Add, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, BitOr, Origin(), padding, loopCounter);
- padding = loop->appendNew<Value>(proc, Sub, Origin(), padding, loopCounter);
- loop->appendNew<MemoryValue>(proc, Store, Origin(), padding, forPaddingOutputAddress);
-
- UpsilonValue* updatedTotalUpsilon = loop->appendNew<UpsilonValue>(proc, Origin(), updatedTotal);
- updatedTotalUpsilon->setPhi(loopTotal);
-
- Value* decCounter = loop->appendNew<Value>(proc, Sub, Origin(), loopCounter, loop->appendNew<Const64Value>(proc, Origin(), 1));
- UpsilonValue* decCounterUpsilon = loop->appendNew<UpsilonValue>(proc, Origin(), decCounter);
- decCounterUpsilon->setPhi(loopCounter);
- loop->appendNew<ControlValue>(
- proc, Branch, Origin(),
- decCounter,
- FrequentedBlock(loop), FrequentedBlock(done));
-
- // Tail.
- done->appendNew<ControlValue>(proc, Return, Origin(), updatedTotal);
- CHECK(isIdentical(compileAndRun<double>(proc, 100000), 5000050000.));
-}
-
-void testBranch()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchPtr()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, static_cast<intptr_t>(42)) == 1);
- CHECK(invoke<int>(*code, static_cast<intptr_t>(0)) == 0);
-}
-
-void testDiamond()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
- BasicBlock* done = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
- proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
- thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
-
- UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
- proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
- elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
-
- Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
- thenResult->setPhi(phi);
- elseResult->setPhi(phi);
- done->appendNew<ControlValue>(proc, Return, Origin(), phi);
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchNotEqual()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchNotEqualCommute()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchNotEqualNotEqual()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchEqual()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchEqualEqual()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchEqualCommute()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchEqualEqual1()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- root->appendNew<Const32Value>(proc, Origin(), 1)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- auto code = compile(proc);
- CHECK(invoke<int>(*code, 42) == 1);
- CHECK(invoke<int>(*code, 0) == 0);
-}
-
-void testBranchEqualOrUnorderedArgs(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
-}
-
-void testBranchEqualOrUnorderedArgs(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentB = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, &a, &b) == expected);
-}
-
-void testBranchNotEqualAndOrderedArgs(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentB = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* equalOrUnordered = root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB);
- Value* notEqualAndOrdered = root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- equalOrUnordered);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- notEqualAndOrdered,
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (!std::isunordered(a, b) && a != b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, a, b) == expected);
-}
-
-void testBranchNotEqualAndOrderedArgs(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentB = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* equalOrUnordered = root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB);
- Value* notEqualAndOrdered = root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0),
- equalOrUnordered);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- notEqualAndOrdered,
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (!std::isunordered(a, b) && a != b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, &a, &b) == expected);
-}
-
-void testBranchEqualOrUnorderedDoubleArgImm(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, a) == expected);
-}
-
-void testBranchEqualOrUnorderedFloatArgImm(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, &a) == expected);
-}
-
-void testBranchEqualOrUnorderedDoubleImms(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<ConstDoubleValue>(proc, Origin(), a);
- Value* argumentB = root->appendNew<ConstDoubleValue>(proc, Origin(), b);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc) == expected);
-}
-
-void testBranchEqualOrUnorderedFloatImms(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argumentA = root->appendNew<ConstFloatValue>(proc, Origin(), a);
- Value* argumentB = root->appendNew<ConstFloatValue>(proc, Origin(), b);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argumentA,
- argumentB),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc) == expected);
-}
-
-void testBranchEqualOrUnorderedFloatWithUselessDoubleConversion(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* argument1 = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2 = root->appendNew<MemoryValue>(proc, Load, Float, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* argument1AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument1);
- Value* argument2AsDouble = root->appendNew<Value>(proc, FloatToDouble, Origin(), argument2);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, EqualOrUnordered, Origin(),
- argument1AsDouble,
- argument2AsDouble),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 42));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), -13));
-
- int64_t expected = (std::isunordered(a, b) || a == b) ? 42 : -13;
- CHECK(compileAndRun<int64_t>(proc, &a, &b) == expected);
-}
-
-void testBranchFold(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(compileAndRun<int>(proc) == !!value);
-}
-
-void testDiamondFold(int value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
- BasicBlock* done = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- UpsilonValue* thenResult = thenCase->appendNew<UpsilonValue>(
- proc, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 1));
- thenCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
-
- UpsilonValue* elseResult = elseCase->appendNew<UpsilonValue>(
- proc, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 0));
- elseCase->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(done));
-
- Value* phi = done->appendNew<Value>(proc, Phi, Int32, Origin());
- thenResult->setPhi(phi);
- elseResult->setPhi(phi);
- done->appendNew<ControlValue>(proc, Return, Origin(), phi);
-
- CHECK(compileAndRun<int>(proc) == !!value);
-}
-
-void testBranchNotEqualFoldPtr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), value),
- root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(compileAndRun<int>(proc) == !!value);
-}
-
-void testBranchEqualFoldPtr(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), value),
- root->appendNew<ConstPtrValue>(proc, Origin(), 0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(compileAndRun<int>(proc) == !value);
-}
-
-void testBranchLoadPtr()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- intptr_t cond;
- cond = 42;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testBranchLoad32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- int32_t cond;
- cond = 42;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testBranchLoad8S()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load8S, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- int8_t cond;
- cond = -1;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testBranchLoad8Z()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- uint8_t cond;
- cond = 1;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testBranchLoad16S()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load16S, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- int16_t cond;
- cond = -1;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testBranchLoad16Z()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<MemoryValue>(
- proc, Load16Z, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<Const32Value>(proc, Origin(), 1));
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- uint16_t cond;
- cond = 1;
- CHECK(invoke<int>(*code, &cond) == 1);
- cond = 0;
- CHECK(invoke<int>(*code, &cond) == 0);
-}
-
-void testComplex(unsigned numVars, unsigned numConstructs)
-{
- double before = monotonicallyIncreasingTimeMS();
-
- Procedure proc;
- BasicBlock* current = proc.addBlock();
-
- Const32Value* one = current->appendNew<Const32Value>(proc, Origin(), 1);
-
- Vector<int32_t> varSlots;
- for (unsigned i = numVars; i--;)
- varSlots.append(i);
-
- Vector<Value*> vars;
- for (int32_t& varSlot : varSlots) {
- Value* varSlotPtr = current->appendNew<ConstPtrValue>(proc, Origin(), &varSlot);
- vars.append(current->appendNew<MemoryValue>(proc, Load, Int32, Origin(), varSlotPtr));
- }
-
- for (unsigned i = 0; i < numConstructs; ++i) {
- if (i & 1) {
- // Control flow diamond.
- unsigned predicateVarIndex = ((i >> 1) + 2) % numVars;
- unsigned thenIncVarIndex = ((i >> 1) + 0) % numVars;
- unsigned elseIncVarIndex = ((i >> 1) + 1) % numVars;
-
- BasicBlock* thenBlock = proc.addBlock();
- BasicBlock* elseBlock = proc.addBlock();
- BasicBlock* continuation = proc.addBlock();
-
- current->appendNew<ControlValue>(
- proc, Branch, Origin(), vars[predicateVarIndex],
- FrequentedBlock(thenBlock), FrequentedBlock(elseBlock));
-
- UpsilonValue* thenThenResult = thenBlock->appendNew<UpsilonValue>(
- proc, Origin(),
- thenBlock->appendNew<Value>(proc, Add, Origin(), vars[thenIncVarIndex], one));
- UpsilonValue* thenElseResult = thenBlock->appendNew<UpsilonValue>(
- proc, Origin(), vars[elseIncVarIndex]);
- thenBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
-
- UpsilonValue* elseElseResult = elseBlock->appendNew<UpsilonValue>(
- proc, Origin(),
- elseBlock->appendNew<Value>(proc, Add, Origin(), vars[elseIncVarIndex], one));
- UpsilonValue* elseThenResult = elseBlock->appendNew<UpsilonValue>(
- proc, Origin(), vars[thenIncVarIndex]);
- elseBlock->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
-
- Value* thenPhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
- thenThenResult->setPhi(thenPhi);
- elseThenResult->setPhi(thenPhi);
- vars[thenIncVarIndex] = thenPhi;
-
- Value* elsePhi = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
- thenElseResult->setPhi(elsePhi);
- elseElseResult->setPhi(elsePhi);
- vars[elseIncVarIndex] = thenPhi;
-
- current = continuation;
- } else {
- // Loop.
-
- BasicBlock* loopEntry = proc.addBlock();
- BasicBlock* loopReentry = proc.addBlock();
- BasicBlock* loopBody = proc.addBlock();
- BasicBlock* loopExit = proc.addBlock();
- BasicBlock* loopSkip = proc.addBlock();
- BasicBlock* continuation = proc.addBlock();
-
- Value* startIndex = vars[((i >> 1) + 1) % numVars];
- Value* startSum = current->appendNew<Const32Value>(proc, Origin(), 0);
- current->appendNew<ControlValue>(
- proc, Branch, Origin(), startIndex,
- FrequentedBlock(loopEntry), FrequentedBlock(loopSkip));
-
- UpsilonValue* startIndexForBody = loopEntry->appendNew<UpsilonValue>(
- proc, Origin(), startIndex);
- UpsilonValue* startSumForBody = loopEntry->appendNew<UpsilonValue>(
- proc, Origin(), startSum);
- loopEntry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
-
- Value* bodyIndex = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
- startIndexForBody->setPhi(bodyIndex);
- Value* bodySum = loopBody->appendNew<Value>(proc, Phi, Int32, Origin());
- startSumForBody->setPhi(bodySum);
- Value* newBodyIndex = loopBody->appendNew<Value>(proc, Sub, Origin(), bodyIndex, one);
- Value* newBodySum = loopBody->appendNew<Value>(
- proc, Add, Origin(),
- bodySum,
- loopBody->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- loopBody->appendNew<Value>(
- proc, Add, Origin(),
- loopBody->appendNew<ConstPtrValue>(proc, Origin(), varSlots.data()),
- loopBody->appendNew<Value>(
- proc, Shl, Origin(),
- loopBody->appendNew<Value>(
- proc, ZExt32, Origin(),
- loopBody->appendNew<Value>(
- proc, BitAnd, Origin(),
- newBodyIndex,
- loopBody->appendNew<Const32Value>(
- proc, Origin(), numVars - 1))),
- loopBody->appendNew<Const32Value>(proc, Origin(), 2)))));
- loopBody->appendNew<ControlValue>(
- proc, Branch, Origin(), newBodyIndex,
- FrequentedBlock(loopReentry), FrequentedBlock(loopExit));
-
- loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodyIndex, bodyIndex);
- loopReentry->appendNew<UpsilonValue>(proc, Origin(), newBodySum, bodySum);
- loopReentry->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loopBody));
-
- UpsilonValue* exitSum = loopExit->appendNew<UpsilonValue>(proc, Origin(), newBodySum);
- loopExit->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
-
- UpsilonValue* skipSum = loopSkip->appendNew<UpsilonValue>(proc, Origin(), startSum);
- loopSkip->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(continuation));
-
- Value* finalSum = continuation->appendNew<Value>(proc, Phi, Int32, Origin());
- exitSum->setPhi(finalSum);
- skipSum->setPhi(finalSum);
-
- current = continuation;
- vars[((i >> 1) + 0) % numVars] = finalSum;
- }
- }
-
- current->appendNew<ControlValue>(proc, Return, Origin(), vars[0]);
-
- compile(proc);
-
- double after = monotonicallyIncreasingTimeMS();
- dataLog(toCString(" That took ", after - before, " ms.\n"));
-}
-
-void testSimplePatchpoint()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testSimplePatchpointWithoutOuputClobbersGPArgs()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* const1 = root->appendNew<Const64Value>(proc, Origin(), 42);
- Value* const2 = root->appendNew<Const64Value>(proc, Origin(), 13);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
- patchpoint->clobberLate(RegisterSet(GPRInfo::argumentGPR0, GPRInfo::argumentGPR1));
- patchpoint->append(ConstrainedValue(const1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(const2, ValueRep::SomeRegister));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params[0].gpr());
- jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), params[1].gpr());
- jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), GPRInfo::argumentGPR0);
- jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), GPRInfo::argumentGPR1);
- });
-
- Value* result = root->appendNew<Value>(proc, Add, Origin(), arg1, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testSimplePatchpointWithOuputClobbersGPArgs()
-{
- // We can't predict where the output will be but we want to be sure it is not
- // one of the clobbered registers which is a bit hard to test.
- //
- // What we do is force the hand of our register allocator by clobbering absolutely
- // everything but 1. The only valid allocation is to give it to the result and
- // spill everything else.
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* const1 = root->appendNew<Const64Value>(proc, Origin(), 42);
- Value* const2 = root->appendNew<Const64Value>(proc, Origin(), 13);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int64, Origin());
-
- RegisterSet clobberAll = RegisterSet::allGPRs();
- clobberAll.exclude(RegisterSet::stackRegisters());
- clobberAll.exclude(RegisterSet::reservedHardwareRegisters());
- clobberAll.clear(GPRInfo::argumentGPR2);
- patchpoint->clobberLate(clobberAll);
-
- patchpoint->append(ConstrainedValue(const1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(const2, ValueRep::SomeRegister));
-
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- jit.move(params[1].gpr(), params[0].gpr());
- jit.add64(params[2].gpr(), params[0].gpr());
-
- clobberAll.forEach([&] (Reg reg) {
- jit.move(CCallHelpers::TrustedImm32(0x00ff00ff), reg.gpr());
- });
- });
-
- Value* result = root->appendNew<Value>(proc, Add, Origin(), patchpoint,
- root->appendNew<Value>(proc, Add, Origin(), arg1, arg2));
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 58);
-}
-
-void testSimplePatchpointWithoutOuputClobbersFPArgs()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* const1 = root->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
- Value* const2 = root->appendNew<ConstDoubleValue>(proc, Origin(), 13.1);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
- patchpoint->clobberLate(RegisterSet(FPRInfo::argumentFPR0, FPRInfo::argumentFPR1));
- patchpoint->append(ConstrainedValue(const1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(const2, ValueRep::SomeRegister));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isFPR());
- CHECK(params[1].isFPR());
- jit.moveZeroToDouble(params[0].fpr());
- jit.moveZeroToDouble(params[1].fpr());
- jit.moveZeroToDouble(FPRInfo::argumentFPR0);
- jit.moveZeroToDouble(FPRInfo::argumentFPR1);
- });
-
- Value* result = root->appendNew<Value>(proc, Add, Origin(), arg1, arg2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<double>(proc, 1.5, 2.5) == 4);
-}
-
-void testSimplePatchpointWithOuputClobbersFPArgs()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* const1 = root->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
- Value* const2 = root->appendNew<ConstDoubleValue>(proc, Origin(), 13.1);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Double, Origin());
-
- RegisterSet clobberAll = RegisterSet::allFPRs();
- clobberAll.exclude(RegisterSet::stackRegisters());
- clobberAll.exclude(RegisterSet::reservedHardwareRegisters());
- clobberAll.clear(FPRInfo::argumentFPR2);
- patchpoint->clobberLate(clobberAll);
-
- patchpoint->append(ConstrainedValue(const1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(const2, ValueRep::SomeRegister));
-
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isFPR());
- CHECK(params[1].isFPR());
- CHECK(params[2].isFPR());
- jit.addDouble(params[1].fpr(), params[2].fpr(), params[0].fpr());
-
- clobberAll.forEach([&] (Reg reg) {
- jit.moveZeroToDouble(reg.fpr());
- });
- });
-
- Value* result = root->appendNew<Value>(proc, Add, Origin(), patchpoint,
- root->appendNew<Value>(proc, Add, Origin(), arg1, arg2));
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<double>(proc, 1.5, 2.5) == 59.6);
-}
-
-void testPatchpointWithEarlyClobber()
-{
- auto test = [] (GPRReg registerToClobber, bool arg1InArgGPR, bool arg2InArgGPR) {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- patchpoint->clobberEarly(RegisterSet(registerToClobber));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- CHECK((params[1].gpr() == GPRInfo::argumentGPR0) == arg1InArgGPR);
- CHECK((params[2].gpr() == GPRInfo::argumentGPR1) == arg2InArgGPR);
-
- add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
- });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
- };
-
- test(GPRInfo::nonArgGPR0, true, true);
- test(GPRInfo::argumentGPR0, false, true);
- test(GPRInfo::argumentGPR1, true, false);
-}
-
-void testPatchpointCallArg()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::stackArgument(0)));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::stackArgument(8)));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isStack());
- CHECK(params[2].isStack());
- jit.load32(
- CCallHelpers::Address(GPRInfo::callFrameRegister, params[1].offsetFromFP()),
- params[0].gpr());
- jit.add32(
- CCallHelpers::Address(GPRInfo::callFrameRegister, params[2].offsetFromFP()),
- params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointFixedRegister()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep(GPRInfo::regT0)));
- patchpoint->append(ConstrainedValue(arg2, ValueRep(GPRInfo::regT1)));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1] == ValueRep(GPRInfo::regT0));
- CHECK(params[2] == ValueRep(GPRInfo::regT1));
- add32(jit, GPRInfo::regT0, GPRInfo::regT1, params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointAny(ValueRep rep)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, rep));
- patchpoint->append(ConstrainedValue(arg2, rep));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- // We shouldn't have spilled the inputs, so we assert that they're in registers.
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointGPScratch()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(arg1, ValueRep::SomeRegister);
- patchpoint->append(arg2, ValueRep::SomeRegister);
- patchpoint->numGPScratchRegisters = 2;
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- // We shouldn't have spilled the inputs, so we assert that they're in registers.
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- CHECK(params.gpScratch(0) != InvalidGPRReg);
- CHECK(params.gpScratch(0) != params[0].gpr());
- CHECK(params.gpScratch(0) != params[1].gpr());
- CHECK(params.gpScratch(0) != params[2].gpr());
- CHECK(params.gpScratch(1) != InvalidGPRReg);
- CHECK(params.gpScratch(1) != params.gpScratch(0));
- CHECK(params.gpScratch(1) != params[0].gpr());
- CHECK(params.gpScratch(1) != params[1].gpr());
- CHECK(params.gpScratch(1) != params[2].gpr());
- CHECK(!params.unavailableRegisters().get(params.gpScratch(0)));
- CHECK(!params.unavailableRegisters().get(params.gpScratch(1)));
- add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointFPScratch()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(arg1, ValueRep::SomeRegister);
- patchpoint->append(arg2, ValueRep::SomeRegister);
- patchpoint->numFPScratchRegisters = 2;
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- // We shouldn't have spilled the inputs, so we assert that they're in registers.
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- CHECK(params.fpScratch(0) != InvalidFPRReg);
- CHECK(params.fpScratch(1) != InvalidFPRReg);
- CHECK(params.fpScratch(1) != params.fpScratch(0));
- CHECK(!params.unavailableRegisters().get(params.fpScratch(0)));
- CHECK(!params.unavailableRegisters().get(params.fpScratch(1)));
- add32(jit, params[1].gpr(), params[2].gpr(), params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointLotsOfLateAnys()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Vector<int> things;
- for (unsigned i = 200; i--;)
- things.append(i);
-
- Vector<Value*> values;
- for (int& thing : things) {
- Value* value = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &thing));
- values.append(value);
- }
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->clobber(RegisterSet::macroScratchRegisters());
- for (Value* value : values)
- patchpoint->append(ConstrainedValue(value, ValueRep::LateColdAny));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- // We shouldn't have spilled the inputs, so we assert that they're in registers.
- CHECK(params.size() == things.size() + 1);
- CHECK(params[0].isGPR());
- jit.move(CCallHelpers::TrustedImm32(0), params[0].gpr());
- for (unsigned i = 1; i < params.size(); ++i) {
- if (params[i].isGPR()) {
- CHECK(params[i] != params[0]);
- jit.add32(params[i].gpr(), params[0].gpr());
- } else {
- CHECK(params[i].isStack());
- jit.add32(CCallHelpers::Address(GPRInfo::callFrameRegister, params[i].offsetFromFP()), params[0].gpr());
- }
- }
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc) == (things.size() * (things.size() - 1)) / 2);
-}
-
-void testPatchpointAnyImm(ValueRep rep)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 42);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, rep));
- patchpoint->append(ConstrainedValue(arg2, rep));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- CHECK(params[2].isConstant());
- CHECK(params[2].value() == 42);
- jit.add32(
- CCallHelpers::TrustedImm32(static_cast<int32_t>(params[2].value())),
- params[1].gpr(), params[0].gpr());
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1) == 43);
-}
-
-void testPatchpointManyImms()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), 42);
- Value* arg2 = root->appendNew<Const64Value>(proc, Origin(), 43);
- Value* arg3 = root->appendNew<Const64Value>(proc, Origin(), 43000000000000ll);
- Value* arg4 = root->appendNew<ConstDoubleValue>(proc, Origin(), 42.5);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Void, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::WarmAny));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::WarmAny));
- patchpoint->append(ConstrainedValue(arg3, ValueRep::WarmAny));
- patchpoint->append(ConstrainedValue(arg4, ValueRep::WarmAny));
- patchpoint->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams& params) {
- CHECK(params.size() == 4);
- CHECK(params[0] == ValueRep::constant(42));
- CHECK(params[1] == ValueRep::constant(43));
- CHECK(params[2] == ValueRep::constant(43000000000000ll));
- CHECK(params[3] == ValueRep::constant(bitwise_cast<int64_t>(42.5)));
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(!compileAndRun<int>(proc));
-}
-
-void testPatchpointWithRegisterResult()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- patchpoint->resultConstraint = ValueRep::reg(GPRInfo::nonArgGPR0);
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0] == ValueRep::reg(GPRInfo::nonArgGPR0));
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- add32(jit, params[1].gpr(), params[2].gpr(), GPRInfo::nonArgGPR0);
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointWithStackArgumentResult()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- patchpoint->resultConstraint = ValueRep::stackArgument(0);
- patchpoint->clobber(RegisterSet::macroScratchRegisters());
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0] == ValueRep::stack(-static_cast<intptr_t>(proc.frameSize())));
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- jit.add32(params[1].gpr(), params[2].gpr(), jit.scratchRegister());
- jit.store32(jit.scratchRegister(), CCallHelpers::Address(CCallHelpers::stackPointerRegister, 0));
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<int>(proc, 1, 2) == 3);
-}
-
-void testPatchpointWithAnyResult()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Double, Origin());
- patchpoint->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- patchpoint->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- patchpoint->resultConstraint = ValueRep::WarmAny;
- patchpoint->clobberLate(RegisterSet::allFPRs());
- patchpoint->clobber(RegisterSet::macroScratchRegisters());
- patchpoint->clobber(RegisterSet(GPRInfo::regT0));
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 3);
- CHECK(params[0].isStack());
- CHECK(params[1].isGPR());
- CHECK(params[2].isGPR());
- add32(jit, params[1].gpr(), params[2].gpr(), GPRInfo::regT0);
- jit.convertInt32ToDouble(GPRInfo::regT0, FPRInfo::fpRegT0);
- jit.storeDouble(FPRInfo::fpRegT0, CCallHelpers::Address(GPRInfo::callFrameRegister, params[0].offsetFromFP()));
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- CHECK(compileAndRun<double>(proc, 1, 2) == 3);
-}
-
-void testSimpleCheck()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- CheckValue* check = root->appendNew<CheckValue>(proc, Check, Origin(), arg);
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code, 0) == 0);
- CHECK(invoke<int>(*code, 1) == 42);
-}
-
-void testCheckFalse()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
- check->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams&) {
- CHECK(!"This should not have executed");
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == 0);
-}
-
-void testCheckTrue()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(), root->appendNew<Const32Value>(proc, Origin(), 1));
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.value()->opcode() == Patchpoint);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == 42);
-}
-
-void testCheckLessThan()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(), arg,
- root->appendNew<Const32Value>(proc, Origin(), 42)));
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code, 42) == 0);
- CHECK(invoke<int>(*code, 1000) == 0);
- CHECK(invoke<int>(*code, 41) == 42);
- CHECK(invoke<int>(*code, 0) == 42);
- CHECK(invoke<int>(*code, -1) == 42);
-}
-
-void testCheckMegaCombo()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* index = root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- Value* ptr = root->appendNew<Value>(
- proc, Add, Origin(), base,
- root->appendNew<Value>(
- proc, Shl, Origin(), index,
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<MemoryValue>(proc, Load8S, Origin(), ptr),
- root->appendNew<Const32Value>(proc, Origin(), 42)));
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- int8_t value;
- value = 42;
- CHECK(invoke<int>(*code, &value - 2, 1) == 0);
- value = 127;
- CHECK(invoke<int>(*code, &value - 2, 1) == 0);
- value = 41;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
- value = 0;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
- value = -1;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
-}
-
-void testCheckTrickyMegaCombo()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* index = root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)),
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- Value* ptr = root->appendNew<Value>(
- proc, Add, Origin(), base,
- root->appendNew<Value>(
- proc, Shl, Origin(), index,
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<MemoryValue>(proc, Load8S, Origin(), ptr),
- root->appendNew<Const32Value>(proc, Origin(), 42)));
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- int8_t value;
- value = 42;
- CHECK(invoke<int>(*code, &value - 2, 0) == 0);
- value = 127;
- CHECK(invoke<int>(*code, &value - 2, 0) == 0);
- value = 41;
- CHECK(invoke<int>(*code, &value - 2, 0) == 42);
- value = 0;
- CHECK(invoke<int>(*code, &value - 2, 0) == 42);
- value = -1;
- CHECK(invoke<int>(*code, &value - 2, 0) == 42);
-}
-
-void testCheckTwoMegaCombos()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* index = root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- Value* ptr = root->appendNew<Value>(
- proc, Add, Origin(), base,
- root->appendNew<Value>(
- proc, Shl, Origin(), index,
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- Value* predicate = root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<MemoryValue>(proc, Load8S, Origin(), ptr),
- root->appendNew<Const32Value>(proc, Origin(), 42));
-
- CheckValue* check = root->appendNew<CheckValue>(proc, Check, Origin(), predicate);
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- CheckValue* check2 = root->appendNew<CheckValue>(proc, Check, Origin(), predicate);
- check2->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(43), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(), root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
-
- int8_t value;
- value = 42;
- CHECK(invoke<int>(*code, &value - 2, 1) == 0);
- value = 127;
- CHECK(invoke<int>(*code, &value - 2, 1) == 0);
- value = 41;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
- value = 0;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
- value = -1;
- CHECK(invoke<int>(*code, &value - 2, 1) == 42);
-}
-
-void testCheckTwoNonRedundantMegaCombos()
-{
- Procedure proc;
-
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* base = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* index = root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* branchPredicate = root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
- root->appendNew<Const32Value>(proc, Origin(), 0xff));
-
- Value* ptr = root->appendNew<Value>(
- proc, Add, Origin(), base,
- root->appendNew<Value>(
- proc, Shl, Origin(), index,
- root->appendNew<Const32Value>(proc, Origin(), 1)));
-
- Value* checkPredicate = root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<MemoryValue>(proc, Load8S, Origin(), ptr),
- root->appendNew<Const32Value>(proc, Origin(), 42));
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(), branchPredicate,
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- CheckValue* check = thenCase->appendNew<CheckValue>(proc, Check, Origin(), checkPredicate);
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(), thenCase->appendNew<Const32Value>(proc, Origin(), 43));
-
- CheckValue* check2 = elseCase->appendNew<CheckValue>(proc, Check, Origin(), checkPredicate);
- check2->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(!params.size());
-
- // This should always work because a function this simple should never have callee
- // saves.
- jit.move(CCallHelpers::TrustedImm32(44), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(), elseCase->appendNew<Const32Value>(proc, Origin(), 45));
-
- auto code = compile(proc);
-
- int8_t value;
-
- value = 42;
- CHECK(invoke<int>(*code, &value - 2, 1, true) == 43);
- value = 127;
- CHECK(invoke<int>(*code, &value - 2, 1, true) == 43);
- value = 41;
- CHECK(invoke<int>(*code, &value - 2, 1, true) == 42);
- value = 0;
- CHECK(invoke<int>(*code, &value - 2, 1, true) == 42);
- value = -1;
- CHECK(invoke<int>(*code, &value - 2, 1, true) == 42);
-
- value = 42;
- CHECK(invoke<int>(*code, &value - 2, 1, false) == 45);
- value = 127;
- CHECK(invoke<int>(*code, &value - 2, 1, false) == 45);
- value = 41;
- CHECK(invoke<int>(*code, &value - 2, 1, false) == 44);
- value = 0;
- CHECK(invoke<int>(*code, &value - 2, 1, false) == 44);
- value = -1;
- CHECK(invoke<int>(*code, &value - 2, 1, false) == 44);
-}
-
-void testCheckAddImm()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 42);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->append(arg1);
- checkAdd->append(arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isConstant());
- CHECK(params[1].value() == 42);
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
- jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkAdd));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == 42.0);
- CHECK(invoke<double>(*code, 1) == 43.0);
- CHECK(invoke<double>(*code, 42) == 84.0);
- CHECK(invoke<double>(*code, 2147483647) == 2147483689.0);
-}
-
-void testCheckAddImmCommute()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 42);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg2, arg1);
- checkAdd->append(arg1);
- checkAdd->append(arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isConstant());
- CHECK(params[1].value() == 42);
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
- jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkAdd));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == 42.0);
- CHECK(invoke<double>(*code, 1) == 43.0);
- CHECK(invoke<double>(*code, 42) == 84.0);
- CHECK(invoke<double>(*code, 2147483647) == 2147483689.0);
-}
-
-void testCheckAddImmSomeRegister()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 42);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->appendSomeRegister(arg1);
- checkAdd->appendSomeRegister(arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkAdd));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == 42.0);
- CHECK(invoke<double>(*code, 1) == 43.0);
- CHECK(invoke<double>(*code, 42) == 84.0);
- CHECK(invoke<double>(*code, 2147483647) == 2147483689.0);
-}
-
-void testCheckAdd()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->appendSomeRegister(arg1);
- checkAdd->appendSomeRegister(arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkAdd));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0, 42) == 42.0);
- CHECK(invoke<double>(*code, 1, 42) == 43.0);
- CHECK(invoke<double>(*code, 42, 42) == 84.0);
- CHECK(invoke<double>(*code, 2147483647, 42) == 2147483689.0);
-}
-
-void testCheckAdd64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->appendSomeRegister(arg1);
- checkAdd->appendSomeRegister(arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.addDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkAdd));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0ll, 42ll) == 42.0);
- CHECK(invoke<double>(*code, 1ll, 42ll) == 43.0);
- CHECK(invoke<double>(*code, 42ll, 42ll) == 84.0);
- CHECK(invoke<double>(*code, 9223372036854775807ll, 42ll) == static_cast<double>(9223372036854775807ll) + 42.0);
-}
-
-void testCheckAddFold(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams&) {
- CHECK(!"Should have been folded");
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == a + b);
-}
-
-void testCheckAddFoldFail(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == 42);
-}
-
-void testCheckAddArgumentAliasing64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
-
- // Pretend to use all the args.
- PatchpointValue* useArgs = root->appendNew<PatchpointValue>(proc, Void, Origin());
- useArgs->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- useArgs->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Last use of first arg (here, arg1).
- CheckValue* checkAdd1 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd1->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Last use of second arg (here, arg2).
- CheckValue* checkAdd2 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg3, arg2);
- checkAdd2->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Keep arg3 live.
- PatchpointValue* keepArg2Live = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepArg2Live->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepArg2Live->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Only use of checkAdd1 and checkAdd2.
- CheckValue* checkAdd3 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), checkAdd1, checkAdd2);
- checkAdd3->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd3);
-
- CHECK(compileAndRun<int64_t>(proc, 1, 2, 3) == 8);
-}
-
-void testCheckAddArgumentAliasing32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg3 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
-
- // Pretend to use all the args.
- PatchpointValue* useArgs = root->appendNew<PatchpointValue>(proc, Void, Origin());
- useArgs->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- useArgs->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Last use of first arg (here, arg1).
- CheckValue* checkAdd1 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg1, arg2);
- checkAdd1->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Last use of second arg (here, arg3).
- CheckValue* checkAdd2 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg2, arg3);
- checkAdd2->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Keep arg3 live.
- PatchpointValue* keepArg2Live = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepArg2Live->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepArg2Live->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Only use of checkAdd1 and checkAdd2.
- CheckValue* checkAdd3 = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), checkAdd1, checkAdd2);
- checkAdd3->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd3);
-
- CHECK(compileAndRun<int32_t>(proc, 1, 2, 3) == 8);
-}
-
-void testCheckAddSelfOverflow64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg, arg);
- checkAdd->append(arg);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.move(params[0].gpr(), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
-
- // Make sure the arg is not the destination of the operation.
- PatchpointValue* opaqueUse = root->appendNew<PatchpointValue>(proc, Void, Origin());
- opaqueUse->append(ConstrainedValue(arg, ValueRep::SomeRegister));
- opaqueUse->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd);
-
- auto code = compile(proc);
-
- CHECK(invoke<int64_t>(*code, 0ll) == 0);
- CHECK(invoke<int64_t>(*code, 1ll) == 2);
- CHECK(invoke<int64_t>(*code, std::numeric_limits<int64_t>::max()) == std::numeric_limits<int64_t>::max());
-}
-
-void testCheckAddSelfOverflow32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- CheckValue* checkAdd = root->appendNew<CheckValue>(proc, CheckAdd, Origin(), arg, arg);
- checkAdd->append(arg);
- checkAdd->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.move(params[0].gpr(), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
-
- // Make sure the arg is not the destination of the operation.
- PatchpointValue* opaqueUse = root->appendNew<PatchpointValue>(proc, Void, Origin());
- opaqueUse->append(ConstrainedValue(arg, ValueRep::SomeRegister));
- opaqueUse->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkAdd);
-
- auto code = compile(proc);
-
- CHECK(invoke<int32_t>(*code, 0ll) == 0);
- CHECK(invoke<int32_t>(*code, 1ll) == 2);
- CHECK(invoke<int32_t>(*code, std::numeric_limits<int32_t>::max()) == std::numeric_limits<int32_t>::max());
-}
-
-void testCheckSubImm()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 42);
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->append(arg1);
- checkSub->append(arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isConstant());
- CHECK(params[1].value() == 42);
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(42), FPRInfo::fpRegT1);
- jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkSub));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == -42.0);
- CHECK(invoke<double>(*code, 1) == -41.0);
- CHECK(invoke<double>(*code, 42) == 0.0);
- CHECK(invoke<double>(*code, -2147483647) == -2147483689.0);
-}
-
-void testCheckSubBadImm()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- int32_t badImm = std::numeric_limits<int>::min();
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), badImm);
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->append(arg1);
- checkSub->append(arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
-
- if (params[1].isConstant()) {
- CHECK(params[1].value() == badImm);
- jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(badImm), FPRInfo::fpRegT1);
- } else {
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- }
- jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkSub));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == -static_cast<double>(badImm));
- CHECK(invoke<double>(*code, -1) == -static_cast<double>(badImm) - 1);
- CHECK(invoke<double>(*code, 1) == -static_cast<double>(badImm) + 1);
- CHECK(invoke<double>(*code, 42) == -static_cast<double>(badImm) + 42);
-}
-
-void testCheckSub()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->append(arg1);
- checkSub->append(arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkSub));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0, 42) == -42.0);
- CHECK(invoke<double>(*code, 1, 42) == -41.0);
- CHECK(invoke<double>(*code, 42, 42) == 0.0);
- CHECK(invoke<double>(*code, -2147483647, 42) == -2147483689.0);
-}
-
-NEVER_INLINE double doubleSub(double a, double b)
-{
- return a - b;
-}
-
-void testCheckSub64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->append(arg1);
- checkSub->append(arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.subDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkSub));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0ll, 42ll) == -42.0);
- CHECK(invoke<double>(*code, 1ll, 42ll) == -41.0);
- CHECK(invoke<double>(*code, 42ll, 42ll) == 0.0);
- CHECK(invoke<double>(*code, -9223372036854775807ll, 42ll) == doubleSub(static_cast<double>(-9223372036854775807ll), 42.0));
-}
-
-void testCheckSubFold(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams&) {
- CHECK(!"Should have been folded");
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkSub);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == a - b);
-}
-
-void testCheckSubFoldFail(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkSub = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkSub->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkSub);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == 42);
-}
-
-void testCheckNeg()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), 0);
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- CheckValue* checkNeg = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkNeg->append(arg2);
- checkNeg->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 1);
- CHECK(params[0].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT1);
- jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkNeg));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == 0.0);
- CHECK(invoke<double>(*code, 1) == -1.0);
- CHECK(invoke<double>(*code, 42) == -42.0);
- CHECK(invoke<double>(*code, -2147483647 - 1) == 2147483648.0);
-}
-
-void testCheckNeg64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const64Value>(proc, Origin(), 0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- CheckValue* checkNeg = root->appendNew<CheckValue>(proc, CheckSub, Origin(), arg1, arg2);
- checkNeg->append(arg2);
- checkNeg->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 1);
- CHECK(params[0].isGPR());
- jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT1);
- jit.negateDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkNeg));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0ll) == 0.0);
- CHECK(invoke<double>(*code, 1ll) == -1.0);
- CHECK(invoke<double>(*code, 42ll) == -42.0);
- CHECK(invoke<double>(*code, -9223372036854775807ll - 1) == 9223372036854775808.0);
-}
-
-void testCheckMul()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->append(arg1);
- checkMul->append(arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkMul));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0, 42) == 0.0);
- CHECK(invoke<double>(*code, 1, 42) == 42.0);
- CHECK(invoke<double>(*code, 42, 42) == 42.0 * 42.0);
- CHECK(invoke<double>(*code, 2147483647, 42) == 2147483647.0 * 42.0);
-}
-
-void testCheckMulMemory()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- int left;
- int right;
-
- Value* arg1 = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &left));
- Value* arg2 = root->appendNew<MemoryValue>(
- proc, Load, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), &right));
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->append(arg1);
- checkMul->append(arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkMul));
-
- auto code = compile(proc);
-
- left = 0;
- right = 42;
- CHECK(invoke<double>(*code) == 0.0);
-
- left = 1;
- right = 42;
- CHECK(invoke<double>(*code) == 42.0);
-
- left = 42;
- right = 42;
- CHECK(invoke<double>(*code) == 42.0 * 42.0);
-
- left = 2147483647;
- right = 42;
- CHECK(invoke<double>(*code) == 2147483647.0 * 42.0);
-}
-
-void testCheckMul2()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), 2);
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->append(arg1);
- checkMul->append(arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isConstant());
- CHECK(params[1].value() == 2);
- jit.convertInt32ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt32ToDouble(CCallHelpers::TrustedImm32(2), FPRInfo::fpRegT1);
- jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkMul));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0) == 0.0);
- CHECK(invoke<double>(*code, 1) == 2.0);
- CHECK(invoke<double>(*code, 42) == 42.0 * 2.0);
- CHECK(invoke<double>(*code, 2147483647) == 2147483647.0 * 2.0);
-}
-
-void testCheckMul64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->append(arg1);
- checkMul->append(arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkMul));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0, 42) == 0.0);
- CHECK(invoke<double>(*code, 1, 42) == 42.0);
- CHECK(invoke<double>(*code, 42, 42) == 42.0 * 42.0);
- CHECK(invoke<double>(*code, 9223372036854775807ll, 42) == static_cast<double>(9223372036854775807ll) * 42.0);
-}
-
-void testCheckMulFold(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams&) {
- CHECK(!"Should have been folded");
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkMul);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == a * b);
-}
-
-void testCheckMulFoldFail(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Const32Value>(proc, Origin(), a);
- Value* arg2 = root->appendNew<Const32Value>(proc, Origin(), b);
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- jit.move(CCallHelpers::TrustedImm32(42), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(proc, Return, Origin(), checkMul);
-
- auto code = compile(proc);
-
- CHECK(invoke<int>(*code) == 42);
-}
-
-void testCheckMulArgumentAliasing64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
-
- // Pretend to use all the args.
- PatchpointValue* useArgs = root->appendNew<PatchpointValue>(proc, Void, Origin());
- useArgs->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- useArgs->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Last use of first arg (here, arg1).
- CheckValue* checkMul1 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul1->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Last use of second arg (here, arg2).
- CheckValue* checkMul2 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg3, arg2);
- checkMul2->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Keep arg3 live.
- PatchpointValue* keepArg2Live = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepArg2Live->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepArg2Live->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Only use of checkMul1 and checkMul2.
- CheckValue* checkMul3 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), checkMul1, checkMul2);
- checkMul3->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkMul3);
-
- CHECK(compileAndRun<int64_t>(proc, 2, 3, 4) == 72);
-}
-
-void testCheckMulArgumentAliasing32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* arg3 = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
-
- // Pretend to use all the args.
- PatchpointValue* useArgs = root->appendNew<PatchpointValue>(proc, Void, Origin());
- useArgs->append(ConstrainedValue(arg1, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- useArgs->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- useArgs->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Last use of first arg (here, arg1).
- CheckValue* checkMul1 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul1->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Last use of second arg (here, arg3).
- CheckValue* checkMul2 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg2, arg3);
- checkMul2->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- // Keep arg3 live.
- PatchpointValue* keepArg2Live = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepArg2Live->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepArg2Live->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- // Only use of checkMul1 and checkMul2.
- CheckValue* checkMul3 = root->appendNew<CheckValue>(proc, CheckMul, Origin(), checkMul1, checkMul2);
- checkMul3->setGenerator([&] (CCallHelpers& jit, const StackmapGenerationParams&) { jit.oops(); });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), checkMul3);
-
- CHECK(compileAndRun<int32_t>(proc, 2, 3, 4) == 72);
-}
-
-void testCheckMul64SShr()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg1 = root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), 1));
- Value* arg2 = root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<Const32Value>(proc, Origin(), 1));
- CheckValue* checkMul = root->appendNew<CheckValue>(proc, CheckMul, Origin(), arg1, arg2);
- checkMul->append(arg1);
- checkMul->append(arg2);
- checkMul->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 2);
- CHECK(params[0].isGPR());
- CHECK(params[1].isGPR());
- jit.convertInt64ToDouble(params[0].gpr(), FPRInfo::fpRegT0);
- jit.convertInt64ToDouble(params[1].gpr(), FPRInfo::fpRegT1);
- jit.mulDouble(FPRInfo::fpRegT1, FPRInfo::fpRegT0);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, IToD, Origin(), checkMul));
-
- auto code = compile(proc);
-
- CHECK(invoke<double>(*code, 0ll, 42ll) == 0.0);
- CHECK(invoke<double>(*code, 1ll, 42ll) == 0.0);
- CHECK(invoke<double>(*code, 42ll, 42ll) == (42.0 / 2.0) * (42.0 / 2.0));
- CHECK(invoke<double>(*code, 10000000000ll, 10000000000ll) == 25000000000000000000.0);
-}
-
-template<typename LeftFunctor, typename RightFunctor, typename InputType>
-void genericTestCompare(
- B3::Opcode opcode, const LeftFunctor& leftFunctor, const RightFunctor& rightFunctor,
- InputType left, InputType right, int result)
-{
- // Using a compare.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* leftValue = leftFunctor(root, proc);
- Value* rightValue = rightFunctor(root, proc);
- Value* comparisonResult = root->appendNew<Value>(proc, opcode, Origin(), leftValue, rightValue);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- comparisonResult,
- root->appendIntConstant(proc, Origin(), comparisonResult->type(), 0)));
-
- CHECK(compileAndRun<int>(proc, left, right) == result);
- }
-
- // Using a branch.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* leftValue = leftFunctor(root, proc);
- Value* rightValue = rightFunctor(root, proc);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), leftValue, rightValue),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- // We use a patchpoint on the then case to ensure that this doesn't get if-converted.
- PatchpointValue* patchpoint = thenCase->appendNew<PatchpointValue>(proc, Int32, Origin());
- patchpoint->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams& params) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
- CHECK(params.size() == 1);
- CHECK(params[0].isGPR());
- jit.move(CCallHelpers::TrustedImm32(1), params[0].gpr());
- });
- thenCase->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<Const32Value>(proc, Origin(), 0));
-
- CHECK(compileAndRun<int>(proc, left, right) == result);
- }
-}
-
-template<typename InputType>
-InputType modelCompare(B3::Opcode opcode, InputType left, InputType right)
-{
- switch (opcode) {
- case Equal:
- return left == right;
- case NotEqual:
- return left != right;
- case LessThan:
- return left < right;
- case GreaterThan:
- return left > right;
- case LessEqual:
- return left <= right;
- case GreaterEqual:
- return left >= right;
- case Above:
- return static_cast<typename std::make_unsigned<InputType>::type>(left) >
- static_cast<typename std::make_unsigned<InputType>::type>(right);
- case Below:
- return static_cast<typename std::make_unsigned<InputType>::type>(left) <
- static_cast<typename std::make_unsigned<InputType>::type>(right);
- case AboveEqual:
- return static_cast<typename std::make_unsigned<InputType>::type>(left) >=
- static_cast<typename std::make_unsigned<InputType>::type>(right);
- case BelowEqual:
- return static_cast<typename std::make_unsigned<InputType>::type>(left) <=
- static_cast<typename std::make_unsigned<InputType>::type>(right);
- case BitAnd:
- return !!(left & right);
- default:
- RELEASE_ASSERT_NOT_REACHED();
- return 0;
- }
-}
-
-template<typename T>
-void testCompareLoad(B3::Opcode opcode, B3::Opcode loadOpcode, int left, int right)
-{
- int result = modelCompare(opcode, modelLoad<T>(left), right);
-
- // Test addr-to-tmp
- int slot = left;
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<MemoryValue>(
- proc, loadOpcode, Int32, Origin(),
- block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- },
- left, right, result);
-
- // Test addr-to-imm
- slot = left;
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<MemoryValue>(
- proc, loadOpcode, Int32, Origin(),
- block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), right);
- },
- left, right, result);
-
- result = modelCompare(opcode, left, modelLoad<T>(right));
-
- // Test tmp-to-addr
- slot = right;
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<MemoryValue>(
- proc, loadOpcode, Int32, Origin(),
- block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- },
- left, right, result);
-
- // Test imm-to-addr
- slot = right;
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), left);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<MemoryValue>(
- proc, loadOpcode, Int32, Origin(),
- block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- },
- left, right, result);
-
- // Test addr-to-addr, with the same addr.
- slot = left;
- Value* value;
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- value = block->appendNew<MemoryValue>(
- proc, loadOpcode, Int32, Origin(),
- block->appendNew<ConstPtrValue>(proc, Origin(), &slot));
- return value;
- },
- [&] (BasicBlock*, Procedure&) {
- return value;
- },
- left, left, modelCompare(opcode, modelLoad<T>(left), modelLoad<T>(left)));
-}
-
-void testCompareImpl(B3::Opcode opcode, int64_t left, int64_t right)
-{
- int64_t result = modelCompare(opcode, left, right);
- int32_t int32Result = modelCompare(opcode, static_cast<int32_t>(left), static_cast<int32_t>(right));
-
- // Test tmp-to-tmp.
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- },
- left, right, result);
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- },
- left, right, int32Result);
-
- // Test imm-to-tmp.
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const64Value>(proc, Origin(), left);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- },
- left, right, result);
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), left);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- },
- left, right, int32Result);
-
- // Test tmp-to-imm.
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const64Value>(proc, Origin(), right);
- },
- left, right, result);
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Value>(
- proc, Trunc, Origin(),
- block->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), right);
- },
- left, right, int32Result);
-
- // Test imm-to-imm.
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const64Value>(proc, Origin(), left);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const64Value>(proc, Origin(), right);
- },
- left, right, result);
- genericTestCompare(
- opcode,
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), left);
- },
- [&] (BasicBlock* block, Procedure& proc) {
- return block->appendNew<Const32Value>(proc, Origin(), right);
- },
- left, right, int32Result);
-
- testCompareLoad<int32_t>(opcode, Load, left, right);
- testCompareLoad<int8_t>(opcode, Load8S, left, right);
- testCompareLoad<uint8_t>(opcode, Load8Z, left, right);
- testCompareLoad<int16_t>(opcode, Load16S, left, right);
- testCompareLoad<uint16_t>(opcode, Load16Z, left, right);
-}
-
-void testCompare(B3::Opcode opcode, int64_t left, int64_t right)
-{
- testCompareImpl(opcode, left, right);
- testCompareImpl(opcode, left, right + 1);
- testCompareImpl(opcode, left, right - 1);
-}
-
-void testEqualDouble(double left, double right, bool result)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
-
- CHECK(compileAndRun<bool>(proc, left, right) == result);
-}
-
-int simpleFunction(int a, int b)
-{
- return a + b;
-}
-
-void testCallSimple(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<CCallValue>(
- proc, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int>(proc, a, b) == a + b);
-}
-
-void testCallRare(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* common = proc.addBlock();
- BasicBlock* rare = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(rare, FrequencyClass::Rare),
- FrequentedBlock(common));
-
- common->appendNew<ControlValue>(
- proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
-
- rare->appendNew<ControlValue>(
- proc, Return, Origin(),
- rare->appendNew<CCallValue>(
- proc, Int32, Origin(),
- rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- CHECK(compileAndRun<int>(proc, true, a, b) == a + b);
-}
-
-void testCallRareLive(int a, int b, int c)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* common = proc.addBlock();
- BasicBlock* rare = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(rare, FrequencyClass::Rare),
- FrequentedBlock(common));
-
- common->appendNew<ControlValue>(
- proc, Return, Origin(), common->appendNew<Const32Value>(proc, Origin(), 0));
-
- rare->appendNew<ControlValue>(
- proc, Return, Origin(),
- rare->appendNew<Value>(
- proc, Add, Origin(),
- rare->appendNew<CCallValue>(
- proc, Int32, Origin(),
- rare->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
- rare->appendNew<Value>(
- proc, Trunc, Origin(),
- rare->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3))));
-
- CHECK(compileAndRun<int>(proc, true, a, b, c) == a + b + c);
-}
-
-void testCallSimplePure(int a, int b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<CCallValue>(
- proc, Int32, Origin(), Effects::none(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunction)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int>(proc, a, b) == a + b);
-}
-
-int functionWithHellaArguments(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l, int m, int n, int o, int p, int q, int r, int s, int t, int u, int v, int w, int x, int y, int z)
-{
- return (a << 0) + (b << 1) + (c << 2) + (d << 3) + (e << 4) + (f << 5) + (g << 6) + (h << 7) + (i << 8) + (j << 9) + (k << 10) + (l << 11) + (m << 12) + (n << 13) + (o << 14) + (p << 15) + (q << 16) + (r << 17) + (s << 18) + (t << 19) + (u << 20) + (v << 21) + (w << 22) + (x << 23) + (y << 24) + (z << 25);
-}
-
-void testCallFunctionWithHellaArguments()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Vector<Value*> args;
- for (unsigned i = 0; i < 26; ++i)
- args.append(root->appendNew<Const32Value>(proc, Origin(), i + 1));
-
- CCallValue* call = root->appendNew<CCallValue>(
- proc, Int32, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(functionWithHellaArguments)));
- call->children().appendVector(args);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), call);
-
- CHECK(compileAndRun<int>(proc) == functionWithHellaArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
-}
-
-void testReturnDouble(double value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<ConstDoubleValue>(proc, Origin(), value));
-
- CHECK(isIdentical(compileAndRun<double>(proc), value));
-}
-
-void testReturnFloat(float value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<ConstFloatValue>(proc, Origin(), value));
-
- CHECK(isIdentical(compileAndRun<float>(proc), value));
-}
-
-double simpleFunctionDouble(double a, double b)
-{
- return a + b;
-}
-
-void testCallSimpleDouble(double a, double b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<CCallValue>(
- proc, Double, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunctionDouble)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
-
- CHECK(compileAndRun<double>(proc, a, b) == a + b);
-}
-
-float simpleFunctionFloat(float a, float b)
-{
- return a + b;
-}
-
-void testCallSimpleFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<CCallValue>(
- proc, Float, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(simpleFunctionFloat)),
- floatValue1,
- floatValue2));
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b)), a + b));
-}
-
-double functionWithHellaDoubleArguments(double a, double b, double c, double d, double e, double f, double g, double h, double i, double j, double k, double l, double m, double n, double o, double p, double q, double r, double s, double t, double u, double v, double w, double x, double y, double z)
-{
- return a * pow(2, 0) + b * pow(2, 1) + c * pow(2, 2) + d * pow(2, 3) + e * pow(2, 4) + f * pow(2, 5) + g * pow(2, 6) + h * pow(2, 7) + i * pow(2, 8) + j * pow(2, 9) + k * pow(2, 10) + l * pow(2, 11) + m * pow(2, 12) + n * pow(2, 13) + o * pow(2, 14) + p * pow(2, 15) + q * pow(2, 16) + r * pow(2, 17) + s * pow(2, 18) + t * pow(2, 19) + u * pow(2, 20) + v * pow(2, 21) + w * pow(2, 22) + x * pow(2, 23) + y * pow(2, 24) + z * pow(2, 25);
-}
-
-void testCallFunctionWithHellaDoubleArguments()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Vector<Value*> args;
- for (unsigned i = 0; i < 26; ++i)
- args.append(root->appendNew<ConstDoubleValue>(proc, Origin(), i + 1));
-
- CCallValue* call = root->appendNew<CCallValue>(
- proc, Double, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(functionWithHellaDoubleArguments)));
- call->children().appendVector(args);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), call);
-
- CHECK(compileAndRun<double>(proc) == functionWithHellaDoubleArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
-}
-
-float functionWithHellaFloatArguments(float a, float b, float c, float d, float e, float f, float g, float h, float i, float j, float k, float l, float m, float n, float o, float p, float q, float r, float s, float t, float u, float v, float w, float x, float y, float z)
-{
- return a * pow(2, 0) + b * pow(2, 1) + c * pow(2, 2) + d * pow(2, 3) + e * pow(2, 4) + f * pow(2, 5) + g * pow(2, 6) + h * pow(2, 7) + i * pow(2, 8) + j * pow(2, 9) + k * pow(2, 10) + l * pow(2, 11) + m * pow(2, 12) + n * pow(2, 13) + o * pow(2, 14) + p * pow(2, 15) + q * pow(2, 16) + r * pow(2, 17) + s * pow(2, 18) + t * pow(2, 19) + u * pow(2, 20) + v * pow(2, 21) + w * pow(2, 22) + x * pow(2, 23) + y * pow(2, 24) + z * pow(2, 25);
-}
-
-void testCallFunctionWithHellaFloatArguments()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Vector<Value*> args;
- for (unsigned i = 0; i < 26; ++i)
- args.append(root->appendNew<ConstFloatValue>(proc, Origin(), i + 1));
-
- CCallValue* call = root->appendNew<CCallValue>(
- proc, Float, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), bitwise_cast<void*>(functionWithHellaFloatArguments)));
- call->children().appendVector(args);
-
- root->appendNew<ControlValue>(proc, Return, Origin(), call);
-
- CHECK(compileAndRun<float>(proc) == functionWithHellaFloatArguments(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26));
-}
-
-void testChillDiv(int num, int den, int res)
-{
- // Test non-constant.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))));
-
- CHECK(compileAndRun<int>(proc, num, den) == res);
- }
-
- // Test constant.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), num),
- root->appendNew<Const32Value>(proc, Origin(), den)));
-
- CHECK(compileAndRun<int>(proc) == res);
- }
-}
-
-void testChillDivTwice(int num1, int den1, int num2, int den2, int res)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1))),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)))));
-
- CHECK(compileAndRun<int>(proc, num1, den1, num2, den2) == res);
-}
-
-void testChillDiv64(int64_t num, int64_t den, int64_t res)
-{
- if (!is64Bit())
- return;
-
- // Test non-constant.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- CHECK(compileAndRun<int64_t>(proc, num, den) == res);
- }
-
- // Test constant.
- {
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ChillDiv, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), num),
- root->appendNew<Const64Value>(proc, Origin(), den)));
-
- CHECK(compileAndRun<int64_t>(proc) == res);
- }
-}
-
-void testModArg(int64_t value)
-{
- if (!value)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(!compileAndRun<int64_t>(proc, value));
-}
-
-void testModArgs(int64_t numerator, int64_t denominator)
-{
- if (!denominator)
- return;
- if (numerator == std::numeric_limits<int64_t>::min() && denominator == -1)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == numerator % denominator);
-}
-
-void testModImms(int64_t numerator, int64_t denominator)
-{
- if (!denominator)
- return;
- if (numerator == std::numeric_limits<int64_t>::min() && denominator == -1)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Const64Value>(proc, Origin(), numerator);
- Value* argument2 = root->appendNew<Const64Value>(proc, Origin(), denominator);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == numerator % denominator);
-}
-
-void testModArg32(int32_t value)
-{
- if (!value)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(!compileAndRun<int32_t>(proc, value));
-}
-
-void testModArgs32(int32_t numerator, int32_t denominator)
-{
- if (!denominator)
- return;
- if (numerator == std::numeric_limits<int32_t>::min() && denominator == -1)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == numerator % denominator);
-}
-
-void testModImms32(int32_t numerator, int32_t denominator)
-{
- if (!denominator)
- return;
- if (numerator == std::numeric_limits<int32_t>::min() && denominator == -1)
- return;
-
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Const32Value>(proc, Origin(), numerator);
- Value* argument2 = root->appendNew<Const32Value>(proc, Origin(), denominator);
- Value* result = root->appendNew<Value>(proc, Mod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == numerator % denominator);
-}
-
-void testChillModArg(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(!compileAndRun<int64_t>(proc, value));
-}
-
-void testChillModArgs(int64_t numerator, int64_t denominator)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* argument2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
-}
-
-void testChillModImms(int64_t numerator, int64_t denominator)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Const64Value>(proc, Origin(), numerator);
- Value* argument2 = root->appendNew<Const64Value>(proc, Origin(), denominator);
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int64_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
-}
-
-void testChillModArg32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument, argument);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(!compileAndRun<int32_t>(proc, value));
-}
-
-void testChillModArgs32(int32_t numerator, int32_t denominator)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
-}
-
-void testChillModImms32(int32_t numerator, int32_t denominator)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* argument1 = root->appendNew<Const32Value>(proc, Origin(), numerator);
- Value* argument2 = root->appendNew<Const32Value>(proc, Origin(), denominator);
- Value* result = root->appendNew<Value>(proc, ChillMod, Origin(), argument1, argument2);
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
-
- CHECK(compileAndRun<int32_t>(proc, numerator, denominator) == chillMod(numerator, denominator));
-}
-
-void testSwitch(unsigned degree, unsigned gap = 1)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- BasicBlock* terminate = proc.addBlock();
- terminate->appendNew<ControlValue>(
- proc, Return, Origin(),
- terminate->appendNew<Const32Value>(proc, Origin(), 0));
-
- SwitchValue* switchValue = root->appendNew<SwitchValue>(
- proc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(terminate));
-
- for (unsigned i = 0; i < degree; ++i) {
- BasicBlock* newBlock = proc.addBlock();
- newBlock->appendNew<ControlValue>(
- proc, Return, Origin(),
- newBlock->appendNew<ArgumentRegValue>(
- proc, Origin(), (i & 1) ? GPRInfo::argumentGPR2 : GPRInfo::argumentGPR1));
- switchValue->appendCase(SwitchCase(gap * i, FrequentedBlock(newBlock)));
- }
-
- auto code = compile(proc);
-
- for (unsigned i = 0; i < degree; ++i) {
- CHECK(invoke<int32_t>(*code, i * gap, 42, 11) == ((i & 1) ? 11 : 42));
- if (gap > 1) {
- CHECK(!invoke<int32_t>(*code, i * gap + 1, 42, 11));
- CHECK(!invoke<int32_t>(*code, i * gap - 1, 42, 11));
- }
- }
-
- CHECK(!invoke<int32_t>(*code, -1, 42, 11));
- CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
- CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
-}
-
-void testSwitchChillDiv(unsigned degree, unsigned gap = 1)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* left = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- Value* right = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2);
-
- BasicBlock* terminate = proc.addBlock();
- terminate->appendNew<ControlValue>(
- proc, Return, Origin(),
- terminate->appendNew<Const32Value>(proc, Origin(), 0));
-
- SwitchValue* switchValue = root->appendNew<SwitchValue>(
- proc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(terminate));
-
- for (unsigned i = 0; i < degree; ++i) {
- BasicBlock* newBlock = proc.addBlock();
-
- newBlock->appendNew<ControlValue>(
- proc, Return, Origin(),
- newBlock->appendNew<Value>(
- proc, ChillDiv, Origin(), (i & 1) ? right : left, (i & 1) ? left : right));
-
- switchValue->appendCase(SwitchCase(gap * i, FrequentedBlock(newBlock)));
- }
-
- auto code = compile(proc);
-
- for (unsigned i = 0; i < degree; ++i) {
- CHECK(invoke<int32_t>(*code, i * gap, 42, 11) == ((i & 1) ? 11/42 : 42/11));
- if (gap > 1) {
- CHECK(!invoke<int32_t>(*code, i * gap + 1, 42, 11));
- CHECK(!invoke<int32_t>(*code, i * gap - 1, 42, 11));
- }
- }
-
- CHECK(!invoke<int32_t>(*code, -1, 42, 11));
- CHECK(!invoke<int32_t>(*code, degree * gap, 42, 11));
- CHECK(!invoke<int32_t>(*code, degree * gap + 1, 42, 11));
-}
-
-void testSwitchTargettingSameBlock()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- BasicBlock* terminate = proc.addBlock();
- terminate->appendNew<ControlValue>(
- proc, Return, Origin(),
- terminate->appendNew<Const32Value>(proc, Origin(), 5));
-
- SwitchValue* switchValue = root->appendNew<SwitchValue>(
- proc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- FrequentedBlock(terminate));
-
- BasicBlock* otherTarget = proc.addBlock();
- otherTarget->appendNew<ControlValue>(
- proc, Return, Origin(),
- otherTarget->appendNew<Const32Value>(proc, Origin(), 42));
- switchValue->appendCase(SwitchCase(3, FrequentedBlock(otherTarget)));
- switchValue->appendCase(SwitchCase(13, FrequentedBlock(otherTarget)));
-
- auto code = compile(proc);
-
- for (unsigned i = 0; i < 20; ++i) {
- int32_t expected = (i == 3 || i == 13) ? 42 : 5;
- CHECK(invoke<int32_t>(*code, i) == expected);
- }
-}
-
-void testSwitchTargettingSameBlockFoldPathConstant()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- BasicBlock* terminate = proc.addBlock();
- terminate->appendNew<ControlValue>(
- proc, Return, Origin(),
- terminate->appendNew<Const32Value>(proc, Origin(), 42));
-
- Value* argument = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- SwitchValue* switchValue = root->appendNew<SwitchValue>(
- proc, Origin(),
- argument,
- FrequentedBlock(terminate));
-
- BasicBlock* otherTarget = proc.addBlock();
- otherTarget->appendNew<ControlValue>(
- proc, Return, Origin(), argument);
- switchValue->appendCase(SwitchCase(3, FrequentedBlock(otherTarget)));
- switchValue->appendCase(SwitchCase(13, FrequentedBlock(otherTarget)));
-
- auto code = compile(proc);
-
- for (unsigned i = 0; i < 20; ++i) {
- int32_t expected = (i == 3 || i == 13) ? i : 42;
- CHECK(invoke<int32_t>(*code, i) == expected);
- }
-}
-
-void testTruncFold(int64_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<Const64Value>(proc, Origin(), value)));
-
- CHECK(compileAndRun<int>(proc) == static_cast<int>(value));
-}
-
-void testZExt32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<uint64_t>(proc, value) == static_cast<uint64_t>(static_cast<uint32_t>(value)));
-}
-
-void testZExt32Fold(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value)));
-
- CHECK(compileAndRun<uint64_t>(proc, value) == static_cast<uint64_t>(static_cast<uint32_t>(value)));
-}
-
-void testSExt32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int64_t>(proc, value) == static_cast<int64_t>(value));
-}
-
-void testSExt32Fold(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt32, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value)));
-
- CHECK(compileAndRun<int64_t>(proc, value) == static_cast<int64_t>(value));
-}
-
-void testTruncZExt32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<Value>(
- proc, ZExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == value);
-}
-
-void testTruncSExt32(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<Value>(
- proc, SExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == value);
-}
-
-void testSExt8(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int8_t>(value)));
-}
-
-void testSExt8Fold(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value)));
-
- CHECK(compileAndRun<int32_t>(proc) == static_cast<int32_t>(static_cast<int8_t>(value)));
-}
-
-void testSExt8SExt8(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int8_t>(value)));
-}
-
-void testSExt8SExt16(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int8_t>(value)));
-}
-
-void testSExt8BitAnd(int32_t value, int32_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), mask))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int8_t>(value & mask)));
-}
-
-void testBitAndSExt8(int32_t value, int32_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- root->appendNew<Const32Value>(proc, Origin(), mask)));
-
- CHECK(compileAndRun<int32_t>(proc, value) == (static_cast<int32_t>(static_cast<int8_t>(value)) & mask));
-}
-
-void testSExt16(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int16_t>(value)));
-}
-
-void testSExt16Fold(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), value)));
-
- CHECK(compileAndRun<int32_t>(proc) == static_cast<int32_t>(static_cast<int16_t>(value)));
-}
-
-void testSExt16SExt16(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int16_t>(value)));
-}
-
-void testSExt16SExt8(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, SExt8, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int8_t>(value)));
-}
-
-void testSExt16BitAnd(int32_t value, int32_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), mask))));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<int32_t>(static_cast<int16_t>(value & mask)));
-}
-
-void testBitAndSExt16(int32_t value, int32_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, SExt16, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- root->appendNew<Const32Value>(proc, Origin(), mask)));
-
- CHECK(compileAndRun<int32_t>(proc, value) == (static_cast<int32_t>(static_cast<int16_t>(value)) & mask));
-}
-
-void testSExt32BitAnd(int32_t value, int32_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SExt32, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), mask))));
-
- CHECK(compileAndRun<int64_t>(proc, value) == static_cast<int64_t>(value & mask));
-}
-
-void testBitAndSExt32(int32_t value, int64_t mask)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, SExt32, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0))),
- root->appendNew<Const64Value>(proc, Origin(), mask)));
-
- CHECK(compileAndRun<int64_t>(proc, value) == (static_cast<int64_t>(value) & mask));
-}
-
-void testBasicSelect()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, 42, 1, 2) == 1);
- CHECK(invoke<intptr_t>(*code, 42, 642462, 32533) == 642462);
- CHECK(invoke<intptr_t>(*code, 43, 1, 2) == 2);
- CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
-}
-
-void testSelectTest()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, 42, 1, 2) == 1);
- CHECK(invoke<intptr_t>(*code, 42, 642462, 32533) == 642462);
- CHECK(invoke<intptr_t>(*code, 0, 1, 2) == 2);
- CHECK(invoke<intptr_t>(*code, 0, 642462, 32533) == 32533);
-}
-
-void testSelectCompareDouble()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, -1.0, 1.0, 1, 2) == 1);
- CHECK(invoke<intptr_t>(*code, 42.5, 42.51, 642462, 32533) == 642462);
- CHECK(invoke<intptr_t>(*code, PNaN, 0.0, 1, 2) == 2);
- CHECK(invoke<intptr_t>(*code, 42.51, 42.5, 642462, 32533) == 32533);
- CHECK(invoke<intptr_t>(*code, 42.52, 42.52, 524978245, 352) == 352);
-}
-
-template<B3::Opcode opcode>
-void testSelectCompareFloat(float a, float b, bool (*operation)(float, float))
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- floatValue1,
- floatValue2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), 42, -5), operation(a, b) ? 42 : -5));
-}
-
-void testSelectCompareFloat(float a, float b)
-{
- testSelectCompareFloat<Equal>(a, b, [](float a, float b) -> bool { return a == b; });
- testSelectCompareFloat<NotEqual>(a, b, [](float a, float b) -> bool { return a != b; });
- testSelectCompareFloat<LessThan>(a, b, [](float a, float b) -> bool { return a < b; });
- testSelectCompareFloat<GreaterThan>(a, b, [](float a, float b) -> bool { return a > b; });
- testSelectCompareFloat<LessEqual>(a, b, [](float a, float b) -> bool { return a <= b; });
- testSelectCompareFloat<GreaterEqual>(a, b, [](float a, float b) -> bool { return a >= b; });
- testSelectCompareFloat<EqualOrUnordered>(a, b, [](float a, float b) -> bool { return a != a || b != b || a == b; });
-}
-
-template<B3::Opcode opcode>
-void testSelectCompareFloatToDouble(float a, float b, bool (*operation)(float, float))
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* doubleValue1 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue1);
- Value* doubleValue2 = root->appendNew<Value>(proc, FloatToDouble, Origin(), floatValue2);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- doubleValue1,
- doubleValue2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
- CHECK(isIdentical(compileAndRun<int32_t>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), 42, -5), operation(a, b) ? 42 : -5));
-}
-
-void testSelectCompareFloatToDouble(float a, float b)
-{
- testSelectCompareFloatToDouble<Equal>(a, b, [](float a, float b) -> bool { return a == b; });
- testSelectCompareFloatToDouble<NotEqual>(a, b, [](float a, float b) -> bool { return a != b; });
- testSelectCompareFloatToDouble<LessThan>(a, b, [](float a, float b) -> bool { return a < b; });
- testSelectCompareFloatToDouble<GreaterThan>(a, b, [](float a, float b) -> bool { return a > b; });
- testSelectCompareFloatToDouble<LessEqual>(a, b, [](float a, float b) -> bool { return a <= b; });
- testSelectCompareFloatToDouble<GreaterEqual>(a, b, [](float a, float b) -> bool { return a >= b; });
- testSelectCompareFloatToDouble<EqualOrUnordered>(a, b, [](float a, float b) -> bool { return a != a || b != b || a == b; });
-}
-
-void testSelectDouble()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
-
- auto code = compile(proc);
- CHECK(invoke<double>(*code, 42, 1.5, 2.6) == 1.5);
- CHECK(invoke<double>(*code, 42, 642462.7, 32533.8) == 642462.7);
- CHECK(invoke<double>(*code, 43, 1.9, 2.0) == 2.0);
- CHECK(invoke<double>(*code, 43, 642462.1, 32533.2) == 32533.2);
-}
-
-void testSelectDoubleTest()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
-
- auto code = compile(proc);
- CHECK(invoke<double>(*code, 42, 1.5, 2.6) == 1.5);
- CHECK(invoke<double>(*code, 42, 642462.7, 32533.8) == 642462.7);
- CHECK(invoke<double>(*code, 0, 1.9, 2.0) == 2.0);
- CHECK(invoke<double>(*code, 0, 642462.1, 32533.2) == 32533.2);
-}
-
-void testSelectDoubleCompareDouble()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR3)));
-
- auto code = compile(proc);
- CHECK(invoke<double>(*code, -1.0, 1.0, 1.1, 2.2) == 1.1);
- CHECK(invoke<double>(*code, 42.5, 42.51, 642462.3, 32533.4) == 642462.3);
- CHECK(invoke<double>(*code, PNaN, 0.0, 1.5, 2.6) == 2.6);
- CHECK(invoke<double>(*code, 42.51, 42.5, 642462.7, 32533.8) == 32533.8);
- CHECK(invoke<double>(*code, 42.52, 42.52, 524978245.9, 352.0) == 352.0);
-}
-
-void testSelectDoubleCompareFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- floatValue1,
- floatValue2),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1)));
-
- CHECK(isIdentical(compileAndRun<double>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), 42.1, -M_PI), a < b ? 42.1 : -M_PI));
-}
-
-void testSelectFloatCompareFloat(float a, float b)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* argument1int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* argument2int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1));
- Value* argument3int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2));
- Value* argument4int32 = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3));
- Value* floatValue1 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument1int32);
- Value* floatValue2 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument2int32);
- Value* floatValue3 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument3int32);
- Value* floatValue4 = root->appendNew<Value>(proc, BitwiseCast, Origin(), argument4int32);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, LessThan, Origin(),
- floatValue1,
- floatValue2),
- floatValue3,
- floatValue4));
-
- CHECK(isIdentical(compileAndRun<float>(proc, bitwise_cast<int32_t>(a), bitwise_cast<int32_t>(b), bitwise_cast<int32_t>(1.1f), bitwise_cast<int32_t>(-42.f)), a < b ? 1.1f : -42.f));
-}
-
-
-template<B3::Opcode opcode>
-void testSelectDoubleCompareDouble(bool (*operation)(double, double))
-{
- { // Compare arguments and selected arguments are all different.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR3);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- arg0,
- arg1),
- arg2,
- arg3));
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, -66.5), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. "thenCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR3);
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, -66.5), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. "elseCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR3);
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, -66.5), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. Both cases are live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
- Value* arg3 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR3);
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, -66.5), expected));
- }
- }
- }
- { // The left argument is the same as the "elseCase" argument.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- arg0,
- arg1),
- arg2,
- arg0));
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : left.value;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, left.value), expected));
- }
- }
- }
- { // The left argument is the same as the "elseCase" argument. "thenCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR1);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR2);
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg0);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<double>()) {
- for (auto& right : floatingPointOperands<double>()) {
- double expected = operation(left.value, right.value) ? 42.5 : left.value;
- CHECK(isIdentical(invoke<double>(*code, left.value, right.value, 42.5, left.value), expected));
- }
- }
- }
-}
-
-void testSelectDoubleCompareDoubleWithAliasing()
-{
- testSelectDoubleCompareDouble<Equal>([](double a, double b) -> bool { return a == b; });
- testSelectDoubleCompareDouble<NotEqual>([](double a, double b) -> bool { return a != b; });
- testSelectDoubleCompareDouble<LessThan>([](double a, double b) -> bool { return a < b; });
- testSelectDoubleCompareDouble<GreaterThan>([](double a, double b) -> bool { return a > b; });
- testSelectDoubleCompareDouble<LessEqual>([](double a, double b) -> bool { return a <= b; });
- testSelectDoubleCompareDouble<GreaterEqual>([](double a, double b) -> bool { return a >= b; });
- testSelectDoubleCompareDouble<EqualOrUnordered>([](double a, double b) -> bool { return a != a || b != b || a == b; });
-}
-
-template<B3::Opcode opcode>
-void testSelectFloatCompareFloat(bool (*operation)(float, float))
-{
- { // Compare arguments and selected arguments are all different.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
- Value* arg3 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- arg0,
- arg1),
- arg2,
- arg3));
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(-66.5f)), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. "thenCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
- Value* arg3 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(-66.5f)), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. "elseCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
- Value* arg3 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(-66.5f)), expected));
- }
- }
- }
- { // Compare arguments and selected arguments are all different. Both cases are live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
- Value* arg3 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR3)));
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg3);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->append(ConstrainedValue(arg3, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : -66.5;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(-66.5f)), expected));
- }
- }
- }
- { // The left argument is the same as the "elseCase" argument.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, opcode, Origin(),
- arg0,
- arg1),
- arg2,
- arg0));
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : left.value;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(left.value)), expected));
- }
- }
- }
- { // The left argument is the same as the "elseCase" argument. "thenCase" is live after operation.
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg0 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)));
- Value* arg1 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
- Value* arg2 = root->appendNew<Value>(proc, BitwiseCast, Origin(),
- root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- Value* result = root->appendNew<Value>(proc, Select, Origin(),
- root->appendNew<Value>(proc, opcode, Origin(), arg0, arg1),
- arg2,
- arg0);
-
- PatchpointValue* keepValuesLive = root->appendNew<PatchpointValue>(proc, Void, Origin());
- keepValuesLive->append(ConstrainedValue(arg2, ValueRep::SomeRegister));
- keepValuesLive->setGenerator([&] (CCallHelpers&, const StackmapGenerationParams&) { });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), result);
- auto code = compile(proc);
-
- for (auto& left : floatingPointOperands<float>()) {
- for (auto& right : floatingPointOperands<float>()) {
- float expected = operation(left.value, right.value) ? 42.5 : left.value;
- CHECK(isIdentical(invoke<float>(*code, bitwise_cast<int32_t>(left.value), bitwise_cast<int32_t>(right.value), bitwise_cast<int32_t>(42.5f), bitwise_cast<int32_t>(left.value)), expected));
- }
- }
- }
-}
-
-void testSelectFloatCompareFloatWithAliasing()
-{
- testSelectFloatCompareFloat<Equal>([](float a, float b) -> bool { return a == b; });
- testSelectFloatCompareFloat<NotEqual>([](float a, float b) -> bool { return a != b; });
- testSelectFloatCompareFloat<LessThan>([](float a, float b) -> bool { return a < b; });
- testSelectFloatCompareFloat<GreaterThan>([](float a, float b) -> bool { return a > b; });
- testSelectFloatCompareFloat<LessEqual>([](float a, float b) -> bool { return a <= b; });
- testSelectFloatCompareFloat<GreaterEqual>([](float a, float b) -> bool { return a >= b; });
- testSelectFloatCompareFloat<EqualOrUnordered>([](float a, float b) -> bool { return a != a || b != b || a == b; });
-}
-
-void testSelectFold(intptr_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<ConstPtrValue>(proc, Origin(), value),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, 1, 2) == (value == 42 ? 1 : 2));
- CHECK(invoke<intptr_t>(*code, 642462, 32533) == (value == 42 ? 642462 : 32533));
-}
-
-void testSelectInvert()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, Equal, Origin(),
- root->appendNew<Value>(
- proc, NotEqual, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)),
- root->appendNew<Const32Value>(proc, Origin(), 0)),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR2)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, 42, 1, 2) == 1);
- CHECK(invoke<intptr_t>(*code, 42, 642462, 32533) == 642462);
- CHECK(invoke<intptr_t>(*code, 43, 1, 2) == 2);
- CHECK(invoke<intptr_t>(*code, 43, 642462, 32533) == 32533);
-}
-
-void testCheckSelect()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(
- proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0xff)),
- root->appendNew<ConstPtrValue>(proc, Origin(), -42),
- root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
- unsigned generationCount = 0;
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
-
- generationCount++;
- jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(generationCount == 1);
- CHECK(invoke<int>(*code, true) == 0);
- CHECK(invoke<int>(*code, false) == 666);
-}
-
-void testCheckSelectCheckSelect()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- CheckValue* check = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(
- proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), 0xff)),
- root->appendNew<ConstPtrValue>(proc, Origin(), -42),
- root->appendNew<ConstPtrValue>(proc, Origin(), 35)),
- root->appendNew<ConstPtrValue>(proc, Origin(), 42)));
-
- unsigned generationCount = 0;
- check->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
-
- generationCount++;
- jit.move(CCallHelpers::TrustedImm32(666), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
-
- CheckValue* check2 = root->appendNew<CheckValue>(
- proc, Check, Origin(),
- root->appendNew<Value>(
- proc, Add, Origin(),
- root->appendNew<Value>(
- proc, Select, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(
- proc, Origin(), GPRInfo::argumentGPR1)),
- root->appendNew<Const32Value>(proc, Origin(), 0xff)),
- root->appendNew<ConstPtrValue>(proc, Origin(), -43),
- root->appendNew<ConstPtrValue>(proc, Origin(), 36)),
- root->appendNew<ConstPtrValue>(proc, Origin(), 43)));
-
- unsigned generationCount2 = 0;
- check2->setGenerator(
- [&] (CCallHelpers& jit, const StackmapGenerationParams&) {
- AllowMacroScratchRegisterUsage allowScratch(jit);
-
- generationCount2++;
- jit.move(CCallHelpers::TrustedImm32(667), GPRInfo::returnValueGPR);
- jit.emitFunctionEpilogue();
- jit.ret();
- });
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Const32Value>(proc, Origin(), 0));
-
- auto code = compile(proc);
- CHECK(generationCount == 1);
- CHECK(generationCount2 == 1);
- CHECK(invoke<int>(*code, true, true) == 0);
- CHECK(invoke<int>(*code, false, true) == 666);
- CHECK(invoke<int>(*code, true, false) == 667);
-}
-
-double b3Pow(double x, int y)
-{
- if (y < 0 || y > 1000)
- return pow(x, y);
- double result = 1;
- while (y) {
- if (y & 1)
- result *= x;
- x *= x;
- y >>= 1;
- }
- return result;
-}
-
-void testPowDoubleByIntegerLoop(double xOperand, int32_t yOperand)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* x = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
- Value* y = root->appendNew<Value>(proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- auto result = powDoubleInt32(proc, root, Origin(), x, y);
- BasicBlock* continuation = result.first;
- continuation->appendNew<ControlValue>(proc, Return, Origin(), result.second);
-
- CHECK(isIdentical(compileAndRun<double>(proc, xOperand, yOperand), b3Pow(xOperand, yOperand)));
-}
-
-void testTruncOrHigh()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), 0x100000000))));
-
- int64_t value = 0x123456781234;
- CHECK(compileAndRun<int>(proc, value) == 0x56781234);
-}
-
-void testTruncOrLow()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), 0x1000000))));
-
- int64_t value = 0x123456781234;
- CHECK(compileAndRun<int>(proc, value) == 0x57781234);
-}
-
-void testBitAndOrHigh()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), 0x8)),
- root->appendNew<Const64Value>(proc, Origin(), 0x777777777777)));
-
- int64_t value = 0x123456781234;
- CHECK(compileAndRun<int64_t>(proc, value) == 0x123456701234ll);
-}
-
-void testBitAndOrLow()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, BitAnd, Origin(),
- root->appendNew<Value>(
- proc, BitOr, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const64Value>(proc, Origin(), 0x1)),
- root->appendNew<Const64Value>(proc, Origin(), 0x777777777777)));
-
- int64_t value = 0x123456781234;
- CHECK(compileAndRun<int64_t>(proc, value) == 0x123456701235ll);
-}
-
-void testBranch64Equal(int64_t left, int64_t right)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- bool trueResult = true;
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- thenCase->appendNew<ConstPtrValue>(proc, Origin(), &trueResult)));
-
- bool elseResult = false;
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- elseCase->appendNew<ConstPtrValue>(proc, Origin(), &elseResult)));
-
- CHECK(compileAndRun<bool>(proc, left, right) == (left == right));
-}
-
-void testBranch64EqualImm(int64_t left, int64_t right)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* arg1 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- Value* arg2 = root->appendNew<ConstPtrValue>(proc, Origin(), right);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- bool trueResult = true;
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- thenCase->appendNew<ConstPtrValue>(proc, Origin(), &trueResult)));
-
- bool elseResult = false;
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- elseCase->appendNew<ConstPtrValue>(proc, Origin(), &elseResult)));
-
- CHECK(compileAndRun<bool>(proc, left) == (left == right));
-}
-
-void testBranch64EqualMem(int64_t left, int64_t right)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* arg1 = root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR1);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- bool trueResult = true;
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- thenCase->appendNew<ConstPtrValue>(proc, Origin(), &trueResult)));
-
- bool elseResult = false;
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- elseCase->appendNew<ConstPtrValue>(proc, Origin(), &elseResult)));
-
- CHECK(compileAndRun<bool>(proc, &left, right) == (left == right));
-}
-
-void testBranch64EqualMemImm(int64_t left, int64_t right)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenCase = proc.addBlock();
- BasicBlock* elseCase = proc.addBlock();
-
- Value* arg1 = root->appendNew<MemoryValue>(
- proc, Load, pointerType(), Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- Value* arg2 = root->appendNew<ConstPtrValue>(proc, Origin(), right);
- root->appendNew<ControlValue>(
- proc, Branch, Origin(),
- root->appendNew<Value>(proc, Equal, Origin(), arg1, arg2),
- FrequentedBlock(thenCase), FrequentedBlock(elseCase));
-
- bool trueResult = true;
- thenCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- thenCase->appendNew<ConstPtrValue>(proc, Origin(), &trueResult)));
-
- bool elseResult = false;
- elseCase->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseCase->appendNew<MemoryValue>(
- proc, Load8Z, Origin(),
- elseCase->appendNew<ConstPtrValue>(proc, Origin(), &elseResult)));
-
- CHECK(compileAndRun<bool>(proc, &left) == (left == right));
-}
-
-void testStore8Load8Z(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- int8_t byte;
- Value* ptr = root->appendNew<ConstPtrValue>(proc, Origin(), &byte);
-
- root->appendNew<MemoryValue>(
- proc, Store8, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- ptr);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(proc, Load8Z, Origin(), ptr));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<uint8_t>(value));
-}
-
-void testStore16Load16Z(int32_t value)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- int16_t byte;
- Value* ptr = root->appendNew<ConstPtrValue>(proc, Origin(), &byte);
-
- root->appendNew<MemoryValue>(
- proc, Store16, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- ptr);
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<MemoryValue>(proc, Load16Z, Origin(), ptr));
-
- CHECK(compileAndRun<int32_t>(proc, value) == static_cast<uint16_t>(value));
-}
-
-void testSShrShl32(int32_t value, int32_t sshrAmount, int32_t shlAmount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0)),
- root->appendNew<Const32Value>(proc, Origin(), shlAmount)),
- root->appendNew<Const32Value>(proc, Origin(), sshrAmount)));
-
- CHECK(
- compileAndRun<int32_t>(proc, value)
- == ((value << (shlAmount & 31)) >> (sshrAmount & 31)));
-}
-
-void testSShrShl64(int64_t value, int32_t sshrAmount, int32_t shlAmount)
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0),
- root->appendNew<Const32Value>(proc, Origin(), shlAmount)),
- root->appendNew<Const32Value>(proc, Origin(), sshrAmount)));
-
- CHECK(
- compileAndRun<int64_t>(proc, value)
- == ((value << (shlAmount & 63)) >> (sshrAmount & 63)));
-}
-
-template<typename T>
-void testComputeDivisionMagic(T value, T magicMultiplier, unsigned shift)
-{
- DivisionMagic<T> magic = computeDivisionMagic(value);
- CHECK(magic.magicMultiplier == magicMultiplier);
- CHECK(magic.shift == shift);
-}
-
-void testTrivialInfiniteLoop()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* loop = proc.addBlock();
- root->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loop));
- loop->appendNew<ControlValue>(proc, Jump, Origin(), FrequentedBlock(loop));
-
- compile(proc);
-}
-
-void testFoldPathEqual()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- BasicBlock* thenBlock = proc.addBlock();
- BasicBlock* elseBlock = proc.addBlock();
-
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
-
- root->appendNew<ControlValue>(
- proc, Branch, Origin(), arg, FrequentedBlock(thenBlock), FrequentedBlock(elseBlock));
-
- thenBlock->appendNew<ControlValue>(
- proc, Return, Origin(),
- thenBlock->appendNew<Value>(
- proc, Equal, Origin(), arg, thenBlock->appendNew<ConstPtrValue>(proc, Origin(), 0)));
-
- elseBlock->appendNew<ControlValue>(
- proc, Return, Origin(),
- elseBlock->appendNew<Value>(
- proc, Equal, Origin(), arg, elseBlock->appendNew<ConstPtrValue>(proc, Origin(), 0)));
-
- auto code = compile(proc);
- CHECK(invoke<intptr_t>(*code, 0) == 1);
- CHECK(invoke<intptr_t>(*code, 1) == 0);
- CHECK(invoke<intptr_t>(*code, 42) == 0);
-}
-
-void testLShiftSelf32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, Shl, Origin(), arg, arg));
-
- auto code = compile(proc);
-
- auto check = [&] (int32_t value) {
- CHECK(invoke<int32_t>(*code, value) == value << (value & 31));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
-}
-
-void testRShiftSelf32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, SShr, Origin(), arg, arg));
-
- auto code = compile(proc);
-
- auto check = [&] (int32_t value) {
- CHECK(invoke<int32_t>(*code, value) == value >> (value & 31));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
-}
-
-void testURShiftSelf32()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<Value>(
- proc, Trunc, Origin(),
- root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0));
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(proc, ZShr, Origin(), arg, arg));
-
- auto code = compile(proc);
-
- auto check = [&] (uint32_t value) {
- CHECK(invoke<uint32_t>(*code, value) == value >> (value & 31));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
-}
-
-void testLShiftSelf64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, Shl, Origin(), arg, root->appendNew<Value>(proc, Trunc, Origin(), arg)));
-
- auto code = compile(proc);
-
- auto check = [&] (int64_t value) {
- CHECK(invoke<int64_t>(*code, value) == value << (value & 63));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
- check(63);
- check(64);
-}
-
-void testRShiftSelf64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, SShr, Origin(), arg, root->appendNew<Value>(proc, Trunc, Origin(), arg)));
-
- auto code = compile(proc);
-
- auto check = [&] (int64_t value) {
- CHECK(invoke<int64_t>(*code, value) == value >> (value & 63));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
- check(63);
- check(64);
-}
-
-void testURShiftSelf64()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), GPRInfo::argumentGPR0);
- root->appendNew<ControlValue>(
- proc, Return, Origin(),
- root->appendNew<Value>(
- proc, ZShr, Origin(), arg, root->appendNew<Value>(proc, Trunc, Origin(), arg)));
-
- auto code = compile(proc);
-
- auto check = [&] (uint64_t value) {
- CHECK(invoke<uint64_t>(*code, value) == value >> (value & 63));
- };
-
- check(0);
- check(1);
- check(31);
- check(32);
- check(63);
- check(64);
-}
-
-void testPatchpointDoubleRegs()
-{
- Procedure proc;
- BasicBlock* root = proc.addBlock();
-
- Value* arg = root->appendNew<ArgumentRegValue>(proc, Origin(), FPRInfo::argumentFPR0);
-
- PatchpointValue* patchpoint = root->appendNew<PatchpointValue>(proc, Double, Origin());
- patchpoint->append(arg, ValueRep(FPRInfo::fpRegT0));
- patchpoint->resultConstraint = ValueRep(FPRInfo::fpRegT0);
-
- unsigned numCalls = 0;
- patchpoint->setGenerator(
- [&] (CCallHelpers&, const StackmapGenerationParams&) {
- numCalls++;
- });
-
- root->appendNew<ControlValue>(proc, Return, Origin(), patchpoint);
-
- auto code = compile(proc);
- CHECK(numCalls == 1);
- CHECK(invoke<double>(*code, 42.5) == 42.5);
-}
-
-// Make sure the compiler does not try to optimize anything out.
-NEVER_INLINE double zero()
-{
- return 0.;
-}
-
-double negativeZero()
-{
- return -zero();
-}
-
-
-
-#define RUN(test) do { \
- if (!shouldRun(#test)) \
- break; \
- tasks.append( \
- createSharedTask<void()>( \
- [&] () { \
- dataLog(#test "...\n"); \
- test; \
- dataLog(#test ": OK!\n"); \
- })); \
- } while (false);
-
-#define RUN_UNARY(test, values) \
- for (auto a : values) { \
- CString testStr = toCString(#test, "(", a.name, ")"); \
- if (!shouldRun(testStr.data())) \
- continue; \
- tasks.append(createSharedTask<void()>( \
- [=] () { \
- dataLog(toCString(testStr, "...\n")); \
- test(a.value); \
- dataLog(toCString(testStr, ": OK!\n")); \
- })); \
- }
-
-#define RUN_BINARY(test, valuesA, valuesB) \
- for (auto a : valuesA) { \
- for (auto b : valuesB) { \
- CString testStr = toCString(#test, "(", a.name, ", ", b.name, ")"); \
- if (!shouldRun(testStr.data())) \
- continue; \
- tasks.append(createSharedTask<void()>( \
- [=] () { \
- dataLog(toCString(testStr, "...\n")); \
- test(a.value, b.value); \
- dataLog(toCString(testStr, ": OK!\n")); \
- })); \
- } \
- }
-
-void run(const char* filter)
-{
- JSC::initializeThreading();
- vm = &VM::create(LargeHeap).leakRef();
-
- Deque<RefPtr<SharedTask<void()>>> tasks;
-
- auto shouldRun = [&] (const char* testName) -> bool {
- return !filter || !!strcasestr(testName, filter);
- };
-
- RUN(test42());
- RUN(testLoad42());
- RUN(testLoadOffsetImm9Max());
- RUN(testLoadOffsetImm9MaxPlusOne());
- RUN(testLoadOffsetImm9MaxPlusTwo());
- RUN(testLoadOffsetImm9Min());
- RUN(testLoadOffsetImm9MinMinusOne());
- RUN(testLoadOffsetScaledUnsignedImm12Max());
- RUN(testLoadOffsetScaledUnsignedOverImm12Max());
- RUN(testArg(43));
- RUN(testReturnConst64(5));
- RUN(testReturnConst64(-42));
-
- RUN(testAddArg(111));
- RUN(testAddArgs(1, 1));
- RUN(testAddArgs(1, 2));
- RUN(testAddArgImm(1, 2));
- RUN(testAddArgImm(0, 2));
- RUN(testAddArgImm(1, 0));
- RUN(testAddImmArg(1, 2));
- RUN(testAddImmArg(0, 2));
- RUN(testAddImmArg(1, 0));
- RUN_BINARY(testAddArgMem, int64Operands(), int64Operands());
- RUN_BINARY(testAddMemArg, int64Operands(), int64Operands());
- RUN_BINARY(testAddImmMem, int64Operands(), int64Operands());
- RUN_UNARY(testAddArg32, int32Operands());
- RUN(testAddArgs32(1, 1));
- RUN(testAddArgs32(1, 2));
- RUN_BINARY(testAddArgMem32, int32Operands(), int32Operands());
- RUN_BINARY(testAddMemArg32, int32Operands(), int32Operands());
- RUN_BINARY(testAddImmMem32, int32Operands(), int32Operands());
- RUN(testAddArgZeroImmZDef());
- RUN(testAddLoadTwice());
-
- RUN(testAddArgDouble(M_PI));
- RUN(testAddArgsDouble(M_PI, 1));
- RUN(testAddArgsDouble(M_PI, -M_PI));
- RUN(testAddArgImmDouble(M_PI, 1));
- RUN(testAddArgImmDouble(M_PI, 0));
- RUN(testAddArgImmDouble(M_PI, negativeZero()));
- RUN(testAddArgImmDouble(0, 0));
- RUN(testAddArgImmDouble(0, negativeZero()));
- RUN(testAddArgImmDouble(negativeZero(), 0));
- RUN(testAddArgImmDouble(negativeZero(), negativeZero()));
- RUN(testAddImmArgDouble(M_PI, 1));
- RUN(testAddImmArgDouble(M_PI, 0));
- RUN(testAddImmArgDouble(M_PI, negativeZero()));
- RUN(testAddImmArgDouble(0, 0));
- RUN(testAddImmArgDouble(0, negativeZero()));
- RUN(testAddImmArgDouble(negativeZero(), 0));
- RUN(testAddImmArgDouble(negativeZero(), negativeZero()));
- RUN(testAddImmsDouble(M_PI, 1));
- RUN(testAddImmsDouble(M_PI, 0));
- RUN(testAddImmsDouble(M_PI, negativeZero()));
- RUN(testAddImmsDouble(0, 0));
- RUN(testAddImmsDouble(0, negativeZero()));
- RUN(testAddImmsDouble(negativeZero(), negativeZero()));
- RUN_UNARY(testAddArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testAddArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testAddArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testAddImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testAddImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_UNARY(testAddArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_BINARY(testAddArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testAddArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN(testMulArg(5));
- RUN(testMulAddArg(5));
- RUN(testMulAddArg(85));
- RUN(testMulArgStore(5));
- RUN(testMulArgStore(85));
- RUN(testMulArgs(1, 1));
- RUN(testMulArgs(1, 2));
- RUN(testMulArgs(3, 3));
- RUN(testMulArgImm(1, 2));
- RUN(testMulArgImm(1, 4));
- RUN(testMulArgImm(1, 8));
- RUN(testMulArgImm(1, 16));
- RUN(testMulArgImm(1, 0x80000000llu));
- RUN(testMulArgImm(1, 0x800000000000llu));
- RUN(testMulArgImm(7, 2));
- RUN(testMulArgImm(7, 4));
- RUN(testMulArgImm(7, 8));
- RUN(testMulArgImm(7, 16));
- RUN(testMulArgImm(7, 0x80000000llu));
- RUN(testMulArgImm(7, 0x800000000000llu));
- RUN(testMulArgImm(-42, 2));
- RUN(testMulArgImm(-42, 4));
- RUN(testMulArgImm(-42, 8));
- RUN(testMulArgImm(-42, 16));
- RUN(testMulArgImm(-42, 0x80000000llu));
- RUN(testMulArgImm(-42, 0x800000000000llu));
- RUN(testMulArgImm(0, 2));
- RUN(testMulArgImm(1, 0));
- RUN(testMulArgImm(3, 3));
- RUN(testMulArgImm(3, -1));
- RUN(testMulArgImm(-3, -1));
- RUN(testMulArgImm(0, -1));
- RUN(testMulImmArg(1, 2));
- RUN(testMulImmArg(0, 2));
- RUN(testMulImmArg(1, 0));
- RUN(testMulImmArg(3, 3));
- RUN(testMulArgs32(1, 1));
- RUN(testMulArgs32(1, 2));
- RUN(testMulLoadTwice());
- RUN(testMulAddArgsLeft());
- RUN(testMulAddArgsRight());
- RUN(testMulAddArgsLeft32());
- RUN(testMulAddArgsRight32());
- RUN(testMulSubArgsLeft());
- RUN(testMulSubArgsRight());
- RUN(testMulSubArgsLeft32());
- RUN(testMulSubArgsRight32());
- RUN(testMulNegArgs());
- RUN(testMulNegArgs32());
-
- RUN_UNARY(testMulArgDouble, floatingPointOperands<double>());
- RUN_BINARY(testMulArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testMulArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testMulImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testMulImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_UNARY(testMulArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testMulArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testMulArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testMulImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testMulImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_UNARY(testMulArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_BINARY(testMulArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testMulArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN(testDivArgDouble(M_PI));
- RUN(testDivArgsDouble(M_PI, 1));
- RUN(testDivArgsDouble(M_PI, -M_PI));
- RUN(testDivArgImmDouble(M_PI, 1));
- RUN(testDivArgImmDouble(M_PI, 0));
- RUN(testDivArgImmDouble(M_PI, negativeZero()));
- RUN(testDivArgImmDouble(0, 0));
- RUN(testDivArgImmDouble(0, negativeZero()));
- RUN(testDivArgImmDouble(negativeZero(), 0));
- RUN(testDivArgImmDouble(negativeZero(), negativeZero()));
- RUN(testDivImmArgDouble(M_PI, 1));
- RUN(testDivImmArgDouble(M_PI, 0));
- RUN(testDivImmArgDouble(M_PI, negativeZero()));
- RUN(testDivImmArgDouble(0, 0));
- RUN(testDivImmArgDouble(0, negativeZero()));
- RUN(testDivImmArgDouble(negativeZero(), 0));
- RUN(testDivImmArgDouble(negativeZero(), negativeZero()));
- RUN(testDivImmsDouble(M_PI, 1));
- RUN(testDivImmsDouble(M_PI, 0));
- RUN(testDivImmsDouble(M_PI, negativeZero()));
- RUN(testDivImmsDouble(0, 0));
- RUN(testDivImmsDouble(0, negativeZero()));
- RUN(testDivImmsDouble(negativeZero(), negativeZero()));
- RUN_UNARY(testDivArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testDivArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testDivArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testDivImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testDivImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_UNARY(testDivArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_BINARY(testDivArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testDivArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN_UNARY(testModArgDouble, floatingPointOperands<double>());
- RUN_BINARY(testModArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testModArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testModImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testModImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_UNARY(testModArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testModArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testModArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testModImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testModImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN(testSubArg(24));
- RUN(testSubArgs(1, 1));
- RUN(testSubArgs(1, 2));
- RUN(testSubArgs(13, -42));
- RUN(testSubArgs(-13, 42));
- RUN(testSubArgImm(1, 1));
- RUN(testSubArgImm(1, 2));
- RUN(testSubArgImm(13, -42));
- RUN(testSubArgImm(-13, 42));
- RUN(testSubArgImm(42, 0));
- RUN(testSubImmArg(1, 1));
- RUN(testSubImmArg(1, 2));
- RUN(testSubImmArg(13, -42));
- RUN(testSubImmArg(-13, 42));
- RUN_BINARY(testSubArgMem, int64Operands(), int64Operands());
- RUN_BINARY(testSubMemArg, int64Operands(), int64Operands());
- RUN_BINARY(testSubImmMem, int32Operands(), int32Operands());
- RUN_BINARY(testSubMemImm, int32Operands(), int32Operands());
- RUN_UNARY(testNegValueSubOne, int32Operands());
-
- RUN(testSubArgs32(1, 1));
- RUN(testSubArgs32(1, 2));
- RUN(testSubArgs32(13, -42));
- RUN(testSubArgs32(-13, 42));
- RUN(testSubArgImm32(1, 1));
- RUN(testSubArgImm32(1, 2));
- RUN(testSubArgImm32(13, -42));
- RUN(testSubArgImm32(-13, 42));
- RUN(testSubImmArg32(1, 1));
- RUN(testSubImmArg32(1, 2));
- RUN(testSubImmArg32(13, -42));
- RUN(testSubImmArg32(-13, 42));
- RUN_BINARY(testSubArgMem32, int32Operands(), int32Operands());
- RUN_BINARY(testSubMemArg32, int32Operands(), int32Operands());
- RUN_BINARY(testSubImmMem32, int32Operands(), int32Operands());
- RUN_BINARY(testSubMemImm32, int32Operands(), int32Operands());
- RUN_UNARY(testNegValueSubOne32, int64Operands());
-
- RUN_UNARY(testSubArgDouble, floatingPointOperands<double>());
- RUN_BINARY(testSubArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testSubArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testSubImmArgDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testSubImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_UNARY(testSubArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testSubArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSubArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSubImmArgFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSubImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_UNARY(testSubArgFloatWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_BINARY(testSubArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSubArgsFloatWithEffectfulDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN(testBitAndArgs(43, 43));
- RUN(testBitAndArgs(43, 0));
- RUN(testBitAndArgs(10, 3));
- RUN(testBitAndArgs(42, 0xffffffffffffffff));
- RUN(testBitAndSameArg(43));
- RUN(testBitAndSameArg(0));
- RUN(testBitAndSameArg(3));
- RUN(testBitAndSameArg(0xffffffffffffffff));
- RUN(testBitAndImms(43, 43));
- RUN(testBitAndImms(43, 0));
- RUN(testBitAndImms(10, 3));
- RUN(testBitAndImms(42, 0xffffffffffffffff));
- RUN(testBitAndArgImm(43, 43));
- RUN(testBitAndArgImm(43, 0));
- RUN(testBitAndArgImm(10, 3));
- RUN(testBitAndArgImm(42, 0xffffffffffffffff));
- RUN(testBitAndArgImm(42, 0xff));
- RUN(testBitAndArgImm(300, 0xff));
- RUN(testBitAndArgImm(-300, 0xff));
- RUN(testBitAndArgImm(42, 0xffff));
- RUN(testBitAndArgImm(40000, 0xffff));
- RUN(testBitAndArgImm(-40000, 0xffff));
- RUN(testBitAndImmArg(43, 43));
- RUN(testBitAndImmArg(43, 0));
- RUN(testBitAndImmArg(10, 3));
- RUN(testBitAndImmArg(42, 0xffffffffffffffff));
- RUN(testBitAndBitAndArgImmImm(2, 7, 3));
- RUN(testBitAndBitAndArgImmImm(1, 6, 6));
- RUN(testBitAndBitAndArgImmImm(0xffff, 24, 7));
- RUN(testBitAndImmBitAndArgImm(7, 2, 3));
- RUN(testBitAndImmBitAndArgImm(6, 1, 6));
- RUN(testBitAndImmBitAndArgImm(24, 0xffff, 7));
- RUN(testBitAndArgs32(43, 43));
- RUN(testBitAndArgs32(43, 0));
- RUN(testBitAndArgs32(10, 3));
- RUN(testBitAndArgs32(42, 0xffffffff));
- RUN(testBitAndSameArg32(43));
- RUN(testBitAndSameArg32(0));
- RUN(testBitAndSameArg32(3));
- RUN(testBitAndSameArg32(0xffffffff));
- RUN(testBitAndImms32(43, 43));
- RUN(testBitAndImms32(43, 0));
- RUN(testBitAndImms32(10, 3));
- RUN(testBitAndImms32(42, 0xffffffff));
- RUN(testBitAndArgImm32(43, 43));
- RUN(testBitAndArgImm32(43, 0));
- RUN(testBitAndArgImm32(10, 3));
- RUN(testBitAndArgImm32(42, 0xffffffff));
- RUN(testBitAndImmArg32(43, 43));
- RUN(testBitAndImmArg32(43, 0));
- RUN(testBitAndImmArg32(10, 3));
- RUN(testBitAndImmArg32(42, 0xffffffff));
- RUN(testBitAndImmArg32(42, 0xff));
- RUN(testBitAndImmArg32(300, 0xff));
- RUN(testBitAndImmArg32(-300, 0xff));
- RUN(testBitAndImmArg32(42, 0xffff));
- RUN(testBitAndImmArg32(40000, 0xffff));
- RUN(testBitAndImmArg32(-40000, 0xffff));
- RUN(testBitAndBitAndArgImmImm32(2, 7, 3));
- RUN(testBitAndBitAndArgImmImm32(1, 6, 6));
- RUN(testBitAndBitAndArgImmImm32(0xffff, 24, 7));
- RUN(testBitAndImmBitAndArgImm32(7, 2, 3));
- RUN(testBitAndImmBitAndArgImm32(6, 1, 6));
- RUN(testBitAndImmBitAndArgImm32(24, 0xffff, 7));
- RUN_BINARY(testBitAndWithMaskReturnsBooleans, int64Operands(), int64Operands());
- RUN_UNARY(testBitAndArgDouble, floatingPointOperands<double>());
- RUN_BINARY(testBitAndArgsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBitAndArgImmDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBitAndImmsDouble, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_UNARY(testBitAndArgFloat, floatingPointOperands<float>());
- RUN_BINARY(testBitAndArgsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBitAndArgImmFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBitAndImmsFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBitAndArgsFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
-
- RUN(testBitOrArgs(43, 43));
- RUN(testBitOrArgs(43, 0));
- RUN(testBitOrArgs(10, 3));
- RUN(testBitOrArgs(42, 0xffffffffffffffff));
- RUN(testBitOrSameArg(43));
- RUN(testBitOrSameArg(0));
- RUN(testBitOrSameArg(3));
- RUN(testBitOrSameArg(0xffffffffffffffff));
- RUN(testBitOrImms(43, 43));
- RUN(testBitOrImms(43, 0));
- RUN(testBitOrImms(10, 3));
- RUN(testBitOrImms(42, 0xffffffffffffffff));
- RUN(testBitOrArgImm(43, 43));
- RUN(testBitOrArgImm(43, 0));
- RUN(testBitOrArgImm(10, 3));
- RUN(testBitOrArgImm(42, 0xffffffffffffffff));
- RUN(testBitOrImmArg(43, 43));
- RUN(testBitOrImmArg(43, 0));
- RUN(testBitOrImmArg(10, 3));
- RUN(testBitOrImmArg(42, 0xffffffffffffffff));
- RUN(testBitOrBitOrArgImmImm(2, 7, 3));
- RUN(testBitOrBitOrArgImmImm(1, 6, 6));
- RUN(testBitOrBitOrArgImmImm(0xffff, 24, 7));
- RUN(testBitOrImmBitOrArgImm(7, 2, 3));
- RUN(testBitOrImmBitOrArgImm(6, 1, 6));
- RUN(testBitOrImmBitOrArgImm(24, 0xffff, 7));
- RUN(testBitOrArgs32(43, 43));
- RUN(testBitOrArgs32(43, 0));
- RUN(testBitOrArgs32(10, 3));
- RUN(testBitOrArgs32(42, 0xffffffff));
- RUN(testBitOrSameArg32(43));
- RUN(testBitOrSameArg32(0));
- RUN(testBitOrSameArg32(3));
- RUN(testBitOrSameArg32(0xffffffff));
- RUN(testBitOrImms32(43, 43));
- RUN(testBitOrImms32(43, 0));
- RUN(testBitOrImms32(10, 3));
- RUN(testBitOrImms32(42, 0xffffffff));
- RUN(testBitOrArgImm32(43, 43));
- RUN(testBitOrArgImm32(43, 0));
- RUN(testBitOrArgImm32(10, 3));
- RUN(testBitOrArgImm32(42, 0xffffffff));
- RUN(testBitOrImmArg32(43, 43));
- RUN(testBitOrImmArg32(43, 0));
- RUN(testBitOrImmArg32(10, 3));
- RUN(testBitOrImmArg32(42, 0xffffffff));
- RUN(testBitOrBitOrArgImmImm32(2, 7, 3));
- RUN(testBitOrBitOrArgImmImm32(1, 6, 6));
- RUN(testBitOrBitOrArgImmImm32(0xffff, 24, 7));
- RUN(testBitOrImmBitOrArgImm32(7, 2, 3));
- RUN(testBitOrImmBitOrArgImm32(6, 1, 6));
- RUN(testBitOrImmBitOrArgImm32(24, 0xffff, 7));
-
- RUN_BINARY(testBitXorArgs, int64Operands(), int64Operands());
- RUN_UNARY(testBitXorSameArg, int64Operands());
- RUN_BINARY(testBitXorImms, int64Operands(), int64Operands());
- RUN_BINARY(testBitXorArgImm, int64Operands(), int64Operands());
- RUN_BINARY(testBitXorImmArg, int64Operands(), int64Operands());
- RUN(testBitXorBitXorArgImmImm(2, 7, 3));
- RUN(testBitXorBitXorArgImmImm(1, 6, 6));
- RUN(testBitXorBitXorArgImmImm(0xffff, 24, 7));
- RUN(testBitXorImmBitXorArgImm(7, 2, 3));
- RUN(testBitXorImmBitXorArgImm(6, 1, 6));
- RUN(testBitXorImmBitXorArgImm(24, 0xffff, 7));
- RUN(testBitXorArgs32(43, 43));
- RUN(testBitXorArgs32(43, 0));
- RUN(testBitXorArgs32(10, 3));
- RUN(testBitXorArgs32(42, 0xffffffff));
- RUN(testBitXorSameArg32(43));
- RUN(testBitXorSameArg32(0));
- RUN(testBitXorSameArg32(3));
- RUN(testBitXorSameArg32(0xffffffff));
- RUN(testBitXorImms32(43, 43));
- RUN(testBitXorImms32(43, 0));
- RUN(testBitXorImms32(10, 3));
- RUN(testBitXorImms32(42, 0xffffffff));
- RUN(testBitXorArgImm32(43, 43));
- RUN(testBitXorArgImm32(43, 0));
- RUN(testBitXorArgImm32(10, 3));
- RUN(testBitXorArgImm32(42, 0xffffffff));
- RUN(testBitXorImmArg32(43, 43));
- RUN(testBitXorImmArg32(43, 0));
- RUN(testBitXorImmArg32(10, 3));
- RUN(testBitXorImmArg32(42, 0xffffffff));
- RUN(testBitXorBitXorArgImmImm32(2, 7, 3));
- RUN(testBitXorBitXorArgImmImm32(1, 6, 6));
- RUN(testBitXorBitXorArgImmImm32(0xffff, 24, 7));
- RUN(testBitXorImmBitXorArgImm32(7, 2, 3));
- RUN(testBitXorImmBitXorArgImm32(6, 1, 6));
- RUN(testBitXorImmBitXorArgImm32(24, 0xffff, 7));
-
- RUN_UNARY(testBitNotArg, int64Operands());
- RUN_UNARY(testBitNotImm, int64Operands());
- RUN_UNARY(testBitNotMem, int64Operands());
- RUN_UNARY(testBitNotArg32, int32Operands());
- RUN_UNARY(testBitNotImm32, int32Operands());
- RUN_UNARY(testBitNotMem32, int32Operands());
- RUN_BINARY(testBitNotOnBooleanAndBranch32, int32Operands(), int32Operands());
-
- RUN(testShlArgs(1, 0));
- RUN(testShlArgs(1, 1));
- RUN(testShlArgs(1, 62));
- RUN(testShlArgs(0xffffffffffffffff, 0));
- RUN(testShlArgs(0xffffffffffffffff, 1));
- RUN(testShlArgs(0xffffffffffffffff, 63));
- RUN(testShlImms(1, 0));
- RUN(testShlImms(1, 1));
- RUN(testShlImms(1, 62));
- RUN(testShlImms(1, 65));
- RUN(testShlImms(0xffffffffffffffff, 0));
- RUN(testShlImms(0xffffffffffffffff, 1));
- RUN(testShlImms(0xffffffffffffffff, 63));
- RUN(testShlArgImm(1, 0));
- RUN(testShlArgImm(1, 1));
- RUN(testShlArgImm(1, 62));
- RUN(testShlArgImm(1, 65));
- RUN(testShlArgImm(0xffffffffffffffff, 0));
- RUN(testShlArgImm(0xffffffffffffffff, 1));
- RUN(testShlArgImm(0xffffffffffffffff, 63));
- RUN(testShlArg32(2));
- RUN(testShlArgs32(1, 0));
- RUN(testShlArgs32(1, 1));
- RUN(testShlArgs32(1, 62));
- RUN(testShlImms32(1, 33));
- RUN(testShlArgs32(0xffffffff, 0));
- RUN(testShlArgs32(0xffffffff, 1));
- RUN(testShlArgs32(0xffffffff, 63));
- RUN(testShlImms32(1, 0));
- RUN(testShlImms32(1, 1));
- RUN(testShlImms32(1, 62));
- RUN(testShlImms32(1, 33));
- RUN(testShlImms32(0xffffffff, 0));
- RUN(testShlImms32(0xffffffff, 1));
- RUN(testShlImms32(0xffffffff, 63));
- RUN(testShlArgImm32(1, 0));
- RUN(testShlArgImm32(1, 1));
- RUN(testShlArgImm32(1, 62));
- RUN(testShlArgImm32(0xffffffff, 0));
- RUN(testShlArgImm32(0xffffffff, 1));
- RUN(testShlArgImm32(0xffffffff, 63));
-
- RUN(testSShrArgs(1, 0));
- RUN(testSShrArgs(1, 1));
- RUN(testSShrArgs(1, 62));
- RUN(testSShrArgs(0xffffffffffffffff, 0));
- RUN(testSShrArgs(0xffffffffffffffff, 1));
- RUN(testSShrArgs(0xffffffffffffffff, 63));
- RUN(testSShrImms(1, 0));
- RUN(testSShrImms(1, 1));
- RUN(testSShrImms(1, 62));
- RUN(testSShrImms(1, 65));
- RUN(testSShrImms(0xffffffffffffffff, 0));
- RUN(testSShrImms(0xffffffffffffffff, 1));
- RUN(testSShrImms(0xffffffffffffffff, 63));
- RUN(testSShrArgImm(1, 0));
- RUN(testSShrArgImm(1, 1));
- RUN(testSShrArgImm(1, 62));
- RUN(testSShrArgImm(1, 65));
- RUN(testSShrArgImm(0xffffffffffffffff, 0));
- RUN(testSShrArgImm(0xffffffffffffffff, 1));
- RUN(testSShrArgImm(0xffffffffffffffff, 63));
- RUN(testSShrArg32(32));
- RUN(testSShrArgs32(1, 0));
- RUN(testSShrArgs32(1, 1));
- RUN(testSShrArgs32(1, 62));
- RUN(testSShrArgs32(1, 33));
- RUN(testSShrArgs32(0xffffffff, 0));
- RUN(testSShrArgs32(0xffffffff, 1));
- RUN(testSShrArgs32(0xffffffff, 63));
- RUN(testSShrImms32(1, 0));
- RUN(testSShrImms32(1, 1));
- RUN(testSShrImms32(1, 62));
- RUN(testSShrImms32(1, 33));
- RUN(testSShrImms32(0xffffffff, 0));
- RUN(testSShrImms32(0xffffffff, 1));
- RUN(testSShrImms32(0xffffffff, 63));
- RUN(testSShrArgImm32(1, 0));
- RUN(testSShrArgImm32(1, 1));
- RUN(testSShrArgImm32(1, 62));
- RUN(testSShrArgImm32(0xffffffff, 0));
- RUN(testSShrArgImm32(0xffffffff, 1));
- RUN(testSShrArgImm32(0xffffffff, 63));
-
- RUN(testZShrArgs(1, 0));
- RUN(testZShrArgs(1, 1));
- RUN(testZShrArgs(1, 62));
- RUN(testZShrArgs(0xffffffffffffffff, 0));
- RUN(testZShrArgs(0xffffffffffffffff, 1));
- RUN(testZShrArgs(0xffffffffffffffff, 63));
- RUN(testZShrImms(1, 0));
- RUN(testZShrImms(1, 1));
- RUN(testZShrImms(1, 62));
- RUN(testZShrImms(1, 65));
- RUN(testZShrImms(0xffffffffffffffff, 0));
- RUN(testZShrImms(0xffffffffffffffff, 1));
- RUN(testZShrImms(0xffffffffffffffff, 63));
- RUN(testZShrArgImm(1, 0));
- RUN(testZShrArgImm(1, 1));
- RUN(testZShrArgImm(1, 62));
- RUN(testZShrArgImm(1, 65));
- RUN(testZShrArgImm(0xffffffffffffffff, 0));
- RUN(testZShrArgImm(0xffffffffffffffff, 1));
- RUN(testZShrArgImm(0xffffffffffffffff, 63));
- RUN(testZShrArg32(32));
- RUN(testZShrArgs32(1, 0));
- RUN(testZShrArgs32(1, 1));
- RUN(testZShrArgs32(1, 62));
- RUN(testZShrArgs32(1, 33));
- RUN(testZShrArgs32(0xffffffff, 0));
- RUN(testZShrArgs32(0xffffffff, 1));
- RUN(testZShrArgs32(0xffffffff, 63));
- RUN(testZShrImms32(1, 0));
- RUN(testZShrImms32(1, 1));
- RUN(testZShrImms32(1, 62));
- RUN(testZShrImms32(1, 33));
- RUN(testZShrImms32(0xffffffff, 0));
- RUN(testZShrImms32(0xffffffff, 1));
- RUN(testZShrImms32(0xffffffff, 63));
- RUN(testZShrArgImm32(1, 0));
- RUN(testZShrArgImm32(1, 1));
- RUN(testZShrArgImm32(1, 62));
- RUN(testZShrArgImm32(0xffffffff, 0));
- RUN(testZShrArgImm32(0xffffffff, 1));
- RUN(testZShrArgImm32(0xffffffff, 63));
-
- RUN_UNARY(testClzArg64, int64Operands());
- RUN_UNARY(testClzMem64, int64Operands());
- RUN_UNARY(testClzArg32, int32Operands());
- RUN_UNARY(testClzMem32, int64Operands());
-
- RUN_UNARY(testAbsArg, floatingPointOperands<double>());
- RUN_UNARY(testAbsImm, floatingPointOperands<double>());
- RUN_UNARY(testAbsMem, floatingPointOperands<double>());
- RUN_UNARY(testAbsAbsArg, floatingPointOperands<double>());
- RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<double>());
- RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<double>());
- RUN_UNARY(testAbsArg, floatingPointOperands<float>());
- RUN_UNARY(testAbsImm, floatingPointOperands<float>());
- RUN_UNARY(testAbsMem, floatingPointOperands<float>());
- RUN_UNARY(testAbsAbsArg, floatingPointOperands<float>());
- RUN_UNARY(testAbsBitwiseCastArg, floatingPointOperands<float>());
- RUN_UNARY(testBitwiseCastAbsBitwiseCastArg, floatingPointOperands<float>());
- RUN_UNARY(testAbsArgWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_UNARY(testAbsArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
-
- RUN_UNARY(testCeilArg, floatingPointOperands<double>());
- RUN_UNARY(testCeilImm, floatingPointOperands<double>());
- RUN_UNARY(testCeilMem, floatingPointOperands<double>());
- RUN_UNARY(testCeilCeilArg, floatingPointOperands<double>());
- RUN_UNARY(testFloorCeilArg, floatingPointOperands<double>());
- RUN_UNARY(testCeilIToD64, int64Operands());
- RUN_UNARY(testCeilIToD32, int32Operands());
- RUN_UNARY(testCeilArg, floatingPointOperands<float>());
- RUN_UNARY(testCeilImm, floatingPointOperands<float>());
- RUN_UNARY(testCeilMem, floatingPointOperands<float>());
- RUN_UNARY(testCeilCeilArg, floatingPointOperands<float>());
- RUN_UNARY(testFloorCeilArg, floatingPointOperands<float>());
- RUN_UNARY(testCeilArgWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_UNARY(testCeilArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
-
- RUN_UNARY(testFloorArg, floatingPointOperands<double>());
- RUN_UNARY(testFloorImm, floatingPointOperands<double>());
- RUN_UNARY(testFloorMem, floatingPointOperands<double>());
- RUN_UNARY(testFloorFloorArg, floatingPointOperands<double>());
- RUN_UNARY(testCeilFloorArg, floatingPointOperands<double>());
- RUN_UNARY(testFloorIToD64, int64Operands());
- RUN_UNARY(testFloorIToD32, int32Operands());
- RUN_UNARY(testFloorArg, floatingPointOperands<float>());
- RUN_UNARY(testFloorImm, floatingPointOperands<float>());
- RUN_UNARY(testFloorMem, floatingPointOperands<float>());
- RUN_UNARY(testFloorFloorArg, floatingPointOperands<float>());
- RUN_UNARY(testCeilFloorArg, floatingPointOperands<float>());
- RUN_UNARY(testFloorArgWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_UNARY(testFloorArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
-
- RUN_UNARY(testSqrtArg, floatingPointOperands<double>());
- RUN_UNARY(testSqrtImm, floatingPointOperands<double>());
- RUN_UNARY(testSqrtMem, floatingPointOperands<double>());
- RUN_UNARY(testSqrtArg, floatingPointOperands<float>());
- RUN_UNARY(testSqrtImm, floatingPointOperands<float>());
- RUN_UNARY(testSqrtMem, floatingPointOperands<float>());
- RUN_UNARY(testSqrtArgWithUselessDoubleConversion, floatingPointOperands<float>());
- RUN_UNARY(testSqrtArgWithEffectfulDoubleConversion, floatingPointOperands<float>());
-
- RUN_UNARY(testDoubleArgToInt64BitwiseCast, floatingPointOperands<double>());
- RUN_UNARY(testDoubleImmToInt64BitwiseCast, floatingPointOperands<double>());
- RUN_UNARY(testTwoBitwiseCastOnDouble, floatingPointOperands<double>());
- RUN_UNARY(testBitwiseCastOnDoubleInMemory, floatingPointOperands<double>());
- RUN_UNARY(testBitwiseCastOnDoubleInMemoryIndexed, floatingPointOperands<double>());
- RUN_UNARY(testInt64BArgToDoubleBitwiseCast, int64Operands());
- RUN_UNARY(testInt64BImmToDoubleBitwiseCast, int64Operands());
- RUN_UNARY(testTwoBitwiseCastOnInt64, int64Operands());
- RUN_UNARY(testBitwiseCastOnInt64InMemory, int64Operands());
- RUN_UNARY(testBitwiseCastOnInt64InMemoryIndexed, int64Operands());
- RUN_UNARY(testFloatImmToInt32BitwiseCast, floatingPointOperands<float>());
- RUN_UNARY(testBitwiseCastOnFloatInMemory, floatingPointOperands<float>());
- RUN_UNARY(testInt32BArgToFloatBitwiseCast, int32Operands());
- RUN_UNARY(testInt32BImmToFloatBitwiseCast, int32Operands());
- RUN_UNARY(testTwoBitwiseCastOnInt32, int32Operands());
- RUN_UNARY(testBitwiseCastOnInt32InMemory, int32Operands());
-
- RUN_UNARY(testConvertDoubleToFloatArg, floatingPointOperands<double>());
- RUN_UNARY(testConvertDoubleToFloatImm, floatingPointOperands<double>());
- RUN_UNARY(testConvertDoubleToFloatMem, floatingPointOperands<double>());
- RUN_UNARY(testConvertFloatToDoubleArg, floatingPointOperands<float>());
- RUN_UNARY(testConvertFloatToDoubleImm, floatingPointOperands<float>());
- RUN_UNARY(testConvertFloatToDoubleMem, floatingPointOperands<float>());
- RUN_UNARY(testConvertDoubleToFloatToDoubleToFloat, floatingPointOperands<double>());
- RUN_UNARY(testStoreFloat, floatingPointOperands<double>());
- RUN_UNARY(testLoadFloatConvertDoubleConvertFloatStoreFloat, floatingPointOperands<float>());
- RUN_UNARY(testFroundArg, floatingPointOperands<double>());
- RUN_UNARY(testFroundMem, floatingPointOperands<double>());
-
- RUN(testStore32(44));
- RUN(testStoreConstant(49));
- RUN(testStoreConstantPtr(49));
- RUN(testStore8Arg());
- RUN(testStore8Imm());
- RUN(testStorePartial8BitRegisterOnX86());
- RUN(testStore16Arg());
- RUN(testStore16Imm());
- RUN(testTrunc((static_cast<int64_t>(1) << 40) + 42));
- RUN(testAdd1(45));
- RUN(testAdd1Ptr(51));
- RUN(testAdd1Ptr(bitwise_cast<intptr_t>(vm)));
- RUN(testNeg32(52));
- RUN(testNegPtr(53));
- RUN(testStoreAddLoad32(46));
- RUN(testStoreAddLoadImm32(46));
- RUN(testStoreAddLoad64(4600));
- RUN(testStoreAddLoadImm64(4600));
- RUN(testStoreAddLoad8(4, Load8Z));
- RUN(testStoreAddLoadImm8(4, Load8Z));
- RUN(testStoreAddLoad8(4, Load8S));
- RUN(testStoreAddLoadImm8(4, Load8S));
- RUN(testStoreAddLoad16(6, Load16Z));
- RUN(testStoreAddLoadImm16(6, Load16Z));
- RUN(testStoreAddLoad16(6, Load16S));
- RUN(testStoreAddLoadImm16(6, Load16S));
- RUN(testStoreAddLoad32Index(46));
- RUN(testStoreAddLoadImm32Index(46));
- RUN(testStoreAddLoad64Index(4600));
- RUN(testStoreAddLoadImm64Index(4600));
- RUN(testStoreAddLoad8Index(4, Load8Z));
- RUN(testStoreAddLoadImm8Index(4, Load8Z));
- RUN(testStoreAddLoad8Index(4, Load8S));
- RUN(testStoreAddLoadImm8Index(4, Load8S));
- RUN(testStoreAddLoad16Index(6, Load16Z));
- RUN(testStoreAddLoadImm16Index(6, Load16Z));
- RUN(testStoreAddLoad16Index(6, Load16S));
- RUN(testStoreAddLoadImm16Index(6, Load16S));
- RUN(testStoreSubLoad(46));
- RUN(testStoreAddLoadInterference(52));
- RUN(testStoreAddAndLoad(47, 0xffff));
- RUN(testStoreAddAndLoad(470000, 0xffff));
- RUN(testStoreNegLoad32(54));
- RUN(testStoreNegLoadPtr(55));
- RUN(testAdd1Uncommuted(48));
- RUN(testLoadOffset());
- RUN(testLoadOffsetNotConstant());
- RUN(testLoadOffsetUsingAdd());
- RUN(testLoadOffsetUsingAddInterference());
- RUN(testLoadOffsetUsingAddNotConstant());
- RUN(testLoadAddrShift(0));
- RUN(testLoadAddrShift(1));
- RUN(testLoadAddrShift(2));
- RUN(testLoadAddrShift(3));
- RUN(testFramePointer());
- RUN(testOverrideFramePointer());
- RUN(testStackSlot());
- RUN(testLoadFromFramePointer());
- RUN(testStoreLoadStackSlot(50));
-
- RUN(testBranch());
- RUN(testBranchPtr());
- RUN(testDiamond());
- RUN(testBranchNotEqual());
- RUN(testBranchNotEqualCommute());
- RUN(testBranchNotEqualNotEqual());
- RUN(testBranchEqual());
- RUN(testBranchEqualEqual());
- RUN(testBranchEqualCommute());
- RUN(testBranchEqualEqual1());
- RUN_BINARY(testBranchEqualOrUnorderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBranchEqualOrUnorderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBranchEqualOrUnorderedDoubleArgImm, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBranchEqualOrUnorderedFloatArgImm, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBranchEqualOrUnorderedDoubleImms, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBranchEqualOrUnorderedFloatImms, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBranchEqualOrUnorderedFloatWithUselessDoubleConversion, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<double>(), floatingPointOperands<double>());
- RUN_BINARY(testBranchNotEqualAndOrderedArgs, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN(testBranchFold(42));
- RUN(testBranchFold(0));
- RUN(testDiamondFold(42));
- RUN(testDiamondFold(0));
- RUN(testBranchNotEqualFoldPtr(42));
- RUN(testBranchNotEqualFoldPtr(0));
- RUN(testBranchEqualFoldPtr(42));
- RUN(testBranchEqualFoldPtr(0));
- RUN(testBranchLoadPtr());
- RUN(testBranchLoad32());
- RUN(testBranchLoad8S());
- RUN(testBranchLoad8Z());
- RUN(testBranchLoad16S());
- RUN(testBranchLoad16Z());
-
- RUN(testComplex(64, 128));
- RUN(testComplex(4, 128));
- RUN(testComplex(4, 256));
- RUN(testComplex(4, 384));
-
- RUN(testSimplePatchpoint());
- RUN(testSimplePatchpointWithoutOuputClobbersGPArgs());
- RUN(testSimplePatchpointWithOuputClobbersGPArgs());
- RUN(testSimplePatchpointWithoutOuputClobbersFPArgs());
- RUN(testSimplePatchpointWithOuputClobbersFPArgs());
- RUN(testPatchpointWithEarlyClobber());
- RUN(testPatchpointCallArg());
- RUN(testPatchpointFixedRegister());
- RUN(testPatchpointAny(ValueRep::WarmAny));
- RUN(testPatchpointAny(ValueRep::ColdAny));
- RUN(testPatchpointGPScratch());
- RUN(testPatchpointFPScratch());
- RUN(testPatchpointLotsOfLateAnys());
- RUN(testPatchpointAnyImm(ValueRep::WarmAny));
- RUN(testPatchpointAnyImm(ValueRep::ColdAny));
- RUN(testPatchpointAnyImm(ValueRep::LateColdAny));
- RUN(testPatchpointManyImms());
- RUN(testPatchpointWithRegisterResult());
- RUN(testPatchpointWithStackArgumentResult());
- RUN(testPatchpointWithAnyResult());
- RUN(testSimpleCheck());
- RUN(testCheckFalse());
- RUN(testCheckTrue());
- RUN(testCheckLessThan());
- RUN(testCheckMegaCombo());
- RUN(testCheckTrickyMegaCombo());
- RUN(testCheckTwoMegaCombos());
- RUN(testCheckTwoNonRedundantMegaCombos());
- RUN(testCheckAddImm());
- RUN(testCheckAddImmCommute());
- RUN(testCheckAddImmSomeRegister());
- RUN(testCheckAdd());
- RUN(testCheckAdd64());
- RUN(testCheckAddFold(100, 200));
- RUN(testCheckAddFoldFail(2147483647, 100));
- RUN(testCheckAddArgumentAliasing64());
- RUN(testCheckAddArgumentAliasing32());
- RUN(testCheckAddSelfOverflow64());
- RUN(testCheckAddSelfOverflow32());
- RUN(testCheckSubImm());
- RUN(testCheckSubBadImm());
- RUN(testCheckSub());
- RUN(testCheckSub64());
- RUN(testCheckSubFold(100, 200));
- RUN(testCheckSubFoldFail(-2147483647, 100));
- RUN(testCheckNeg());
- RUN(testCheckNeg64());
- RUN(testCheckMul());
- RUN(testCheckMulMemory());
- RUN(testCheckMul2());
- RUN(testCheckMul64());
- RUN(testCheckMulFold(100, 200));
- RUN(testCheckMulFoldFail(2147483647, 100));
- RUN(testCheckMulArgumentAliasing64());
- RUN(testCheckMulArgumentAliasing32());
-
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(Equal, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(NotEqual, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessThan, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterThan, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(LessEqual, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(GreaterEqual, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(Below, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(Above, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(BelowEqual, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(AboveEqual, a, b); }, int64Operands(), int64Operands());
- RUN_BINARY([](int32_t a, int32_t b) { testCompare(BitAnd, a, b); }, int64Operands(), int64Operands());
-
- RUN(testEqualDouble(42, 42, true));
- RUN(testEqualDouble(0, -0, true));
- RUN(testEqualDouble(42, 43, false));
- RUN(testEqualDouble(PNaN, 42, false));
- RUN(testEqualDouble(42, PNaN, false));
- RUN(testEqualDouble(PNaN, PNaN, false));
-
- RUN(testLoad<Int32>(60));
- RUN(testLoad<Int32>(-60));
- RUN(testLoad<Int32>(1000));
- RUN(testLoad<Int32>(-1000));
- RUN(testLoad<Int32>(1000000));
- RUN(testLoad<Int32>(-1000000));
- RUN(testLoad<Int32>(1000000000));
- RUN(testLoad<Int32>(-1000000000));
- RUN_UNARY(testLoad<Int64>, int64Operands());
- RUN_UNARY(testLoad<Float>, floatingPointOperands<float>());
- RUN_UNARY(testLoad<Double>, floatingPointOperands<double>());
-
- RUN(testLoad<int8_t>(Load8S, 60));
- RUN(testLoad<int8_t>(Load8S, -60));
- RUN(testLoad<int8_t>(Load8S, 1000));
- RUN(testLoad<int8_t>(Load8S, -1000));
- RUN(testLoad<int8_t>(Load8S, 1000000));
- RUN(testLoad<int8_t>(Load8S, -1000000));
- RUN(testLoad<int8_t>(Load8S, 1000000000));
- RUN(testLoad<int8_t>(Load8S, -1000000000));
-
- RUN(testLoad<uint8_t>(Load8Z, 60));
- RUN(testLoad<uint8_t>(Load8Z, -60));
- RUN(testLoad<uint8_t>(Load8Z, 1000));
- RUN(testLoad<uint8_t>(Load8Z, -1000));
- RUN(testLoad<uint8_t>(Load8Z, 1000000));
- RUN(testLoad<uint8_t>(Load8Z, -1000000));
- RUN(testLoad<uint8_t>(Load8Z, 1000000000));
- RUN(testLoad<uint8_t>(Load8Z, -1000000000));
-
- RUN(testLoad<int16_t>(Load16S, 60));
- RUN(testLoad<int16_t>(Load16S, -60));
- RUN(testLoad<int16_t>(Load16S, 1000));
- RUN(testLoad<int16_t>(Load16S, -1000));
- RUN(testLoad<int16_t>(Load16S, 1000000));
- RUN(testLoad<int16_t>(Load16S, -1000000));
- RUN(testLoad<int16_t>(Load16S, 1000000000));
- RUN(testLoad<int16_t>(Load16S, -1000000000));
-
- RUN(testLoad<uint16_t>(Load16Z, 60));
- RUN(testLoad<uint16_t>(Load16Z, -60));
- RUN(testLoad<uint16_t>(Load16Z, 1000));
- RUN(testLoad<uint16_t>(Load16Z, -1000));
- RUN(testLoad<uint16_t>(Load16Z, 1000000));
- RUN(testLoad<uint16_t>(Load16Z, -1000000));
- RUN(testLoad<uint16_t>(Load16Z, 1000000000));
- RUN(testLoad<uint16_t>(Load16Z, -1000000000));
-
- RUN(testSpillGP());
- RUN(testSpillFP());
-
- RUN(testInt32ToDoublePartialRegisterStall());
- RUN(testInt32ToDoublePartialRegisterWithoutStall());
-
- RUN(testCallSimple(1, 2));
- RUN(testCallRare(1, 2));
- RUN(testCallRareLive(1, 2, 3));
- RUN(testCallSimplePure(1, 2));
- RUN(testCallFunctionWithHellaArguments());
-
- RUN(testReturnDouble(0.0));
- RUN(testReturnDouble(negativeZero()));
- RUN(testReturnDouble(42.5));
- RUN_UNARY(testReturnFloat, floatingPointOperands<float>());
-
- RUN(testCallSimpleDouble(1, 2));
- RUN(testCallFunctionWithHellaDoubleArguments());
- RUN_BINARY(testCallSimpleFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN(testCallFunctionWithHellaFloatArguments());
-
- RUN(testChillDiv(4, 2, 2));
- RUN(testChillDiv(1, 0, 0));
- RUN(testChillDiv(0, 0, 0));
- RUN(testChillDiv(1, -1, -1));
- RUN(testChillDiv(-2147483647 - 1, 0, 0));
- RUN(testChillDiv(-2147483647 - 1, 1, -2147483647 - 1));
- RUN(testChillDiv(-2147483647 - 1, -1, -2147483647 - 1));
- RUN(testChillDiv(-2147483647 - 1, 2, -1073741824));
- RUN(testChillDiv64(4, 2, 2));
- RUN(testChillDiv64(1, 0, 0));
- RUN(testChillDiv64(0, 0, 0));
- RUN(testChillDiv64(1, -1, -1));
- RUN(testChillDiv64(-9223372036854775807ll - 1, 0, 0));
- RUN(testChillDiv64(-9223372036854775807ll - 1, 1, -9223372036854775807ll - 1));
- RUN(testChillDiv64(-9223372036854775807ll - 1, -1, -9223372036854775807ll - 1));
- RUN(testChillDiv64(-9223372036854775807ll - 1, 2, -4611686018427387904));
- RUN(testChillDivTwice(4, 2, 6, 2, 5));
- RUN(testChillDivTwice(4, 0, 6, 2, 3));
- RUN(testChillDivTwice(4, 2, 6, 0, 2));
-
- RUN_UNARY(testModArg, int64Operands());
- RUN_BINARY(testModArgs, int64Operands(), int64Operands());
- RUN_BINARY(testModImms, int64Operands(), int64Operands());
- RUN_UNARY(testModArg32, int32Operands());
- RUN_BINARY(testModArgs32, int32Operands(), int32Operands());
- RUN_BINARY(testModImms32, int32Operands(), int32Operands());
- RUN_UNARY(testChillModArg, int64Operands());
- RUN_BINARY(testChillModArgs, int64Operands(), int64Operands());
- RUN_BINARY(testChillModImms, int64Operands(), int64Operands());
- RUN_UNARY(testChillModArg32, int32Operands());
- RUN_BINARY(testChillModArgs32, int32Operands(), int32Operands());
- RUN_BINARY(testChillModImms32, int32Operands(), int32Operands());
-
- RUN(testSwitch(0, 1));
- RUN(testSwitch(1, 1));
- RUN(testSwitch(2, 1));
- RUN(testSwitch(2, 2));
- RUN(testSwitch(10, 1));
- RUN(testSwitch(10, 2));
- RUN(testSwitch(100, 1));
- RUN(testSwitch(100, 100));
-
- RUN(testSwitchChillDiv(0, 1));
- RUN(testSwitchChillDiv(1, 1));
- RUN(testSwitchChillDiv(2, 1));
- RUN(testSwitchChillDiv(2, 2));
- RUN(testSwitchChillDiv(10, 1));
- RUN(testSwitchChillDiv(10, 2));
- RUN(testSwitchChillDiv(100, 1));
- RUN(testSwitchChillDiv(100, 100));
-
- RUN(testSwitchTargettingSameBlock());
- RUN(testSwitchTargettingSameBlockFoldPathConstant());
-
- RUN(testTrunc(0));
- RUN(testTrunc(1));
- RUN(testTrunc(-1));
- RUN(testTrunc(1000000000000ll));
- RUN(testTrunc(-1000000000000ll));
- RUN(testTruncFold(0));
- RUN(testTruncFold(1));
- RUN(testTruncFold(-1));
- RUN(testTruncFold(1000000000000ll));
- RUN(testTruncFold(-1000000000000ll));
-
- RUN(testZExt32(0));
- RUN(testZExt32(1));
- RUN(testZExt32(-1));
- RUN(testZExt32(1000000000ll));
- RUN(testZExt32(-1000000000ll));
- RUN(testZExt32Fold(0));
- RUN(testZExt32Fold(1));
- RUN(testZExt32Fold(-1));
- RUN(testZExt32Fold(1000000000ll));
- RUN(testZExt32Fold(-1000000000ll));
-
- RUN(testSExt32(0));
- RUN(testSExt32(1));
- RUN(testSExt32(-1));
- RUN(testSExt32(1000000000ll));
- RUN(testSExt32(-1000000000ll));
- RUN(testSExt32Fold(0));
- RUN(testSExt32Fold(1));
- RUN(testSExt32Fold(-1));
- RUN(testSExt32Fold(1000000000ll));
- RUN(testSExt32Fold(-1000000000ll));
-
- RUN(testTruncZExt32(0));
- RUN(testTruncZExt32(1));
- RUN(testTruncZExt32(-1));
- RUN(testTruncZExt32(1000000000ll));
- RUN(testTruncZExt32(-1000000000ll));
- RUN(testTruncSExt32(0));
- RUN(testTruncSExt32(1));
- RUN(testTruncSExt32(-1));
- RUN(testTruncSExt32(1000000000ll));
- RUN(testTruncSExt32(-1000000000ll));
-
- RUN(testSExt8(0));
- RUN(testSExt8(1));
- RUN(testSExt8(42));
- RUN(testSExt8(-1));
- RUN(testSExt8(0xff));
- RUN(testSExt8(0x100));
- RUN(testSExt8Fold(0));
- RUN(testSExt8Fold(1));
- RUN(testSExt8Fold(42));
- RUN(testSExt8Fold(-1));
- RUN(testSExt8Fold(0xff));
- RUN(testSExt8Fold(0x100));
- RUN(testSExt8SExt8(0));
- RUN(testSExt8SExt8(1));
- RUN(testSExt8SExt8(42));
- RUN(testSExt8SExt8(-1));
- RUN(testSExt8SExt8(0xff));
- RUN(testSExt8SExt8(0x100));
- RUN(testSExt8SExt16(0));
- RUN(testSExt8SExt16(1));
- RUN(testSExt8SExt16(42));
- RUN(testSExt8SExt16(-1));
- RUN(testSExt8SExt16(0xff));
- RUN(testSExt8SExt16(0x100));
- RUN(testSExt8SExt16(0xffff));
- RUN(testSExt8SExt16(0x10000));
- RUN(testSExt8BitAnd(0, 0));
- RUN(testSExt8BitAnd(1, 0));
- RUN(testSExt8BitAnd(42, 0));
- RUN(testSExt8BitAnd(-1, 0));
- RUN(testSExt8BitAnd(0xff, 0));
- RUN(testSExt8BitAnd(0x100, 0));
- RUN(testSExt8BitAnd(0xffff, 0));
- RUN(testSExt8BitAnd(0x10000, 0));
- RUN(testSExt8BitAnd(0, 0xf));
- RUN(testSExt8BitAnd(1, 0xf));
- RUN(testSExt8BitAnd(42, 0xf));
- RUN(testSExt8BitAnd(-1, 0xf));
- RUN(testSExt8BitAnd(0xff, 0xf));
- RUN(testSExt8BitAnd(0x100, 0xf));
- RUN(testSExt8BitAnd(0xffff, 0xf));
- RUN(testSExt8BitAnd(0x10000, 0xf));
- RUN(testSExt8BitAnd(0, 0xff));
- RUN(testSExt8BitAnd(1, 0xff));
- RUN(testSExt8BitAnd(42, 0xff));
- RUN(testSExt8BitAnd(-1, 0xff));
- RUN(testSExt8BitAnd(0xff, 0xff));
- RUN(testSExt8BitAnd(0x100, 0xff));
- RUN(testSExt8BitAnd(0xffff, 0xff));
- RUN(testSExt8BitAnd(0x10000, 0xff));
- RUN(testSExt8BitAnd(0, 0x80));
- RUN(testSExt8BitAnd(1, 0x80));
- RUN(testSExt8BitAnd(42, 0x80));
- RUN(testSExt8BitAnd(-1, 0x80));
- RUN(testSExt8BitAnd(0xff, 0x80));
- RUN(testSExt8BitAnd(0x100, 0x80));
- RUN(testSExt8BitAnd(0xffff, 0x80));
- RUN(testSExt8BitAnd(0x10000, 0x80));
- RUN(testBitAndSExt8(0, 0xf));
- RUN(testBitAndSExt8(1, 0xf));
- RUN(testBitAndSExt8(42, 0xf));
- RUN(testBitAndSExt8(-1, 0xf));
- RUN(testBitAndSExt8(0xff, 0xf));
- RUN(testBitAndSExt8(0x100, 0xf));
- RUN(testBitAndSExt8(0xffff, 0xf));
- RUN(testBitAndSExt8(0x10000, 0xf));
- RUN(testBitAndSExt8(0, 0xff));
- RUN(testBitAndSExt8(1, 0xff));
- RUN(testBitAndSExt8(42, 0xff));
- RUN(testBitAndSExt8(-1, 0xff));
- RUN(testBitAndSExt8(0xff, 0xff));
- RUN(testBitAndSExt8(0x100, 0xff));
- RUN(testBitAndSExt8(0xffff, 0xff));
- RUN(testBitAndSExt8(0x10000, 0xff));
- RUN(testBitAndSExt8(0, 0xfff));
- RUN(testBitAndSExt8(1, 0xfff));
- RUN(testBitAndSExt8(42, 0xfff));
- RUN(testBitAndSExt8(-1, 0xfff));
- RUN(testBitAndSExt8(0xff, 0xfff));
- RUN(testBitAndSExt8(0x100, 0xfff));
- RUN(testBitAndSExt8(0xffff, 0xfff));
- RUN(testBitAndSExt8(0x10000, 0xfff));
-
- RUN(testSExt16(0));
- RUN(testSExt16(1));
- RUN(testSExt16(42));
- RUN(testSExt16(-1));
- RUN(testSExt16(0xffff));
- RUN(testSExt16(0x10000));
- RUN(testSExt16Fold(0));
- RUN(testSExt16Fold(1));
- RUN(testSExt16Fold(42));
- RUN(testSExt16Fold(-1));
- RUN(testSExt16Fold(0xffff));
- RUN(testSExt16Fold(0x10000));
- RUN(testSExt16SExt8(0));
- RUN(testSExt16SExt8(1));
- RUN(testSExt16SExt8(42));
- RUN(testSExt16SExt8(-1));
- RUN(testSExt16SExt8(0xffff));
- RUN(testSExt16SExt8(0x10000));
- RUN(testSExt16SExt16(0));
- RUN(testSExt16SExt16(1));
- RUN(testSExt16SExt16(42));
- RUN(testSExt16SExt16(-1));
- RUN(testSExt16SExt16(0xffff));
- RUN(testSExt16SExt16(0x10000));
- RUN(testSExt16SExt16(0xffffff));
- RUN(testSExt16SExt16(0x1000000));
- RUN(testSExt16BitAnd(0, 0));
- RUN(testSExt16BitAnd(1, 0));
- RUN(testSExt16BitAnd(42, 0));
- RUN(testSExt16BitAnd(-1, 0));
- RUN(testSExt16BitAnd(0xffff, 0));
- RUN(testSExt16BitAnd(0x10000, 0));
- RUN(testSExt16BitAnd(0xffffff, 0));
- RUN(testSExt16BitAnd(0x1000000, 0));
- RUN(testSExt16BitAnd(0, 0xf));
- RUN(testSExt16BitAnd(1, 0xf));
- RUN(testSExt16BitAnd(42, 0xf));
- RUN(testSExt16BitAnd(-1, 0xf));
- RUN(testSExt16BitAnd(0xffff, 0xf));
- RUN(testSExt16BitAnd(0x10000, 0xf));
- RUN(testSExt16BitAnd(0xffffff, 0xf));
- RUN(testSExt16BitAnd(0x1000000, 0xf));
- RUN(testSExt16BitAnd(0, 0xffff));
- RUN(testSExt16BitAnd(1, 0xffff));
- RUN(testSExt16BitAnd(42, 0xffff));
- RUN(testSExt16BitAnd(-1, 0xffff));
- RUN(testSExt16BitAnd(0xffff, 0xffff));
- RUN(testSExt16BitAnd(0x10000, 0xffff));
- RUN(testSExt16BitAnd(0xffffff, 0xffff));
- RUN(testSExt16BitAnd(0x1000000, 0xffff));
- RUN(testSExt16BitAnd(0, 0x8000));
- RUN(testSExt16BitAnd(1, 0x8000));
- RUN(testSExt16BitAnd(42, 0x8000));
- RUN(testSExt16BitAnd(-1, 0x8000));
- RUN(testSExt16BitAnd(0xffff, 0x8000));
- RUN(testSExt16BitAnd(0x10000, 0x8000));
- RUN(testSExt16BitAnd(0xffffff, 0x8000));
- RUN(testSExt16BitAnd(0x1000000, 0x8000));
- RUN(testBitAndSExt16(0, 0xf));
- RUN(testBitAndSExt16(1, 0xf));
- RUN(testBitAndSExt16(42, 0xf));
- RUN(testBitAndSExt16(-1, 0xf));
- RUN(testBitAndSExt16(0xffff, 0xf));
- RUN(testBitAndSExt16(0x10000, 0xf));
- RUN(testBitAndSExt16(0xffffff, 0xf));
- RUN(testBitAndSExt16(0x1000000, 0xf));
- RUN(testBitAndSExt16(0, 0xffff));
- RUN(testBitAndSExt16(1, 0xffff));
- RUN(testBitAndSExt16(42, 0xffff));
- RUN(testBitAndSExt16(-1, 0xffff));
- RUN(testBitAndSExt16(0xffff, 0xffff));
- RUN(testBitAndSExt16(0x10000, 0xffff));
- RUN(testBitAndSExt16(0xffffff, 0xffff));
- RUN(testBitAndSExt16(0x1000000, 0xffff));
- RUN(testBitAndSExt16(0, 0xfffff));
- RUN(testBitAndSExt16(1, 0xfffff));
- RUN(testBitAndSExt16(42, 0xfffff));
- RUN(testBitAndSExt16(-1, 0xfffff));
- RUN(testBitAndSExt16(0xffff, 0xfffff));
- RUN(testBitAndSExt16(0x10000, 0xfffff));
- RUN(testBitAndSExt16(0xffffff, 0xfffff));
- RUN(testBitAndSExt16(0x1000000, 0xfffff));
-
- RUN(testSExt32BitAnd(0, 0));
- RUN(testSExt32BitAnd(1, 0));
- RUN(testSExt32BitAnd(42, 0));
- RUN(testSExt32BitAnd(-1, 0));
- RUN(testSExt32BitAnd(0x80000000, 0));
- RUN(testSExt32BitAnd(0, 0xf));
- RUN(testSExt32BitAnd(1, 0xf));
- RUN(testSExt32BitAnd(42, 0xf));
- RUN(testSExt32BitAnd(-1, 0xf));
- RUN(testSExt32BitAnd(0x80000000, 0xf));
- RUN(testSExt32BitAnd(0, 0x80000000));
- RUN(testSExt32BitAnd(1, 0x80000000));
- RUN(testSExt32BitAnd(42, 0x80000000));
- RUN(testSExt32BitAnd(-1, 0x80000000));
- RUN(testSExt32BitAnd(0x80000000, 0x80000000));
- RUN(testBitAndSExt32(0, 0xf));
- RUN(testBitAndSExt32(1, 0xf));
- RUN(testBitAndSExt32(42, 0xf));
- RUN(testBitAndSExt32(-1, 0xf));
- RUN(testBitAndSExt32(0xffff, 0xf));
- RUN(testBitAndSExt32(0x10000, 0xf));
- RUN(testBitAndSExt32(0xffffff, 0xf));
- RUN(testBitAndSExt32(0x1000000, 0xf));
- RUN(testBitAndSExt32(0, 0xffff00000000llu));
- RUN(testBitAndSExt32(1, 0xffff00000000llu));
- RUN(testBitAndSExt32(42, 0xffff00000000llu));
- RUN(testBitAndSExt32(-1, 0xffff00000000llu));
- RUN(testBitAndSExt32(0x80000000, 0xffff00000000llu));
-
- RUN(testBasicSelect());
- RUN(testSelectTest());
- RUN(testSelectCompareDouble());
- RUN_BINARY(testSelectCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSelectCompareFloatToDouble, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN(testSelectDouble());
- RUN(testSelectDoubleTest());
- RUN(testSelectDoubleCompareDouble());
- RUN_BINARY(testSelectDoubleCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN_BINARY(testSelectFloatCompareFloat, floatingPointOperands<float>(), floatingPointOperands<float>());
- RUN(testSelectDoubleCompareDoubleWithAliasing());
- RUN(testSelectFloatCompareFloatWithAliasing());
- RUN(testSelectFold(42));
- RUN(testSelectFold(43));
- RUN(testSelectInvert());
- RUN(testCheckSelect());
- RUN(testCheckSelectCheckSelect());
- RUN_BINARY(testPowDoubleByIntegerLoop, floatingPointOperands<double>(), int64Operands());
-
- RUN(testTruncOrHigh());
- RUN(testTruncOrLow());
- RUN(testBitAndOrHigh());
- RUN(testBitAndOrLow());
-
- RUN(testBranch64Equal(0, 0));
- RUN(testBranch64Equal(1, 1));
- RUN(testBranch64Equal(-1, -1));
- RUN(testBranch64Equal(1, -1));
- RUN(testBranch64Equal(-1, 1));
- RUN(testBranch64EqualImm(0, 0));
- RUN(testBranch64EqualImm(1, 1));
- RUN(testBranch64EqualImm(-1, -1));
- RUN(testBranch64EqualImm(1, -1));
- RUN(testBranch64EqualImm(-1, 1));
- RUN(testBranch64EqualMem(0, 0));
- RUN(testBranch64EqualMem(1, 1));
- RUN(testBranch64EqualMem(-1, -1));
- RUN(testBranch64EqualMem(1, -1));
- RUN(testBranch64EqualMem(-1, 1));
- RUN(testBranch64EqualMemImm(0, 0));
- RUN(testBranch64EqualMemImm(1, 1));
- RUN(testBranch64EqualMemImm(-1, -1));
- RUN(testBranch64EqualMemImm(1, -1));
- RUN(testBranch64EqualMemImm(-1, 1));
-
- RUN(testStore8Load8Z(0));
- RUN(testStore8Load8Z(123));
- RUN(testStore8Load8Z(12345));
- RUN(testStore8Load8Z(-123));
-
- RUN(testStore16Load16Z(0));
- RUN(testStore16Load16Z(123));
- RUN(testStore16Load16Z(12345));
- RUN(testStore16Load16Z(12345678));
- RUN(testStore16Load16Z(-123));
-
- RUN(testSShrShl32(42, 24, 24));
- RUN(testSShrShl32(-42, 24, 24));
- RUN(testSShrShl32(4200, 24, 24));
- RUN(testSShrShl32(-4200, 24, 24));
- RUN(testSShrShl32(4200000, 24, 24));
- RUN(testSShrShl32(-4200000, 24, 24));
-
- RUN(testSShrShl32(42, 16, 16));
- RUN(testSShrShl32(-42, 16, 16));
- RUN(testSShrShl32(4200, 16, 16));
- RUN(testSShrShl32(-4200, 16, 16));
- RUN(testSShrShl32(4200000, 16, 16));
- RUN(testSShrShl32(-4200000, 16, 16));
-
- RUN(testSShrShl32(42, 8, 8));
- RUN(testSShrShl32(-42, 8, 8));
- RUN(testSShrShl32(4200, 8, 8));
- RUN(testSShrShl32(-4200, 8, 8));
- RUN(testSShrShl32(4200000, 8, 8));
- RUN(testSShrShl32(-4200000, 8, 8));
- RUN(testSShrShl32(420000000, 8, 8));
- RUN(testSShrShl32(-420000000, 8, 8));
-
- RUN(testSShrShl64(42, 56, 56));
- RUN(testSShrShl64(-42, 56, 56));
- RUN(testSShrShl64(4200, 56, 56));
- RUN(testSShrShl64(-4200, 56, 56));
- RUN(testSShrShl64(4200000, 56, 56));
- RUN(testSShrShl64(-4200000, 56, 56));
- RUN(testSShrShl64(420000000, 56, 56));
- RUN(testSShrShl64(-420000000, 56, 56));
- RUN(testSShrShl64(42000000000, 56, 56));
- RUN(testSShrShl64(-42000000000, 56, 56));
-
- RUN(testSShrShl64(42, 48, 48));
- RUN(testSShrShl64(-42, 48, 48));
- RUN(testSShrShl64(4200, 48, 48));
- RUN(testSShrShl64(-4200, 48, 48));
- RUN(testSShrShl64(4200000, 48, 48));
- RUN(testSShrShl64(-4200000, 48, 48));
- RUN(testSShrShl64(420000000, 48, 48));
- RUN(testSShrShl64(-420000000, 48, 48));
- RUN(testSShrShl64(42000000000, 48, 48));
- RUN(testSShrShl64(-42000000000, 48, 48));
-
- RUN(testSShrShl64(42, 32, 32));
- RUN(testSShrShl64(-42, 32, 32));
- RUN(testSShrShl64(4200, 32, 32));
- RUN(testSShrShl64(-4200, 32, 32));
- RUN(testSShrShl64(4200000, 32, 32));
- RUN(testSShrShl64(-4200000, 32, 32));
- RUN(testSShrShl64(420000000, 32, 32));
- RUN(testSShrShl64(-420000000, 32, 32));
- RUN(testSShrShl64(42000000000, 32, 32));
- RUN(testSShrShl64(-42000000000, 32, 32));
-
- RUN(testSShrShl64(42, 24, 24));
- RUN(testSShrShl64(-42, 24, 24));
- RUN(testSShrShl64(4200, 24, 24));
- RUN(testSShrShl64(-4200, 24, 24));
- RUN(testSShrShl64(4200000, 24, 24));
- RUN(testSShrShl64(-4200000, 24, 24));
- RUN(testSShrShl64(420000000, 24, 24));
- RUN(testSShrShl64(-420000000, 24, 24));
- RUN(testSShrShl64(42000000000, 24, 24));
- RUN(testSShrShl64(-42000000000, 24, 24));
-
- RUN(testSShrShl64(42, 16, 16));
- RUN(testSShrShl64(-42, 16, 16));
- RUN(testSShrShl64(4200, 16, 16));
- RUN(testSShrShl64(-4200, 16, 16));
- RUN(testSShrShl64(4200000, 16, 16));
- RUN(testSShrShl64(-4200000, 16, 16));
- RUN(testSShrShl64(420000000, 16, 16));
- RUN(testSShrShl64(-420000000, 16, 16));
- RUN(testSShrShl64(42000000000, 16, 16));
- RUN(testSShrShl64(-42000000000, 16, 16));
-
- RUN(testSShrShl64(42, 8, 8));
- RUN(testSShrShl64(-42, 8, 8));
- RUN(testSShrShl64(4200, 8, 8));
- RUN(testSShrShl64(-4200, 8, 8));
- RUN(testSShrShl64(4200000, 8, 8));
- RUN(testSShrShl64(-4200000, 8, 8));
- RUN(testSShrShl64(420000000, 8, 8));
- RUN(testSShrShl64(-420000000, 8, 8));
- RUN(testSShrShl64(42000000000, 8, 8));
- RUN(testSShrShl64(-42000000000, 8, 8));
-
- RUN(testCheckMul64SShr());
-
- RUN(testComputeDivisionMagic<int32_t>(2, -2147483647, 0));
- RUN(testTrivialInfiniteLoop());
- RUN(testFoldPathEqual());
-
- RUN(testRShiftSelf32());
- RUN(testURShiftSelf32());
- RUN(testLShiftSelf32());
- RUN(testRShiftSelf64());
- RUN(testURShiftSelf64());
- RUN(testLShiftSelf64());
-
- RUN(testPatchpointDoubleRegs());
-
- if (tasks.isEmpty())
- usage();
-
- Lock lock;
-
- Vector<ThreadIdentifier> threads;
- for (unsigned i = filter ? 1 : WTF::numberOfProcessorCores(); i--;) {
- threads.append(
- createThread(
- "testb3 thread",
- [&] () {
- for (;;) {
- RefPtr<SharedTask<void()>> task;
- {
- LockHolder locker(lock);
- if (tasks.isEmpty())
- return;
- task = tasks.takeFirst();
- }
-
- task->run();
- }
- }));
- }
-
- for (ThreadIdentifier thread : threads)
- waitForThreadCompletion(thread);
- crashLock.lock();
-}
-
-} // anonymous namespace
-
-#else // ENABLE(B3_JIT)
-
-static void run(const char*)
-{
- dataLog("B3 JIT is not enabled.\n");
-}
-
-#endif // ENABLE(B3_JIT)
-
-int main(int argc, char** argv)
-{
- const char* filter = nullptr;
- switch (argc) {
- case 1:
- break;
- case 2:
- filter = argv[1];
- break;
- default:
- usage();
- break;
- }
-
- run(filter);
- return 0;
-}
-