// 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.

#include "src/assembler.h"
#include "src/codegen.h"
#include "src/compiler/linkage.h"
#include "src/compiler/raw-machine-assembler.h"
#include "src/machine-type.h"
#include "src/objects-inl.h"
#include "src/register-configuration.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"

namespace v8 {
namespace internal {
namespace compiler {
namespace test_run_native_calls {

const auto GetRegConfig = RegisterConfiguration::Default;

namespace {
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 Pairs {
 public:
  Pairs(int max_pairs, int range, const int* codes)
      : range_(range),
        codes_(codes),
        max_pairs_(std::min(max_pairs, range_ * range_)),
        counter_(0) {}

  bool More() { return counter_ < max_pairs_; }

  void Next(int* r0, int* r1, bool same_is_ok) {
    do {
      // Find the next pair.
      if (exhaustive()) {
        *r0 = codes_[counter_ % range_];
        *r1 = codes_[counter_ / range_];
      } else {
        // Try each integer at least once for both r0 and r1.
        int index = counter_ / 2;
        if (counter_ & 1) {
          *r0 = codes_[index % range_];
          *r1 = codes_[index / range_];
        } else {
          *r1 = codes_[index % range_];
          *r0 = codes_[index / range_];
        }
      }
      counter_++;
      if ((same_is_ok) || (*r0 != *r1)) break;
      if (counter_ == max_pairs_) {
        // For the last hurrah, reg#0 with reg#n-1
        *r0 = codes_[0];
        *r1 = codes_[range_ - 1];
        break;
      }
    } while (true);
  }

 private:
  int range_;
  const int* codes_;
  int max_pairs_;
  int counter_;
  bool exhaustive() { return max_pairs_ == (range_ * range_); }
};


// Pairs of general purpose registers.
class RegisterPairs : public Pairs {
 public:
  RegisterPairs()
      : Pairs(100, GetRegConfig()->num_allocatable_general_registers(),
              GetRegConfig()->allocatable_general_codes()) {}
};


// Pairs of double registers.
class Float32RegisterPairs : public Pairs {
 public:
  Float32RegisterPairs()
      : Pairs(
            100,
#if V8_TARGET_ARCH_ARM
            // TODO(bbudge) Modify wasm linkage to allow use of all float regs.
            GetRegConfig()->num_allocatable_double_registers() / 2 - 2,
#else
            GetRegConfig()->num_allocatable_double_registers(),
#endif
            GetRegConfig()->allocatable_double_codes()) {
  }
};


// Pairs of double registers.
class Float64RegisterPairs : public Pairs {
 public:
  Float64RegisterPairs()
      : Pairs(100, GetRegConfig()->num_allocatable_double_registers(),
              GetRegConfig()->allocatable_double_codes()) {}
};


// 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.representation())) {
      // Allocate a floating point register/stack location.
      if (fp_offset < fp_count) {
        int code = fp_regs[fp_offset++];
#if V8_TARGET_ARCH_ARM
        // TODO(bbudge) Modify wasm linkage to allow use of all float regs.
        if (type.representation() == MachineRepresentation::kFloat32) code *= 2;
#endif
        return LinkageLocation::ForRegister(code, type);
      } else {
        int offset = -1 - stack_offset;
        stack_offset += StackWords(type);
        return LinkageLocation::ForCallerFrameSlot(offset, type);
      }
    } else {
      // Allocate a general purpose register/stack location.
      if (gp_offset < gp_count) {
        return LinkageLocation::ForRegister(gp_regs[gp_offset++], type);
      } else {
        int offset = -1 - stack_offset;
        stack_offset += StackWords(type);
        return LinkageLocation::ForCallerFrameSlot(offset, type);
      }
    }
  }
  int StackWords(MachineType type) {
    int size = 1 << ElementSizeLog2Of(type.representation());
    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 = MachineType::AnyTagged();
    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
        locations.Build(),                  // location_sig
        stack_param_count,                  // stack_parameter_count
        compiler::Operator::kNoProperties,  // properties
        kCalleeSaveRegisters,               // callee-saved registers
        kCalleeSaveFPRegisters,             // callee-saved fp regs
        CallDescriptor::kUseNativeStack,    // flags
        "c-call");
  }

 private:
  Allocator& params;
  Allocator& rets;
};

const int kMaxParamCount = 64;

MachineType kIntTypes[kMaxParamCount + 1] = {
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32(), MachineType::Int32(),
    MachineType::Int32(), MachineType::Int32()};


// For making uniform int32 signatures shorter.
class Int32Signature : public MachineSignature {
 public:
  explicit Int32Signature(int param_count)
      : MachineSignature(1, param_count, kIntTypes) {
    CHECK_GE(kMaxParamCount, param_count);
  }
};


Handle<Code> CompileGraph(const char* name, CallDescriptor* desc, Graph* graph,
                          Schedule* schedule = nullptr) {
  Isolate* isolate = CcTest::InitIsolateOnce();
  CompilationInfo info(ArrayVector("testing"), isolate, graph->zone(),
                       Code::STUB);
  Handle<Code> code =
      Pipeline::GenerateCodeForTesting(&info, 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(inner->GetIsolate()->allocator(), ZONE_NAME);
  int param_count = static_cast<int>(desc->ParameterCount());
  GraphAndBuilders caller(&zone);
  {
    GraphAndBuilders& b = caller;
    Node* start = b.graph()->NewNode(b.common()->Start(param_count + 3));
    b.graph()->SetStart(start);
    Node* target = b.graph()->NewNode(b.common()->HeapConstant(inner));

    // 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* zero = b.graph()->NewNode(b.common()->Int32Constant(0));
    Node* ret =
        b.graph()->NewNode(b.common()->Return(), zero, call, call, start);
    b.graph()->SetEnd(ret);
  }

  MachineSignature* msig = desc->GetMachineSignature(&zone);
  CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, msig);

  return CompileGraph("wrapper", cdesc, caller.graph());
}


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_GE(kMaxParamCount, param_count);
    }
  };

  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>().representation(), base, offset,
                     value, kNoWriteBarrier);
  }

  // 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 < kMaxParamCount; 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 < kMaxParamCount; 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 < kMaxParamCount; 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 < kMaxParamCount; 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->ParameterCount());
}


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(isolate->allocator(), ZONE_NAME);
      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(isolate->allocator(), ZONE_NAME);
        Graph graph(&zone);
        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
        RawMachineAssembler raw(isolate, &graph, cdesc);
        Node* target = raw.HeapConstant(inner);
        Node** inputs = zone.NewArray<Node*>(num_params + 1);
        int input_count = 0;
        inputs[input_count++] = target;
        for (int i = 0; i < num_params; i++) {
          inputs[input_count++] = io.MakeConstant(raw, io.input[i]);
        }

        Node* call = raw.CallN(desc, input_count, inputs);
        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(isolate->allocator(), ZONE_NAME);
        Graph graph(&zone);
        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
        RawMachineAssembler raw(isolate, &graph, cdesc);
        Node* base = raw.PointerConstant(io.input);
        Node* target = raw.HeapConstant(inner);
        Node** inputs = zone.NewArray<Node*>(kMaxParamCount + 1);
        int input_count = 0;
        inputs[input_count++] = target;
        for (int i = 0; i < num_params; i++) {
          inputs[input_count++] = io.LoadInput(raw, base, i);
        }

        Node* call = raw.CallN(desc, input_count, inputs);
        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


static void TestInt32Sub(CallDescriptor* desc) {
  Isolate* isolate = CcTest::InitIsolateOnce();
  HandleScope scope(isolate);
  Zone zone(isolate->allocator(), ZONE_NAME);
  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* zero = b.graph()->NewNode(b.common()->Int32Constant(0));
    Node* ret =
        b.graph()->NewNode(b.common()->Return(), zero, 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 = desc->GetMachineSignature(&zone);
  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);
    }
  }
}


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(isolate->allocator(), ZONE_NAME);
    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(MachineRepresentation::kWord32, base, offset, raw.Parameter(i),
                kNoWriteBarrier);
    }
    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(isolate->allocator(), ZONE_NAME);
    Graph graph(&zone);
    CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
    RawMachineAssembler raw(isolate, &graph, cdesc);
    Node* base = raw.PointerConstant(input);
    Node* target = raw.HeapConstant(inner);
    Node** inputs = zone.NewArray<Node*>(kNumParams + 1);
    int input_count = 0;
    inputs[input_count++] = target;
    for (int i = 0; i < kNumParams; i++) {
      Node* offset = raw.Int32Constant(i * sizeof(int32_t));
      inputs[input_count++] = raw.Load(MachineType::Int32(), base, offset);
    }

    Node* call = raw.CallN(desc, input_count, inputs);
    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]);
    }
  }
}


static void Test_RunInt32SubWithRet(int retreg) {
  Int32Signature sig(2);
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  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 (x < Register::kNumRegisters &&                 \
        GetRegConfig()->IsAllocatableGeneralCode(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) {
  Int32Signature sig(2);
  RegisterPairs pairs;
  while (pairs.More()) {
    v8::internal::AccountingAllocator allocator;
    Zone zone(&allocator, ZONE_NAME);
    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);
  }
}


TEST(Run_CopyTwentyInt32_all_allocatable_pairs) {
  Int32Signature sig(20);
  RegisterPairs pairs;
  while (pairs.More()) {
    v8::internal::AccountingAllocator allocator;
    Zone zone(&allocator, ZONE_NAME);
    int parray[2];
    int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(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);
  }
}


template <typename CType>
static void Run_Computation(
    CallDescriptor* desc, void (*build)(CallDescriptor*, RawMachineAssembler&),
    CType (*compute)(CallDescriptor*, CType* inputs), int seed = 1) {
  Computer<CType>::Run(desc, build, compute, seed);
}


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::kNumRegisters; p0++) {
    if (GetRegConfig()->IsAllocatableGeneralCode(p0)) {
      v8::internal::AccountingAllocator allocator;
      Zone zone(&allocator, ZONE_NAME);

      int parray[] = {p0};
      int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
      Allocator params(parray, 1, nullptr, 0);
      Allocator rets(rarray, 1, nullptr, 0);
      RegisterConfig config(params, rets);
      CallDescriptor* desc = config.Create(&zone, &sig);
      Run_Computation<int32_t>(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_Select(CallDescriptor* desc, RawMachineAssembler& raw) {
  raw.Return(raw.Parameter(which));
}


template <typename CType, int which>
static CType Compute_Select(CallDescriptor* desc, CType* inputs) {
  return inputs[which];
}


template <typename CType, int which>
static void RunSelect(CallDescriptor* desc) {
  int count = ParamCount(desc);
  if (count <= which) return;
  Run_Computation<CType>(desc, Build_Select<which>,
                         Compute_Select<CType, which>,
                         1044 + which + 3 * sizeof(CType));
}


template <int which>
void Test_Int32_Select() {
  int parray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
  int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
  Allocator params(parray, 1, nullptr, 0);
  Allocator rets(rarray, 1, nullptr, 0);
  RegisterConfig config(params, rets);

  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);

  for (int i = which + 1; i <= 64; i++) {
    Int32Signature sig(i);
    CallDescriptor* desc = config.Create(&zone, &sig);
    RunSelect<int32_t, which>(desc);
  }
}


// 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)


TEST(Int64Select_registers) {
  if (GetRegConfig()->num_allocatable_general_registers() < 2) return;
  if (kPointerSize < 8) return;  // TODO(titzer): int64 on 32-bit platforms

  int rarray[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
  ArgsBuffer<int64_t>::Sig sig(2);

  RegisterPairs pairs;
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  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);
    RunSelect<int64_t, 0>(desc);
    RunSelect<int64_t, 1>(desc);
  }
}


TEST(Float32Select_registers) {
  if (GetRegConfig()->num_allocatable_double_registers() < 2) {
    return;
  }

  int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  ArgsBuffer<float32>::Sig sig(2);

  Float32RegisterPairs pairs;
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  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);
    RunSelect<float32, 0>(desc);
    RunSelect<float32, 1>(desc);
  }
}


TEST(Float64Select_registers) {
  if (GetRegConfig()->num_allocatable_double_registers() < 2) return;
  if (GetRegConfig()->num_allocatable_general_registers() < 2) return;
  int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  ArgsBuffer<float64>::Sig sig(2);

  Float64RegisterPairs pairs;
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  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);
    RunSelect<float64, 0>(desc);
    RunSelect<float64, 1>(desc);
  }
}


TEST(Float32Select_stack_params_return_reg) {
  int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  Allocator params(nullptr, 0, nullptr, 0);
  Allocator rets(nullptr, 0, rarray, 1);
  RegisterConfig config(params, rets);

  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  for (int count = 1; count < 6; count++) {
    ArgsBuffer<float32>::Sig sig(count);
    CallDescriptor* desc = config.Create(&zone, &sig);
    RunSelect<float32, 0>(desc);
    RunSelect<float32, 1>(desc);
    RunSelect<float32, 2>(desc);
    RunSelect<float32, 3>(desc);
    RunSelect<float32, 4>(desc);
    RunSelect<float32, 5>(desc);
  }
}


TEST(Float64Select_stack_params_return_reg) {
  int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  Allocator params(nullptr, 0, nullptr, 0);
  Allocator rets(nullptr, 0, rarray, 1);
  RegisterConfig config(params, rets);

  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  for (int count = 1; count < 6; count++) {
    ArgsBuffer<float64>::Sig sig(count);
    CallDescriptor* desc = config.Create(&zone, &sig);
    RunSelect<float64, 0>(desc);
    RunSelect<float64, 1>(desc);
    RunSelect<float64, 2>(desc);
    RunSelect<float64, 3>(desc);
    RunSelect<float64, 4>(desc);
    RunSelect<float64, 5>(desc);
  }
}


template <typename CType, int which>
static void Build_Select_With_Call(CallDescriptor* desc,
                                   RawMachineAssembler& raw) {
  Handle<Code> inner = Handle<Code>::null();
  int num_params = ParamCount(desc);
  CHECK_LE(num_params, kMaxParamCount);
  {
    Isolate* isolate = CcTest::InitIsolateOnce();
    // Build the actual select.
    Zone zone(isolate->allocator(), ZONE_NAME);
    Graph graph(&zone);
    RawMachineAssembler raw(isolate, &graph, desc);
    raw.Return(raw.Parameter(which));
    inner = CompileGraph("Select-indirection", desc, &graph, raw.Export());
    CHECK(!inner.is_null());
    CHECK(inner->IsCode());
  }

  {
    // Build a call to the function that does the select.
    Node* target = raw.HeapConstant(inner);
    Node** inputs = raw.zone()->NewArray<Node*>(num_params + 1);
    int input_count = 0;
    inputs[input_count++] = target;
    for (int i = 0; i < num_params; i++) {
      inputs[input_count++] = raw.Parameter(i);
    }

    Node* call = raw.CallN(desc, input_count, inputs);
    raw.Return(call);
  }
}


TEST(Float64StackParamsToStackParams) {
  int rarray[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  Allocator params(nullptr, 0, nullptr, 0);
  Allocator rets(nullptr, 0, rarray, 1);

  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  ArgsBuffer<float64>::Sig sig(2);
  RegisterConfig config(params, rets);
  CallDescriptor* desc = config.Create(&zone, &sig);

  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 0>,
                           Compute_Select<float64, 0>, 1098);

  Run_Computation<float64>(desc, Build_Select_With_Call<float64, 1>,
                           Compute_Select<float64, 1>, 1099);
}


void MixedParamTest(int start) {
  if (GetRegConfig()->num_double_registers() < 2) return;

// TODO(titzer): mix in 64-bit types on all platforms when supported.
#if V8_TARGET_ARCH_32_BIT
  static MachineType types[] = {
      MachineType::Int32(),   MachineType::Float32(), MachineType::Float64(),
      MachineType::Int32(),   MachineType::Float64(), MachineType::Float32(),
      MachineType::Float32(), MachineType::Float64(), MachineType::Int32(),
      MachineType::Float32(), MachineType::Int32(),   MachineType::Float64(),
      MachineType::Float64(), MachineType::Float32(), MachineType::Int32(),
      MachineType::Float64(), MachineType::Int32(),   MachineType::Float32()};
#else
  static MachineType types[] = {
      MachineType::Int32(),   MachineType::Int64(),   MachineType::Float32(),
      MachineType::Float64(), MachineType::Int32(),   MachineType::Float64(),
      MachineType::Float32(), MachineType::Int64(),   MachineType::Int64(),
      MachineType::Float32(), MachineType::Float32(), MachineType::Int32(),
      MachineType::Float64(), MachineType::Float64(), MachineType::Int64(),
      MachineType::Int32(),   MachineType::Float64(), MachineType::Int32(),
      MachineType::Float32()};
#endif

  Isolate* isolate = CcTest::InitIsolateOnce();

  // Build machine signature
  MachineType* params = &types[start];
  const int num_params = static_cast<int>(arraysize(types) - start);

  // Build call descriptor
  int parray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0),
                     GetRegConfig()->GetAllocatableGeneralCode(1)};
  int rarray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
  int parray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0),
                     GetRegConfig()->GetAllocatableDoubleCode(1)};
  int rarray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  Allocator palloc(parray_gp, 2, parray_fp, 2);
  Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
  RegisterConfig config(palloc, ralloc);

  for (int which = 0; which < num_params; which++) {
    v8::internal::AccountingAllocator allocator;
    Zone zone(&allocator, ZONE_NAME);
    HandleScope scope(isolate);
    MachineSignature::Builder builder(&zone, 1, num_params);
    builder.AddReturn(params[which]);
    for (int j = 0; j < num_params; j++) builder.AddParam(params[j]);
    MachineSignature* sig = builder.Build();
    CallDescriptor* desc = config.Create(&zone, sig);

    Handle<Code> select;
    {
      // build the select.
      Zone zone(&allocator, ZONE_NAME);
      Graph graph(&zone);
      RawMachineAssembler raw(isolate, &graph, desc);
      raw.Return(raw.Parameter(which));
      select = CompileGraph("Compute", desc, &graph, raw.Export());
    }

    {
      // call the select.
      Handle<Code> wrapper = Handle<Code>::null();
      int32_t expected_ret;
      char bytes[kDoubleSize];
      V8_ALIGNED(8) char output[kDoubleSize];
      int expected_size = 0;
      CSignature0<int32_t> csig;
      {
        // Wrap the select code with a callable function that passes constants.
        Zone zone(&allocator, ZONE_NAME);
        Graph graph(&zone);
        CallDescriptor* cdesc = Linkage::GetSimplifiedCDescriptor(&zone, &csig);
        RawMachineAssembler raw(isolate, &graph, cdesc);
        Node* target = raw.HeapConstant(select);
        Node** inputs = zone.NewArray<Node*>(num_params + 1);
        int input_count = 0;
        inputs[input_count++] = target;
        int64_t constant = 0x0102030405060708;
        for (int i = 0; i < num_params; i++) {
          MachineType param_type = sig->GetParam(i);
          Node* konst = nullptr;
          if (param_type == MachineType::Int32()) {
            int32_t value[] = {static_cast<int32_t>(constant)};
            konst = raw.Int32Constant(value[0]);
            if (i == which) memcpy(bytes, value, expected_size = 4);
          }
          if (param_type == MachineType::Int64()) {
            int64_t value[] = {static_cast<int64_t>(constant)};
            konst = raw.Int64Constant(value[0]);
            if (i == which) memcpy(bytes, value, expected_size = 8);
          }
          if (param_type == MachineType::Float32()) {
            float32 value[] = {static_cast<float32>(constant)};
            konst = raw.Float32Constant(value[0]);
            if (i == which) memcpy(bytes, value, expected_size = 4);
          }
          if (param_type == MachineType::Float64()) {
            float64 value[] = {static_cast<float64>(constant)};
            konst = raw.Float64Constant(value[0]);
            if (i == which) memcpy(bytes, value, expected_size = 8);
          }
          CHECK_NOT_NULL(konst);

          inputs[input_count++] = konst;
          constant += 0x1010101010101010;
        }

        Node* call = raw.CallN(desc, input_count, inputs);
        Node* store =
            raw.StoreToPointer(output, sig->GetReturn().representation(), call);
        USE(store);
        expected_ret = static_cast<int32_t>(constant);
        raw.Return(raw.Int32Constant(expected_ret));
        wrapper = CompileGraph("Select-mixed-wrapper-const", cdesc, &graph,
                               raw.Export());
      }

      CodeRunner<int32_t> runnable(isolate, wrapper, &csig);
      CHECK_EQ(expected_ret, runnable.Call());
      for (int i = 0; i < expected_size; i++) {
        CHECK_EQ(static_cast<int>(bytes[i]), static_cast<int>(output[i]));
      }
    }
  }
}


TEST(MixedParams_0) { MixedParamTest(0); }
TEST(MixedParams_1) { MixedParamTest(1); }
TEST(MixedParams_2) { MixedParamTest(2); }
TEST(MixedParams_3) { MixedParamTest(3); }

template <typename T>
void TestStackSlot(MachineType slot_type, T expected) {
  // Test: Generate with a function f which reserves a stack slot, call an inner
  // function g from f which writes into the stack slot of f.

  if (GetRegConfig()->num_allocatable_double_registers() < 2) return;

  Isolate* isolate = CcTest::InitIsolateOnce();

  // Lots of code to generate the build descriptor for the inner function.
  int parray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0),
                     GetRegConfig()->GetAllocatableGeneralCode(1)};
  int rarray_gp[] = {GetRegConfig()->GetAllocatableGeneralCode(0)};
  int parray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0),
                     GetRegConfig()->GetAllocatableDoubleCode(1)};
  int rarray_fp[] = {GetRegConfig()->GetAllocatableDoubleCode(0)};
  Allocator palloc(parray_gp, 2, parray_fp, 2);
  Allocator ralloc(rarray_gp, 1, rarray_fp, 1);
  RegisterConfig config(palloc, ralloc);

  Zone zone(isolate->allocator(), ZONE_NAME);
  HandleScope scope(isolate);
  MachineSignature::Builder builder(&zone, 1, 12);
  builder.AddReturn(MachineType::Int32());
  for (int i = 0; i < 10; i++) {
    builder.AddParam(MachineType::Int32());
  }
  builder.AddParam(slot_type);
  builder.AddParam(MachineType::Pointer());
  MachineSignature* sig = builder.Build();
  CallDescriptor* desc = config.Create(&zone, sig);

  // Create inner function g. g has lots of parameters so that they are passed
  // over the stack.
  Handle<Code> inner;
  Graph graph(&zone);
  RawMachineAssembler g(isolate, &graph, desc);

  g.Store(slot_type.representation(), g.Parameter(11), g.Parameter(10),
          WriteBarrierKind::kNoWriteBarrier);
  g.Return(g.Parameter(9));
  inner = CompileGraph("Compute", desc, &graph, g.Export());

  // Create function f with a stack slot which calls the inner function g.
  BufferedRawMachineAssemblerTester<T> f(slot_type);
  Node* target = f.HeapConstant(inner);
  Node* stack_slot = f.StackSlot(slot_type.representation());
  Node* nodes[14];
  int input_count = 0;
  nodes[input_count++] = target;
  for (int i = 0; i < 10; i++) {
    nodes[input_count++] = f.Int32Constant(i);
  }
  nodes[input_count++] = f.Parameter(0);
  nodes[input_count++] = stack_slot;

  f.CallN(desc, input_count, nodes);
  f.Return(f.Load(slot_type, stack_slot, f.IntPtrConstant(0)));

  CHECK_EQ(expected, f.Call(expected));
}

TEST(RunStackSlotInt32) {
  int32_t magic = 0x12345678;
  TestStackSlot(MachineType::Int32(), magic);
}

#if !V8_TARGET_ARCH_32_BIT
TEST(RunStackSlotInt64) {
  int64_t magic = 0x123456789abcdef0;
  TestStackSlot(MachineType::Int64(), magic);
}
#endif

TEST(RunStackSlotFloat32) {
  float magic = 1234.125f;
  TestStackSlot(MachineType::Float32(), magic);
}

TEST(RunStackSlotFloat64) {
  double magic = 3456.375;
  TestStackSlot(MachineType::Float64(), magic);
}

}  // namespace test_run_native_calls
}  // namespace compiler
}  // namespace internal
}  // namespace v8
