// 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 <cmath>
#include <functional>
#include <limits>

#include "src/assembler.h"
#include "src/base/bits.h"
#include "src/base/utils/random-number-generator.h"
#include "src/codegen.h"
#include "src/compiler.h"
#include "src/compiler/linkage.h"
#include "src/macro-assembler.h"
#include "src/objects-inl.h"
#include "test/cctest/cctest.h"
#include "test/cctest/compiler/codegen-tester.h"
#include "test/cctest/compiler/value-helper.h"

namespace v8 {
namespace internal {
namespace compiler {

namespace {

CallDescriptor* GetCallDescriptor(Zone* zone, int return_count,
                                  int param_count) {
  LocationSignature::Builder locations(zone, return_count, param_count);
  const RegisterConfiguration* config = RegisterConfiguration::Default();

  // Add return location(s).
  CHECK(return_count <= config->num_allocatable_general_registers());
  for (int i = 0; i < return_count; i++) {
    locations.AddReturn(LinkageLocation::ForRegister(
        config->allocatable_general_codes()[i], MachineType::AnyTagged()));
  }

  // Add register and/or stack parameter(s).
  CHECK(param_count <= config->num_allocatable_general_registers());
  for (int i = 0; i < param_count; i++) {
    locations.AddParam(LinkageLocation::ForRegister(
        config->allocatable_general_codes()[i], MachineType::AnyTagged()));
  }

  const RegList kCalleeSaveRegisters = 0;
  const RegList kCalleeSaveFPRegisters = 0;

  // The target for wasm calls is always a code object.
  MachineType target_type = MachineType::AnyTagged();
  LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
  return new (zone) CallDescriptor(       // --
      CallDescriptor::kCallCodeObject,    // kind
      target_type,                        // target MachineType
      target_loc,                         // target location
      locations.Build(),                  // location_sig
      0,                                  // js_parameter_count
      compiler::Operator::kNoProperties,  // properties
      kCalleeSaveRegisters,               // callee-saved registers
      kCalleeSaveFPRegisters,             // callee-saved fp regs
      CallDescriptor::kNoFlags,           // flags
      "c-call");
}
}  // namespace


TEST(ReturnThreeValues) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  CallDescriptor* desc = GetCallDescriptor(&zone, 3, 2);
  HandleAndZoneScope handles;
  RawMachineAssembler m(handles.main_isolate(),
                        new (handles.main_zone()) Graph(handles.main_zone()),
                        desc, MachineType::PointerRepresentation(),
                        InstructionSelector::SupportedMachineOperatorFlags());

  Node* p0 = m.Parameter(0);
  Node* p1 = m.Parameter(1);
  Node* add = m.Int32Add(p0, p1);
  Node* sub = m.Int32Sub(p0, p1);
  Node* mul = m.Int32Mul(p0, p1);
  m.Return(add, sub, mul);

  CompilationInfo info(ArrayVector("testing"), handles.main_isolate(),
                       handles.main_zone(), Code::STUB);
  Handle<Code> code =
      Pipeline::GenerateCodeForTesting(&info, desc, m.graph(), m.Export());
#ifdef ENABLE_DISASSEMBLER
  if (FLAG_print_code) {
    OFStream os(stdout);
    code->Disassemble("three_value", os);
  }
#endif

  RawMachineAssemblerTester<int32_t> mt;
  Node* a = mt.Int32Constant(123);
  Node* b = mt.Int32Constant(456);
  Node* ret3 = mt.AddNode(mt.common()->Call(desc), mt.HeapConstant(code), a, b);
  Node* x = mt.AddNode(mt.common()->Projection(0), ret3);
  Node* y = mt.AddNode(mt.common()->Projection(1), ret3);
  Node* z = mt.AddNode(mt.common()->Projection(2), ret3);
  Node* ret = mt.Int32Add(mt.Int32Add(x, y), z);
  mt.Return(ret);
#ifdef ENABLE_DISASSEMBLER
  Handle<Code> code2 = mt.GetCode();
  if (FLAG_print_code) {
    OFStream os(stdout);
    code2->Disassemble("three_value_call", os);
  }
#endif
  CHECK_EQ((123 + 456) + (123 - 456) + (123 * 456), mt.Call());
}

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