| 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
 | 
| deleted file mode 100644
 | 
| index 4c0d8cff6ade3e397ee88d58ef846ed0bb568d17..0000000000000000000000000000000000000000
 | 
| --- a/test/cctest/compiler/test-run-native-calls.cc
 | 
| +++ /dev/null
 | 
| @@ -1,634 +0,0 @@
 | 
| -// Copyright 2014 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.
 | 
| -
 | 
| -#include "src/assembler.h"
 | 
| -#include "src/codegen.h"
 | 
| -#include "src/compiler/linkage.h"
 | 
| -#include "src/compiler/machine-type.h"
 | 
| -#include "src/compiler/raw-machine-assembler.h"
 | 
| -
 | 
| -#include "test/cctest/cctest.h"
 | 
| -#include "test/cctest/compiler/codegen-tester.h"
 | 
| -#include "test/cctest/compiler/graph-builder-tester.h"
 | 
| -#include "test/cctest/compiler/value-helper.h"
 | 
| -
 | 
| -using namespace v8::base;
 | 
| -using namespace v8::internal;
 | 
| -using namespace v8::internal::compiler;
 | 
| -
 | 
| -typedef RawMachineAssembler::Label MLabel;
 | 
| -
 | 
| -#if !V8_TARGET_ARCH_ARM64
 | 
| -// TODO(titzer): fix native stack parameters on arm64
 | 
| -#define NATIVE_STACK_PARAMS_OK
 | 
| -#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
 | 
| -// to select a representative set.
 | 
| -class RegisterPairs {
 | 
| - public:
 | 
| -  RegisterPairs()
 | 
| -      : max_(std::min(100, Register::kMaxNumAllocatableRegisters *
 | 
| -                               Register::kMaxNumAllocatableRegisters)),
 | 
| -        counter_(0) {}
 | 
| -
 | 
| -  bool More() { return counter_ < max_; }
 | 
| -
 | 
| -  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;
 | 
| -      } else {
 | 
| -        // Try each register at least once for both r0 and r1.
 | 
| -        int index = counter_ / 2;
 | 
| -        if (counter_ & 1) {
 | 
| -          *r0 = index % Register::kMaxNumAllocatableRegisters;
 | 
| -          *r1 = index / Register::kMaxNumAllocatableRegisters;
 | 
| -        } else {
 | 
| -          *r1 = index % Register::kMaxNumAllocatableRegisters;
 | 
| -          *r0 = index / Register::kMaxNumAllocatableRegisters;
 | 
| -        }
 | 
| -      }
 | 
| -      counter_++;
 | 
| -      if (same_is_ok) break;
 | 
| -      if (*r0 == *r1) {
 | 
| -        if (counter_ >= max_) {
 | 
| -          // For the last hurrah, reg#0 with reg#n-1
 | 
| -          *r0 = 0;
 | 
| -          *r1 = Register::kMaxNumAllocatableRegisters - 1;
 | 
| -          break;
 | 
| -        }
 | 
| -      }
 | 
| -    } while (true);
 | 
| -
 | 
| -    DCHECK(*r0 >= 0 && *r0 < Register::kMaxNumAllocatableRegisters);
 | 
| -    DCHECK(*r1 >= 0 && *r1 < Register::kMaxNumAllocatableRegisters);
 | 
| -    printf("pair = %d, %d\n", *r0, *r1);
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  int max_;
 | 
| -  int counter_;
 | 
| -  bool exhaustive() {
 | 
| -    return max_ == (Register::kMaxNumAllocatableRegisters *
 | 
| -                    Register::kMaxNumAllocatableRegisters);
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -// Helper for allocating either an GP or FP reg, or the next stack slot.
 | 
| -struct Allocator {
 | 
| -  Allocator(int* gp, int gpc, int* fp, int fpc)
 | 
| -      : gp_count(gpc),
 | 
| -        gp_offset(0),
 | 
| -        gp_regs(gp),
 | 
| -        fp_count(fpc),
 | 
| -        fp_offset(0),
 | 
| -        fp_regs(fp),
 | 
| -        stack_offset(0) {}
 | 
| -
 | 
| -  int gp_count;
 | 
| -  int gp_offset;
 | 
| -  int* gp_regs;
 | 
| -
 | 
| -  int fp_count;
 | 
| -  int fp_offset;
 | 
| -  int* fp_regs;
 | 
| -
 | 
| -  int stack_offset;
 | 
| -
 | 
| -  LinkageLocation Next(MachineType type) {
 | 
| -    if (IsFloatingPoint(type)) {
 | 
| -      // Allocate a floating point register/stack location.
 | 
| -      if (fp_offset < fp_count) {
 | 
| -        return LinkageLocation::ForRegister(fp_regs[fp_offset++]);
 | 
| -      } else {
 | 
| -        int offset = -1 - stack_offset;
 | 
| -        stack_offset += Words(type);
 | 
| -        return LinkageLocation::ForCallerFrameSlot(offset);
 | 
| -      }
 | 
| -    } else {
 | 
| -      // Allocate a general purpose register/stack location.
 | 
| -      if (gp_offset < gp_count) {
 | 
| -        return LinkageLocation::ForRegister(gp_regs[gp_offset++]);
 | 
| -      } else {
 | 
| -        int offset = -1 - stack_offset;
 | 
| -        stack_offset += Words(type);
 | 
| -        return LinkageLocation::ForCallerFrameSlot(offset);
 | 
| -      }
 | 
| -    }
 | 
| -  }
 | 
| -  bool IsFloatingPoint(MachineType type) {
 | 
| -    return RepresentationOf(type) == kRepFloat32 ||
 | 
| -           RepresentationOf(type) == kRepFloat64;
 | 
| -  }
 | 
| -  int Words(MachineType type) {
 | 
| -    int size = ElementSizeOf(type);
 | 
| -    return size <= kPointerSize ? 1 : size / kPointerSize;
 | 
| -  }
 | 
| -  void Reset() {
 | 
| -    fp_offset = 0;
 | 
| -    gp_offset = 0;
 | 
| -    stack_offset = 0;
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -class RegisterConfig {
 | 
| - public:
 | 
| -  RegisterConfig(Allocator& p, Allocator& r) : params(p), rets(r) {}
 | 
| -
 | 
| -  CallDescriptor* Create(Zone* zone, MachineSignature* msig) {
 | 
| -    rets.Reset();
 | 
| -    params.Reset();
 | 
| -
 | 
| -    LocationSignature::Builder locations(zone, msig->return_count(),
 | 
| -                                         msig->parameter_count());
 | 
| -    // Add return location(s).
 | 
| -    const int return_count = static_cast<int>(locations.return_count_);
 | 
| -    for (int i = 0; i < return_count; i++) {
 | 
| -      locations.AddReturn(rets.Next(msig->GetReturn(i)));
 | 
| -    }
 | 
| -
 | 
| -    // Add register and/or stack parameter(s).
 | 
| -    const int parameter_count = static_cast<int>(msig->parameter_count());
 | 
| -    for (int i = 0; i < parameter_count; i++) {
 | 
| -      locations.AddParam(params.Next(msig->GetParam(i)));
 | 
| -    }
 | 
| -
 | 
| -    const RegList kCalleeSaveRegisters = 0;
 | 
| -    const RegList kCalleeSaveFPRegisters = 0;
 | 
| -
 | 
| -    MachineType target_type = compiler::kMachAnyTagged;
 | 
| -    LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
 | 
| -    int stack_param_count = params.stack_offset;
 | 
| -    return new (zone) CallDescriptor(       // --
 | 
| -        CallDescriptor::kCallCodeObject,    // kind
 | 
| -        target_type,                        // target MachineType
 | 
| -        target_loc,                         // target location
 | 
| -        msig,                               // machine_sig
 | 
| -        locations.Build(),                  // location_sig
 | 
| -        stack_param_count,                  // stack_parameter_count
 | 
| -        compiler::Operator::kNoProperties,  // properties
 | 
| -        kCalleeSaveRegisters,               // callee-saved registers
 | 
| -        kCalleeSaveFPRegisters,             // callee-saved fp regs
 | 
| -        CallDescriptor::kNoFlags,           // flags
 | 
| -        "c-call");
 | 
| -  }
 | 
| -
 | 
| - private:
 | 
| -  Allocator& params;
 | 
| -  Allocator& rets;
 | 
| -};
 | 
| -
 | 
| -const int kMaxParamCount = 64;
 | 
| -
 | 
| -MachineType kIntTypes[kMaxParamCount + 1] = {
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32,
 | 
| -    kMachInt32, kMachInt32, kMachInt32, kMachInt32, kMachInt32};
 | 
| -
 | 
| -
 | 
| -// For making uniform int32 signatures shorter.
 | 
| -class Int32Signature : public MachineSignature {
 | 
| - public:
 | 
| -  explicit Int32Signature(int param_count)
 | 
| -      : MachineSignature(1, param_count, kIntTypes) {
 | 
| -    CHECK(param_count <= kMaxParamCount);
 | 
| -  }
 | 
| -};
 | 
| -
 | 
| -
 | 
| -Handle<Code> CompileGraph(const char* name, CallDescriptor* desc, Graph* graph,
 | 
| -                          Schedule* schedule = nullptr) {
 | 
| -  Isolate* isolate = CcTest::InitIsolateOnce();
 | 
| -  Handle<Code> code =
 | 
| -      Pipeline::GenerateCodeForTesting(isolate, desc, graph, schedule);
 | 
| -  CHECK(!code.is_null());
 | 
| -#ifdef ENABLE_DISASSEMBLER
 | 
| -  if (FLAG_print_opt_code) {
 | 
| -    OFStream os(stdout);
 | 
| -    code->Disassemble(name, os);
 | 
| -  }
 | 
| -#endif
 | 
| -  return code;
 | 
| -}
 | 
| -
 | 
| -
 | 
| -Handle<Code> WrapWithCFunction(Handle<Code> inner, CallDescriptor* desc) {
 | 
| -  Zone zone;
 | 
| -  MachineSignature* msig =
 | 
| -      const_cast<MachineSignature*>(desc->GetMachineSignature());
 | 
| -  int param_count = static_cast<int>(msig->parameter_count());
 | 
| -  GraphAndBuilders caller(&zone);
 | 
| -  {
 | 
| -    GraphAndBuilders& b = caller;
 | 
| -    Node* start = b.graph()->NewNode(b.common()->Start(param_count + 3));
 | 
| -    b.graph()->SetStart(start);
 | 
| -    Unique<HeapObject> unique = Unique<HeapObject>::CreateUninitialized(inner);
 | 
| -    Node* target = b.graph()->NewNode(b.common()->HeapConstant(unique));
 | 
| -
 | 
| -    // Add arguments to the call.
 | 
| -    Node** args = zone.NewArray<Node*>(param_count + 3);
 | 
| -    int index = 0;
 | 
| -    args[index++] = target;
 | 
| -    for (int i = 0; i < param_count; i++) {
 | 
| -      args[index] = b.graph()->NewNode(b.common()->Parameter(i), start);
 | 
| -      index++;
 | 
| -    }
 | 
| -    args[index++] = start;  // effect.
 | 
| -    args[index++] = start;  // control.
 | 
| -
 | 
| -    // Build the call and return nodes.
 | 
| -    Node* call =
 | 
| -        b.graph()->NewNode(b.common()->Call(desc), param_count + 3, args);
 | 
| -    Node* ret = b.graph()->NewNode(b.common()->Return(), call, call, start);
 | 
| -    b.graph()->SetEnd(ret);
 | 
| -  }
 | 
| -
 | 
| -  CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, msig);
 | 
| -
 | 
| -  return CompileGraph("wrapper", cdesc, caller.graph());
 | 
| -}
 | 
| -
 | 
| -
 | 
| -}  // namespace
 | 
| -
 | 
| -
 | 
| -static void TestInt32Sub(CallDescriptor* desc) {
 | 
| -  Isolate* isolate = CcTest::InitIsolateOnce();
 | 
| -  HandleScope scope(isolate);
 | 
| -  Zone zone;
 | 
| -  GraphAndBuilders inner(&zone);
 | 
| -  {
 | 
| -    // Build the add function.
 | 
| -    GraphAndBuilders& b = inner;
 | 
| -    Node* start = b.graph()->NewNode(b.common()->Start(5));
 | 
| -    b.graph()->SetStart(start);
 | 
| -    Node* p0 = b.graph()->NewNode(b.common()->Parameter(0), start);
 | 
| -    Node* p1 = b.graph()->NewNode(b.common()->Parameter(1), start);
 | 
| -    Node* add = b.graph()->NewNode(b.machine()->Int32Sub(), p0, p1);
 | 
| -    Node* ret = b.graph()->NewNode(b.common()->Return(), add, start, start);
 | 
| -    b.graph()->SetEnd(ret);
 | 
| -  }
 | 
| -
 | 
| -  Handle<Code> inner_code = CompileGraph("Int32Sub", desc, inner.graph());
 | 
| -  Handle<Code> wrapper = WrapWithCFunction(inner_code, desc);
 | 
| -  MachineSignature* msig =
 | 
| -      const_cast<MachineSignature*>(desc->GetMachineSignature());
 | 
| -  CodeRunner<int32_t> runnable(isolate, wrapper,
 | 
| -                               CSignature::FromMachine(&zone, msig));
 | 
| -
 | 
| -  FOR_INT32_INPUTS(i) {
 | 
| -    FOR_INT32_INPUTS(j) {
 | 
| -      int32_t expected = static_cast<int32_t>(static_cast<uint32_t>(*i) -
 | 
| -                                              static_cast<uint32_t>(*j));
 | 
| -      int32_t result = runnable.Call(*i, *j);
 | 
| -      CHECK_EQ(expected, result);
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -#ifdef NATIVE_STACK_PARAMS_OK
 | 
| -static void CopyTwentyInt32(CallDescriptor* desc) {
 | 
| -  const int kNumParams = 20;
 | 
| -  int32_t input[kNumParams];
 | 
| -  int32_t output[kNumParams];
 | 
| -  Isolate* isolate = CcTest::InitIsolateOnce();
 | 
| -  HandleScope scope(isolate);
 | 
| -  Handle<Code> inner = Handle<Code>::null();
 | 
| -  {
 | 
| -    // Writes all parameters into the output buffer.
 | 
| -    Zone zone;
 | 
| -    Graph graph(&zone);
 | 
| -    RawMachineAssembler raw(isolate, &graph, desc);
 | 
| -    Node* base = raw.PointerConstant(output);
 | 
| -    for (int i = 0; i < kNumParams; i++) {
 | 
| -      Node* offset = raw.Int32Constant(i * sizeof(int32_t));
 | 
| -      raw.Store(kMachInt32, base, offset, raw.Parameter(i));
 | 
| -    }
 | 
| -    raw.Return(raw.Int32Constant(42));
 | 
| -    inner = CompileGraph("CopyTwentyInt32", desc, &graph, raw.Export());
 | 
| -  }
 | 
| -
 | 
| -  CSignature0<int32_t> csig;
 | 
| -  Handle<Code> wrapper = Handle<Code>::null();
 | 
| -  {
 | 
| -    // Loads parameters from the input buffer and calls the above code.
 | 
| -    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*>(kNumParams);
 | 
| -    for (int i = 0; i < kNumParams; 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("CopyTwentyInt32-wrapper", cdesc, &graph, raw.Export());
 | 
| -  }
 | 
| -
 | 
| -  CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
 | 
| -
 | 
| -  // Run the code, checking it correctly implements the memcpy.
 | 
| -  for (int i = 0; i < 5; i++) {
 | 
| -    uint32_t base = 1111111111u * i;
 | 
| -    for (int j = 0; j < kNumParams; j++) {
 | 
| -      input[j] = static_cast<int32_t>(base + 13 * j);
 | 
| -    }
 | 
| -
 | 
| -    memset(output, 0, sizeof(output));
 | 
| -    CHECK_EQ(42, runnable.Call());
 | 
| -
 | 
| -    for (int j = 0; j < kNumParams; j++) {
 | 
| -      CHECK_EQ(input[j], output[j]);
 | 
| -    }
 | 
| -  }
 | 
| -}
 | 
| -#endif  // NATIVE_STACK_PARAMS_OK
 | 
| -
 | 
| -
 | 
| -static void Test_RunInt32SubWithRet(int retreg) {
 | 
| -  Int32Signature sig(2);
 | 
| -  Zone zone;
 | 
| -  RegisterPairs pairs;
 | 
| -  while (pairs.More()) {
 | 
| -    int parray[2];
 | 
| -    int rarray[] = {retreg};
 | 
| -    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);
 | 
| -    TestInt32Sub(desc);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Separate tests for parallelization.
 | 
| -#define TEST_INT32_SUB_WITH_RET(x)                                             \
 | 
| -  TEST(Run_Int32Sub_all_allocatable_pairs_##x) {                               \
 | 
| -    if (Register::kMaxNumAllocatableRegisters > x) Test_RunInt32SubWithRet(x); \
 | 
| -  }
 | 
| -
 | 
| -
 | 
| -TEST_INT32_SUB_WITH_RET(0)
 | 
| -TEST_INT32_SUB_WITH_RET(1)
 | 
| -TEST_INT32_SUB_WITH_RET(2)
 | 
| -TEST_INT32_SUB_WITH_RET(3)
 | 
| -TEST_INT32_SUB_WITH_RET(4)
 | 
| -TEST_INT32_SUB_WITH_RET(5)
 | 
| -TEST_INT32_SUB_WITH_RET(6)
 | 
| -TEST_INT32_SUB_WITH_RET(7)
 | 
| -TEST_INT32_SUB_WITH_RET(8)
 | 
| -TEST_INT32_SUB_WITH_RET(9)
 | 
| -TEST_INT32_SUB_WITH_RET(10)
 | 
| -TEST_INT32_SUB_WITH_RET(11)
 | 
| -TEST_INT32_SUB_WITH_RET(12)
 | 
| -TEST_INT32_SUB_WITH_RET(13)
 | 
| -TEST_INT32_SUB_WITH_RET(14)
 | 
| -TEST_INT32_SUB_WITH_RET(15)
 | 
| -TEST_INT32_SUB_WITH_RET(16)
 | 
| -TEST_INT32_SUB_WITH_RET(17)
 | 
| -TEST_INT32_SUB_WITH_RET(18)
 | 
| -TEST_INT32_SUB_WITH_RET(19)
 | 
| -
 | 
| -
 | 
| -TEST(Run_Int32Sub_all_allocatable_single) {
 | 
| -#ifdef NATIVE_STACK_PARAMS_OK
 | 
| -  Int32Signature sig(2);
 | 
| -  RegisterPairs pairs;
 | 
| -  while (pairs.More()) {
 | 
| -    Zone zone;
 | 
| -    int parray[1];
 | 
| -    int rarray[1];
 | 
| -    pairs.Next(&rarray[0], &parray[0], true);
 | 
| -    Allocator params(parray, 1, nullptr, 0);
 | 
| -    Allocator rets(rarray, 1, nullptr, 0);
 | 
| -    RegisterConfig config(params, rets);
 | 
| -    CallDescriptor* desc = config.Create(&zone, &sig);
 | 
| -    TestInt32Sub(desc);
 | 
| -  }
 | 
| -#endif  // NATIVE_STACK_PARAMS_OK
 | 
| -}
 | 
| -
 | 
| -
 | 
| -TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
 | 
| -#ifdef NATIVE_STACK_PARAMS_OK
 | 
| -  Int32Signature sig(20);
 | 
| -  RegisterPairs pairs;
 | 
| -  while (pairs.More()) {
 | 
| -    Zone zone;
 | 
| -    int parray[2];
 | 
| -    int rarray[] = {0};
 | 
| -    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);
 | 
| -    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(
 | 
| -    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;
 | 
| -  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);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static uint32_t coeff[] = {1,  2,  3,  5,  7,   11,  13,  17,  19, 23, 29,
 | 
| -                           31, 37, 41, 43, 47,  53,  59,  61,  67, 71, 73,
 | 
| -                           79, 83, 89, 97, 101, 103, 107, 109, 113};
 | 
| -
 | 
| -
 | 
| -static void Build_Int32_WeightedSum(CallDescriptor* desc,
 | 
| -                                    RawMachineAssembler& raw) {
 | 
| -  Node* result = raw.Int32Constant(0);
 | 
| -  for (int i = 0; i < ParamCount(desc); i++) {
 | 
| -    Node* term = raw.Int32Mul(raw.Parameter(i), raw.Int32Constant(coeff[i]));
 | 
| -    result = raw.Int32Add(result, term);
 | 
| -  }
 | 
| -  raw.Return(result);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static int32_t Compute_Int32_WeightedSum(CallDescriptor* desc, int32_t* input) {
 | 
| -  uint32_t result = 0;
 | 
| -  for (int i = 0; i < ParamCount(desc); i++) {
 | 
| -    result += static_cast<uint32_t>(input[i]) * coeff[i];
 | 
| -  }
 | 
| -  return static_cast<int32_t>(result);
 | 
| -}
 | 
| -
 | 
| -
 | 
| -static void Test_Int32_WeightedSum_of_size(int count) {
 | 
| -  Int32Signature sig(count);
 | 
| -  for (int p0 = 0; p0 < Register::kMaxNumAllocatableRegisters; p0++) {
 | 
| -    Zone zone;
 | 
| -
 | 
| -    int parray[] = {p0};
 | 
| -    int rarray[] = {0};
 | 
| -    Allocator params(parray, 1, nullptr, 0);
 | 
| -    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);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Separate tests for parallelization.
 | 
| -#define TEST_INT32_WEIGHTEDSUM(x) \
 | 
| -  TEST(Run_Int32_WeightedSum_##x) { Test_Int32_WeightedSum_of_size(x); }
 | 
| -
 | 
| -
 | 
| -TEST_INT32_WEIGHTEDSUM(1)
 | 
| -TEST_INT32_WEIGHTEDSUM(2)
 | 
| -TEST_INT32_WEIGHTEDSUM(3)
 | 
| -TEST_INT32_WEIGHTEDSUM(4)
 | 
| -TEST_INT32_WEIGHTEDSUM(5)
 | 
| -TEST_INT32_WEIGHTEDSUM(7)
 | 
| -TEST_INT32_WEIGHTEDSUM(9)
 | 
| -TEST_INT32_WEIGHTEDSUM(11)
 | 
| -TEST_INT32_WEIGHTEDSUM(17)
 | 
| -TEST_INT32_WEIGHTEDSUM(19)
 | 
| -
 | 
| -
 | 
| -template <int which>
 | 
| -static void Build_Int32_Select(CallDescriptor* desc, RawMachineAssembler& raw) {
 | 
| -  raw.Return(raw.Parameter(which));
 | 
| -}
 | 
| -
 | 
| -
 | 
| -template <int which>
 | 
| -static int32_t Compute_Int32_Select(CallDescriptor* desc, int32_t* inputs) {
 | 
| -  return inputs[which];
 | 
| -}
 | 
| -
 | 
| -
 | 
| -template <int which>
 | 
| -void Test_Int32_Select() {
 | 
| -  int parray[] = {0};
 | 
| -  int rarray[] = {0};
 | 
| -  Allocator params(parray, 1, nullptr, 0);
 | 
| -  Allocator rets(rarray, 1, nullptr, 0);
 | 
| -  RegisterConfig config(params, rets);
 | 
| -
 | 
| -  Zone zone;
 | 
| -  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);
 | 
| -  }
 | 
| -}
 | 
| -
 | 
| -
 | 
| -// Separate tests for parallelization.
 | 
| -#define TEST_INT32_SELECT(x) \
 | 
| -  TEST(Run_Int32_Select_##x) { Test_Int32_Select<x>(); }
 | 
| -
 | 
| -
 | 
| -TEST_INT32_SELECT(0)
 | 
| -TEST_INT32_SELECT(1)
 | 
| -TEST_INT32_SELECT(2)
 | 
| -TEST_INT32_SELECT(3)
 | 
| -TEST_INT32_SELECT(4)
 | 
| -TEST_INT32_SELECT(5)
 | 
| -TEST_INT32_SELECT(6)
 | 
| -TEST_INT32_SELECT(11)
 | 
| -TEST_INT32_SELECT(15)
 | 
| -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.
 | 
| -}
 | 
| 
 |