| Index: test/cctest/compiler/test-run-native-calls.cc
|
| diff --git a/test/cctest/compiler/test-run-native-calls.cc b/test/cctest/compiler/test-run-native-calls.cc
|
| index 942d699ae89167b13bce3bac8637ed377e9c96d9..fe30b3c97f1eb18e291817a0ca7ed7442a0fed8e 100644
|
| --- a/test/cctest/compiler/test-run-native-calls.cc
|
| +++ b/test/cctest/compiler/test-run-native-calls.cc
|
| @@ -1,4 +1,4 @@
|
| -// Copyright 2014 the V8 project authors. All rights reserved.
|
| +// Copyright 2015 the V8 project authors. All rights reserved.
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| @@ -19,65 +19,90 @@ using namespace v8::internal::compiler;
|
|
|
| typedef RawMachineAssembler::Label MLabel;
|
|
|
| -#if !V8_TARGET_ARCH_ARM64
|
| +#if V8_TARGET_ARCH_ARM64
|
| // TODO(titzer): fix native stack parameters on arm64
|
| -#define NATIVE_STACK_PARAMS_OK
|
| +#define DISABLE_NATIVE_STACK_PARAMS true
|
| +#else
|
| +#define DISABLE_NATIVE_STACK_PARAMS false
|
| #endif
|
|
|
| namespace {
|
| -// Picks a representative set of registers from the allocatable set.
|
| -// If there are less than 100 possible pairs, do them all, otherwise try
|
| +typedef float float32;
|
| +typedef double float64;
|
| +
|
| +// Picks a representative pair of integers from the given range.
|
| +// If there are less than {max_pairs} possible pairs, do them all, otherwise try
|
| // to select a representative set.
|
| -class RegisterPairs {
|
| +class Pairs {
|
| public:
|
| - RegisterPairs()
|
| - : max_(std::min(100, Register::kMaxNumAllocatableRegisters *
|
| - Register::kMaxNumAllocatableRegisters)),
|
| + Pairs(int max_pairs, int range)
|
| + : range_(range),
|
| + max_pairs_(std::min(max_pairs, range_ * range_)),
|
| counter_(0) {}
|
|
|
| - bool More() { return counter_ < max_; }
|
| + bool More() { return counter_ < max_pairs_; }
|
|
|
| void Next(int* r0, int* r1, bool same_is_ok) {
|
| do {
|
| // Find the next pair.
|
| if (exhaustive()) {
|
| - *r0 = counter_ % Register::kMaxNumAllocatableRegisters;
|
| - *r1 = counter_ / Register::kMaxNumAllocatableRegisters;
|
| + *r0 = counter_ % range_;
|
| + *r1 = counter_ / range_;
|
| } else {
|
| - // Try each register at least once for both r0 and r1.
|
| + // Try each integer at least once for both r0 and r1.
|
| int index = counter_ / 2;
|
| if (counter_ & 1) {
|
| - *r0 = index % Register::kMaxNumAllocatableRegisters;
|
| - *r1 = index / Register::kMaxNumAllocatableRegisters;
|
| + *r0 = index % range_;
|
| + *r1 = index / range_;
|
| } else {
|
| - *r1 = index % Register::kMaxNumAllocatableRegisters;
|
| - *r0 = index / Register::kMaxNumAllocatableRegisters;
|
| + *r1 = index % range_;
|
| + *r0 = index / range_;
|
| }
|
| }
|
| counter_++;
|
| if (same_is_ok) break;
|
| if (*r0 == *r1) {
|
| - if (counter_ >= max_) {
|
| + if (counter_ >= max_pairs_) {
|
| // For the last hurrah, reg#0 with reg#n-1
|
| *r0 = 0;
|
| - *r1 = Register::kMaxNumAllocatableRegisters - 1;
|
| + *r1 = range_ - 1;
|
| break;
|
| }
|
| }
|
| } while (true);
|
|
|
| - DCHECK(*r0 >= 0 && *r0 < Register::kMaxNumAllocatableRegisters);
|
| - DCHECK(*r1 >= 0 && *r1 < Register::kMaxNumAllocatableRegisters);
|
| - printf("pair = %d, %d\n", *r0, *r1);
|
| + DCHECK(*r0 >= 0 && *r0 < range_);
|
| + DCHECK(*r1 >= 0 && *r1 < range_);
|
| }
|
|
|
| private:
|
| - int max_;
|
| + int range_;
|
| + int max_pairs_;
|
| int counter_;
|
| - bool exhaustive() {
|
| - return max_ == (Register::kMaxNumAllocatableRegisters *
|
| - Register::kMaxNumAllocatableRegisters);
|
| - }
|
| + bool exhaustive() { return max_pairs_ == (range_ * range_); }
|
| +};
|
| +
|
| +
|
| +// Pairs of general purpose registers.
|
| +class RegisterPairs : public Pairs {
|
| + public:
|
| + RegisterPairs() : Pairs(100, Register::kMaxNumAllocatableRegisters) {}
|
| +};
|
| +
|
| +
|
| +// Pairs of double registers.
|
| +class Float32RegisterPairs : public Pairs {
|
| + public:
|
| + Float32RegisterPairs()
|
| + : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {}
|
| +};
|
| +
|
| +
|
| +// Pairs of double registers.
|
| +class Float64RegisterPairs : public Pairs {
|
| + public:
|
| + Float64RegisterPairs()
|
| + : Pairs(100, DoubleRegister::NumAllocatableAliasedRegisters()) {}
|
| };
|
|
|
|
|
| @@ -265,6 +290,220 @@ Handle<Code> WrapWithCFunction(Handle<Code> inner, CallDescriptor* desc) {
|
| }
|
|
|
|
|
| +template <typename CType>
|
| +class ArgsBuffer {
|
| + public:
|
| + static const int kMaxParamCount = 64;
|
| +
|
| + explicit ArgsBuffer(int count, int seed = 1) : count_(count), seed_(seed) {
|
| + // initialize the buffer with "seed 0"
|
| + seed_ = 0;
|
| + Mutate();
|
| + seed_ = seed;
|
| + }
|
| +
|
| + class Sig : public MachineSignature {
|
| + public:
|
| + explicit Sig(int param_count)
|
| + : MachineSignature(1, param_count, MachTypes()) {
|
| + CHECK(param_count <= kMaxParamCount);
|
| + }
|
| + };
|
| +
|
| + static MachineType* MachTypes() {
|
| + MachineType t = MachineTypeForC<CType>();
|
| + static MachineType kTypes[kMaxParamCount + 1] = {
|
| + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t,
|
| + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t,
|
| + t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t, t};
|
| + return kTypes;
|
| + }
|
| +
|
| + Node* MakeConstant(RawMachineAssembler& raw, int32_t value) {
|
| + return raw.Int32Constant(value);
|
| + }
|
| +
|
| + Node* MakeConstant(RawMachineAssembler& raw, int64_t value) {
|
| + return raw.Int64Constant(value);
|
| + }
|
| +
|
| + Node* MakeConstant(RawMachineAssembler& raw, float32 value) {
|
| + return raw.Float32Constant(value);
|
| + }
|
| +
|
| + Node* MakeConstant(RawMachineAssembler& raw, float64 value) {
|
| + return raw.Float64Constant(value);
|
| + }
|
| +
|
| + Node* LoadInput(RawMachineAssembler& raw, Node* base, int index) {
|
| + Node* offset = raw.Int32Constant(index * sizeof(CType));
|
| + return raw.Load(MachineTypeForC<CType>(), base, offset);
|
| + }
|
| +
|
| + Node* StoreOutput(RawMachineAssembler& raw, Node* value) {
|
| + Node* base = raw.PointerConstant(&output);
|
| + Node* offset = raw.Int32Constant(0);
|
| + return raw.Store(MachineTypeForC<CType>(), base, offset, value);
|
| + }
|
| +
|
| + // Computes the next set of inputs by updating the {input} array.
|
| + void Mutate();
|
| +
|
| + void Reset() { memset(input, 0, sizeof(input)); }
|
| +
|
| + int count_;
|
| + int seed_;
|
| + CType input[kMaxParamCount];
|
| + CType output;
|
| +};
|
| +
|
| +
|
| +template <>
|
| +void ArgsBuffer<int32_t>::Mutate() {
|
| + uint32_t base = 1111111111u * seed_;
|
| + for (int j = 0; j < count_; j++) {
|
| + input[j] = static_cast<int32_t>(256 + base + j + seed_ * 13);
|
| + }
|
| + output = -1;
|
| + seed_++;
|
| +}
|
| +
|
| +
|
| +template <>
|
| +void ArgsBuffer<int64_t>::Mutate() {
|
| + uint64_t base = 11111111111111111ull * seed_;
|
| + for (int j = 0; j < count_; j++) {
|
| + input[j] = static_cast<int64_t>(256 + base + j + seed_ * 13);
|
| + }
|
| + output = -1;
|
| + seed_++;
|
| +}
|
| +
|
| +
|
| +template <>
|
| +void ArgsBuffer<float32>::Mutate() {
|
| + float64 base = -33.25 * seed_;
|
| + for (int j = 0; j < count_; j++) {
|
| + input[j] = 256 + base + j + seed_ * 13;
|
| + }
|
| + output = std::numeric_limits<float32>::quiet_NaN();
|
| + seed_++;
|
| +}
|
| +
|
| +
|
| +template <>
|
| +void ArgsBuffer<float64>::Mutate() {
|
| + float64 base = -111.25 * seed_;
|
| + for (int j = 0; j < count_; j++) {
|
| + input[j] = 256 + base + j + seed_ * 13;
|
| + }
|
| + output = std::numeric_limits<float64>::quiet_NaN();
|
| + seed_++;
|
| +}
|
| +
|
| +
|
| +int ParamCount(CallDescriptor* desc) {
|
| + return static_cast<int>(desc->GetMachineSignature()->parameter_count());
|
| +}
|
| +
|
| +
|
| +template <typename CType>
|
| +class Computer {
|
| + public:
|
| + static void Run(CallDescriptor* desc,
|
| + void (*build)(CallDescriptor*, RawMachineAssembler&),
|
| + CType (*compute)(CallDescriptor*, CType* inputs),
|
| + int seed = 1) {
|
| + int num_params = ParamCount(desc);
|
| + CHECK_LE(num_params, kMaxParamCount);
|
| + Isolate* isolate = CcTest::InitIsolateOnce();
|
| + HandleScope scope(isolate);
|
| + Handle<Code> inner = Handle<Code>::null();
|
| + {
|
| + // Build the graph for the computation.
|
| + Zone zone;
|
| + Graph graph(&zone);
|
| + RawMachineAssembler raw(isolate, &graph, desc);
|
| + build(desc, raw);
|
| + inner = CompileGraph("Compute", desc, &graph, raw.Export());
|
| + }
|
| +
|
| + CSignature0<int32_t> csig;
|
| + ArgsBuffer<CType> io(num_params, seed);
|
| +
|
| + {
|
| + // constant mode.
|
| + Handle<Code> wrapper = Handle<Code>::null();
|
| + {
|
| + // Wrap the above code with a callable function that passes constants.
|
| + Zone zone;
|
| + Graph graph(&zone);
|
| + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
|
| + RawMachineAssembler raw(isolate, &graph, cdesc);
|
| + Unique<HeapObject> unique =
|
| + Unique<HeapObject>::CreateUninitialized(inner);
|
| + Node* target = raw.HeapConstant(unique);
|
| + Node** args = zone.NewArray<Node*>(kMaxParamCount);
|
| + for (int i = 0; i < num_params; i++) {
|
| + args[i] = io.MakeConstant(raw, io.input[i]);
|
| + }
|
| +
|
| + Node* call = raw.CallN(desc, target, args);
|
| + Node* store = io.StoreOutput(raw, call);
|
| + USE(store);
|
| + raw.Return(raw.Int32Constant(seed));
|
| + wrapper =
|
| + CompileGraph("Compute-wrapper-const", cdesc, &graph, raw.Export());
|
| + }
|
| +
|
| + CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
|
| +
|
| + // Run the code, checking it against the reference.
|
| + CType expected = compute(desc, io.input);
|
| + int32_t check_seed = runnable.Call();
|
| + CHECK_EQ(seed, check_seed);
|
| + CHECK_EQ(expected, io.output);
|
| + }
|
| +
|
| + {
|
| + // buffer mode.
|
| + Handle<Code> wrapper = Handle<Code>::null();
|
| + {
|
| + // Wrap the above code with a callable function that loads from {input}.
|
| + Zone zone;
|
| + Graph graph(&zone);
|
| + CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
|
| + RawMachineAssembler raw(isolate, &graph, cdesc);
|
| + Node* base = raw.PointerConstant(io.input);
|
| + Unique<HeapObject> unique =
|
| + Unique<HeapObject>::CreateUninitialized(inner);
|
| + Node* target = raw.HeapConstant(unique);
|
| + Node** args = zone.NewArray<Node*>(kMaxParamCount);
|
| + for (int i = 0; i < num_params; i++) {
|
| + args[i] = io.LoadInput(raw, base, i);
|
| + }
|
| +
|
| + Node* call = raw.CallN(desc, target, args);
|
| + Node* store = io.StoreOutput(raw, call);
|
| + USE(store);
|
| + raw.Return(raw.Int32Constant(seed));
|
| + wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export());
|
| + }
|
| +
|
| + CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
|
| +
|
| + // Run the code, checking it against the reference.
|
| + for (int i = 0; i < 5; i++) {
|
| + CType expected = compute(desc, io.input);
|
| + int32_t check_seed = runnable.Call();
|
| + CHECK_EQ(seed, check_seed);
|
| + CHECK_EQ(expected, io.output);
|
| + io.Mutate();
|
| + }
|
| + }
|
| + }
|
| +};
|
| +
|
| } // namespace
|
|
|
|
|
| @@ -303,8 +542,9 @@ static void TestInt32Sub(CallDescriptor* desc) {
|
| }
|
|
|
|
|
| -#ifdef NATIVE_STACK_PARAMS_OK
|
| static void CopyTwentyInt32(CallDescriptor* desc) {
|
| + if (DISABLE_NATIVE_STACK_PARAMS) return;
|
| +
|
| const int kNumParams = 20;
|
| int32_t input[kNumParams];
|
| int32_t output[kNumParams];
|
| @@ -365,7 +605,6 @@ static void CopyTwentyInt32(CallDescriptor* desc) {
|
| }
|
| }
|
| }
|
| -#endif // NATIVE_STACK_PARAMS_OK
|
|
|
|
|
| static void Test_RunInt32SubWithRet(int retreg) {
|
| @@ -415,7 +654,7 @@ TEST_INT32_SUB_WITH_RET(19)
|
|
|
|
|
| TEST(Run_Int32Sub_all_allocatable_single) {
|
| -#ifdef NATIVE_STACK_PARAMS_OK
|
| + if (DISABLE_NATIVE_STACK_PARAMS) return;
|
| Int32Signature sig(2);
|
| RegisterPairs pairs;
|
| while (pairs.More()) {
|
| @@ -429,12 +668,11 @@ TEST(Run_Int32Sub_all_allocatable_single) {
|
| CallDescriptor* desc = config.Create(&zone, &sig);
|
| TestInt32Sub(desc);
|
| }
|
| -#endif // NATIVE_STACK_PARAMS_OK
|
| }
|
|
|
|
|
| TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
|
| -#ifdef NATIVE_STACK_PARAMS_OK
|
| + if (DISABLE_NATIVE_STACK_PARAMS) return;
|
| Int32Signature sig(20);
|
| RegisterPairs pairs;
|
| while (pairs.More()) {
|
| @@ -448,113 +686,14 @@ TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
|
| CallDescriptor* desc = config.Create(&zone, &sig);
|
| CopyTwentyInt32(desc);
|
| }
|
| -#endif // NATIVE_STACK_PARAMS_OK
|
| }
|
|
|
|
|
| -#ifdef NATIVE_STACK_PARAMS_OK
|
| -int ParamCount(CallDescriptor* desc) {
|
| - return static_cast<int>(desc->GetMachineSignature()->parameter_count());
|
| -}
|
| -
|
| -
|
| -// Super mega helper routine to generate a computation with a given
|
| -// call descriptor, compile the code, wrap the code, and pass various inputs,
|
| -// comparing against a reference implementation.
|
| -static void Run_Int32_Computation(
|
| +template <typename CType>
|
| +static void Run_Computation(
|
| CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&),
|
| - int32_t (*compute)(CallDescriptor*, int32_t* inputs), int seed = 1) {
|
| - int num_params = ParamCount(desc);
|
| - CHECK_LE(num_params, kMaxParamCount);
|
| - int32_t input[kMaxParamCount];
|
| - Isolate* isolate = CcTest::InitIsolateOnce();
|
| - HandleScope scope(isolate);
|
| - Handle<Code> inner = Handle<Code>::null();
|
| - {
|
| - // Build the graph for the computation.
|
| - Zone zone;
|
| - Graph graph(&zone);
|
| - RawMachineAssembler raw(isolate, &graph, desc);
|
| - build(desc, raw);
|
| - inner = CompileGraph("Compute", desc, &graph, raw.Export());
|
| - }
|
| -
|
| - CSignature0<int32_t> csig;
|
| -
|
| - if (false) {
|
| - // constant mode.
|
| - Handle<Code> wrapper = Handle<Code>::null();
|
| - {
|
| - // Wrap the above code with a callable function that passes constants.
|
| - Zone zone;
|
| - Graph graph(&zone);
|
| - CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
|
| - RawMachineAssembler raw(isolate, &graph, cdesc);
|
| - Unique<HeapObject> unique =
|
| - Unique<HeapObject>::CreateUninitialized(inner);
|
| - Node* target = raw.HeapConstant(unique);
|
| - Node** args = zone.NewArray<Node*>(kMaxParamCount);
|
| - for (int i = 0; i < num_params; i++) {
|
| - args[i] = raw.Int32Constant(0x100 + i);
|
| - }
|
| -
|
| - Node* call = raw.CallN(desc, target, args);
|
| - raw.Return(call);
|
| - wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export());
|
| - }
|
| -
|
| - CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
|
| -
|
| - // Run the code, checking it against the reference.
|
| - for (int j = 0; j < kMaxParamCount; j++) {
|
| - input[j] = 0x100 + j;
|
| - }
|
| - int32_t expected = compute(desc, input);
|
| - int32_t result = runnable.Call();
|
| -
|
| - CHECK_EQ(expected, result);
|
| - }
|
| -
|
| - {
|
| - // buffer mode.
|
| - Handle<Code> wrapper = Handle<Code>::null();
|
| - {
|
| - // Wrap the above code with a callable function that loads from {input}.
|
| - Zone zone;
|
| - Graph graph(&zone);
|
| - CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
|
| - RawMachineAssembler raw(isolate, &graph, cdesc);
|
| - Node* base = raw.PointerConstant(input);
|
| - Unique<HeapObject> unique =
|
| - Unique<HeapObject>::CreateUninitialized(inner);
|
| - Node* target = raw.HeapConstant(unique);
|
| - Node** args = zone.NewArray<Node*>(kMaxParamCount);
|
| - for (int i = 0; i < num_params; i++) {
|
| - Node* offset = raw.Int32Constant(i * sizeof(int32_t));
|
| - args[i] = raw.Load(kMachInt32, base, offset);
|
| - }
|
| -
|
| - Node* call = raw.CallN(desc, target, args);
|
| - raw.Return(call);
|
| - wrapper = CompileGraph("Compute-wrapper", cdesc, &graph, raw.Export());
|
| - }
|
| -
|
| - CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
|
| -
|
| - // Run the code, checking it against the reference.
|
| - for (int i = 0; i < 5; i++) {
|
| - // Use pseudo-random values for each run, but the first run gets args
|
| - // 100, 101, 102, 103... for easier diagnosis.
|
| - uint32_t base = 1111111111u * i * seed;
|
| - for (int j = 0; j < kMaxParamCount; j++) {
|
| - input[j] = static_cast<int32_t>(100 + base + j);
|
| - }
|
| - int32_t expected = compute(desc, input);
|
| - int32_t result = runnable.Call();
|
| -
|
| - CHECK_EQ(expected, result);
|
| - }
|
| - }
|
| + CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) {
|
| + Computer<CType>::Run(desc, build, compute, seed);
|
| }
|
|
|
|
|
| @@ -584,6 +723,7 @@ static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) {
|
|
|
|
|
| static void Test_Int32_WeightedSum_of_size(int count) {
|
| + if (DISABLE_NATIVE_STACK_PARAMS) return;
|
| Int32Signature sig(count);
|
| for (int p0 = 0; p0 < Register::kMaxNumAllocatableRegisters; p0++) {
|
| Zone zone;
|
| @@ -594,8 +734,8 @@ static void Test_Int32_WeightedSum_of_size(int count) {
|
| Allocator rets(rarray, 1, nullptr, 0);
|
| RegisterConfig config(params, rets);
|
| CallDescriptor* desc = config.Create(&zone, &sig);
|
| - Run_Int32_Computation(desc, Build_Int32_WeightedSum,
|
| - Compute_Int32_WeightedSum, 257 + count);
|
| + Run_Computation<int32_t>(desc, Build_Int32_WeightedSum,
|
| + Compute_Int32_WeightedSum, 257 + count);
|
| }
|
| }
|
|
|
| @@ -618,19 +758,21 @@ TEST_INT32_WEIGHTEDSUM(19)
|
|
|
|
|
| template <int which>
|
| -static void Build_Int32_Select(CallDescriptor* desc, RawMachineAssembler& raw) {
|
| +static void Build_Select(CallDescriptor* desc, RawMachineAssembler& raw) {
|
| raw.Return(raw.Parameter(which));
|
| }
|
|
|
|
|
| -template <int which>
|
| -static int32_t Compute_Int32_Select(CallDescriptor* desc, int32_t* inputs) {
|
| +template <typename CType, int which>
|
| +static CType Compute_Select(CallDescriptor* desc, CType* inputs) {
|
| return inputs[which];
|
| }
|
|
|
|
|
| template <int which>
|
| void Test_Int32_Select() {
|
| + if (DISABLE_NATIVE_STACK_PARAMS) return;
|
| +
|
| int parray[] = {0};
|
| int rarray[] = {0};
|
| Allocator params(parray, 1, nullptr, 0);
|
| @@ -642,8 +784,8 @@ void Test_Int32_Select() {
|
| for (int i = which + 1; i <= 64; i++) {
|
| Int32Signature sig(i);
|
| CallDescriptor* desc = config.Create(&zone, &sig);
|
| - Run_Int32_Computation(desc, Build_Int32_Select<which>,
|
| - Compute_Int32_Select<which>, 1025 + which);
|
| + Run_Computation<int32_t>(desc, Build_Select<which>,
|
| + Compute_Select<int32_t, which>, 1025 + which);
|
| }
|
| }
|
|
|
| @@ -666,9 +808,79 @@ TEST_INT32_SELECT(19)
|
| TEST_INT32_SELECT(45)
|
| TEST_INT32_SELECT(62)
|
| TEST_INT32_SELECT(63)
|
| -#endif // NATIVE_STACK_PARAMS_OK
|
|
|
|
|
| -TEST(TheLastTestForLint) {
|
| - // Yes, thank you.
|
| +TEST(Int64Select_registers) {
|
| + if (Register::kMaxNumAllocatableRegisters < 2) return;
|
| + if (kPointerSize < 8) return; // TODO(titzer): int64 on 32-bit platforms
|
| +
|
| + int rarray[] = {0};
|
| + ArgsBuffer<int64_t>::Sig sig(2);
|
| +
|
| + RegisterPairs pairs;
|
| + Zone zone;
|
| + while (pairs.More()) {
|
| + int parray[2];
|
| + pairs.Next(&parray[0], &parray[1], false);
|
| + Allocator params(parray, 2, nullptr, 0);
|
| + Allocator rets(rarray, 1, nullptr, 0);
|
| + RegisterConfig config(params, rets);
|
| +
|
| + CallDescriptor* desc = config.Create(&zone, &sig);
|
| + Run_Computation<int64_t>(desc, Build_Select<0>, Compute_Select<int64_t, 0>,
|
| + 1021);
|
| +
|
| + Run_Computation<int64_t>(desc, Build_Select<1>, Compute_Select<int64_t, 1>,
|
| + 1022);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST(Float32Select_registers) {
|
| + if (DoubleRegister::kMaxNumAllocatableRegisters < 2) return;
|
| +
|
| + int rarray[] = {0};
|
| + ArgsBuffer<float32>::Sig sig(2);
|
| +
|
| + Float32RegisterPairs pairs;
|
| + Zone zone;
|
| + while (pairs.More()) {
|
| + int parray[2];
|
| + pairs.Next(&parray[0], &parray[1], false);
|
| + Allocator params(nullptr, 0, parray, 2);
|
| + Allocator rets(nullptr, 0, rarray, 1);
|
| + RegisterConfig config(params, rets);
|
| +
|
| + CallDescriptor* desc = config.Create(&zone, &sig);
|
| + Run_Computation<float32>(desc, Build_Select<0>, Compute_Select<float32, 0>,
|
| + 1019);
|
| +
|
| + Run_Computation<float32>(desc, Build_Select<1>, Compute_Select<float32, 1>,
|
| + 1018);
|
| + }
|
| +}
|
| +
|
| +
|
| +TEST(Float64Select_registers) {
|
| + if (DoubleRegister::kMaxNumAllocatableRegisters < 2) return;
|
| +
|
| + int rarray[] = {0};
|
| + ArgsBuffer<float64>::Sig sig(2);
|
| +
|
| + Float64RegisterPairs pairs;
|
| + Zone zone;
|
| + while (pairs.More()) {
|
| + int parray[2];
|
| + pairs.Next(&parray[0], &parray[1], false);
|
| + Allocator params(nullptr, 0, parray, 2);
|
| + Allocator rets(nullptr, 0, rarray, 1);
|
| + RegisterConfig config(params, rets);
|
| +
|
| + CallDescriptor* desc = config.Create(&zone, &sig);
|
| + Run_Computation<float64>(desc, Build_Select<0>, Compute_Select<float64, 0>,
|
| + 1033);
|
| +
|
| + Run_Computation<float64>(desc, Build_Select<1>, Compute_Select<float64, 1>,
|
| + 1034);
|
| + }
|
| }
|
|
|