// 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/compiler/opcodes.h"
#include "src/compiler/operator.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
#include "src/types.h"
#include "test/unittests/test-utils.h"

namespace v8 {
namespace internal {
namespace compiler {

// -----------------------------------------------------------------------------
// Pure operators.


namespace {

struct PureOperator {
  const Operator* (SimplifiedOperatorBuilder::*constructor)();
  IrOpcode::Value opcode;
  Operator::Properties properties;
  int value_input_count;
};


std::ostream& operator<<(std::ostream& os, const PureOperator& pop) {
  return os << IrOpcode::Mnemonic(pop.opcode);
}

const PureOperator kPureOperators[] = {
#define PURE(Name, properties, input_count)              \
  {                                                      \
    &SimplifiedOperatorBuilder::Name, IrOpcode::k##Name, \
        Operator::kPure | properties, input_count        \
  }
    PURE(BooleanNot, Operator::kNoProperties, 1),
    PURE(BooleanToNumber, Operator::kNoProperties, 1),
    PURE(NumberEqual, Operator::kCommutative, 2),
    PURE(NumberLessThan, Operator::kNoProperties, 2),
    PURE(NumberLessThanOrEqual, Operator::kNoProperties, 2),
    PURE(NumberAdd, Operator::kCommutative, 2),
    PURE(NumberSubtract, Operator::kNoProperties, 2),
    PURE(NumberMultiply, Operator::kCommutative, 2),
    PURE(NumberDivide, Operator::kNoProperties, 2),
    PURE(NumberModulus, Operator::kNoProperties, 2),
    PURE(NumberBitwiseOr, Operator::kCommutative, 2),
    PURE(NumberBitwiseXor, Operator::kCommutative, 2),
    PURE(NumberBitwiseAnd, Operator::kCommutative, 2),
    PURE(NumberShiftLeft, Operator::kNoProperties, 2),
    PURE(NumberShiftRight, Operator::kNoProperties, 2),
    PURE(NumberShiftRightLogical, Operator::kNoProperties, 2),
    PURE(NumberToInt32, Operator::kNoProperties, 1),
    PURE(NumberToUint32, Operator::kNoProperties, 1),
    PURE(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1),
    PURE(ChangeTaggedToInt32, Operator::kNoProperties, 1),
    PURE(ChangeTaggedToUint32, Operator::kNoProperties, 1),
    PURE(ChangeTaggedToFloat64, Operator::kNoProperties, 1),
    PURE(ChangeInt32ToTagged, Operator::kNoProperties, 1),
    PURE(ChangeUint32ToTagged, Operator::kNoProperties, 1),
    PURE(ChangeFloat64ToTagged, Operator::kNoProperties, 1),
    PURE(ChangeTaggedToBit, Operator::kNoProperties, 1),
    PURE(ChangeBitToTagged, Operator::kNoProperties, 1),
    PURE(TruncateTaggedToWord32, Operator::kNoProperties, 1),
    PURE(ObjectIsNumber, Operator::kNoProperties, 1),
    PURE(ObjectIsReceiver, Operator::kNoProperties, 1),
    PURE(ObjectIsSmi, Operator::kNoProperties, 1)
#undef PURE
};

}  // namespace


class SimplifiedPureOperatorTest
    : public TestWithZone,
      public ::testing::WithParamInterface<PureOperator> {};


TEST_P(SimplifiedPureOperatorTest, InstancesAreGloballyShared) {
  const PureOperator& pop = GetParam();
  SimplifiedOperatorBuilder simplified1(zone());
  SimplifiedOperatorBuilder simplified2(zone());
  EXPECT_EQ((simplified1.*pop.constructor)(), (simplified2.*pop.constructor)());
}


TEST_P(SimplifiedPureOperatorTest, NumberOfInputsAndOutputs) {
  SimplifiedOperatorBuilder simplified(zone());
  const PureOperator& pop = GetParam();
  const Operator* op = (simplified.*pop.constructor)();

  EXPECT_EQ(pop.value_input_count, op->ValueInputCount());
  EXPECT_EQ(0, op->EffectInputCount());
  EXPECT_EQ(0, op->ControlInputCount());
  EXPECT_EQ(pop.value_input_count, OperatorProperties::GetTotalInputCount(op));

  EXPECT_EQ(1, op->ValueOutputCount());
  EXPECT_EQ(0, op->EffectOutputCount());
  EXPECT_EQ(0, op->ControlOutputCount());
}


TEST_P(SimplifiedPureOperatorTest, OpcodeIsCorrect) {
  SimplifiedOperatorBuilder simplified(zone());
  const PureOperator& pop = GetParam();
  const Operator* op = (simplified.*pop.constructor)();
  EXPECT_EQ(pop.opcode, op->opcode());
}


TEST_P(SimplifiedPureOperatorTest, Properties) {
  SimplifiedOperatorBuilder simplified(zone());
  const PureOperator& pop = GetParam();
  const Operator* op = (simplified.*pop.constructor)();
  EXPECT_EQ(pop.properties, op->properties() & pop.properties);
}

INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest, SimplifiedPureOperatorTest,
                        ::testing::ValuesIn(kPureOperators));


// -----------------------------------------------------------------------------
// Buffer access operators.


namespace {

const ExternalArrayType kExternalArrayTypes[] = {
    kExternalUint8Array,   kExternalInt8Array,   kExternalUint16Array,
    kExternalInt16Array,   kExternalUint32Array, kExternalInt32Array,
    kExternalFloat32Array, kExternalFloat64Array};

}  // namespace


class SimplifiedBufferAccessOperatorTest
    : public TestWithZone,
      public ::testing::WithParamInterface<ExternalArrayType> {};


TEST_P(SimplifiedBufferAccessOperatorTest, InstancesAreGloballyShared) {
  BufferAccess const access(GetParam());
  SimplifiedOperatorBuilder simplified1(zone());
  SimplifiedOperatorBuilder simplified2(zone());
  EXPECT_EQ(simplified1.LoadBuffer(access), simplified2.LoadBuffer(access));
  EXPECT_EQ(simplified1.StoreBuffer(access), simplified2.StoreBuffer(access));
}


TEST_P(SimplifiedBufferAccessOperatorTest, LoadBuffer) {
  SimplifiedOperatorBuilder simplified(zone());
  BufferAccess const access(GetParam());
  const Operator* op = simplified.LoadBuffer(access);

  EXPECT_EQ(IrOpcode::kLoadBuffer, op->opcode());
  EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
            op->properties());
  EXPECT_EQ(access, BufferAccessOf(op));

  EXPECT_EQ(3, op->ValueInputCount());
  EXPECT_EQ(1, op->EffectInputCount());
  EXPECT_EQ(1, op->ControlInputCount());
  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));

  EXPECT_EQ(1, op->ValueOutputCount());
  EXPECT_EQ(1, op->EffectOutputCount());
  EXPECT_EQ(0, op->ControlOutputCount());
}


TEST_P(SimplifiedBufferAccessOperatorTest, StoreBuffer) {
  SimplifiedOperatorBuilder simplified(zone());
  BufferAccess const access(GetParam());
  const Operator* op = simplified.StoreBuffer(access);

  EXPECT_EQ(IrOpcode::kStoreBuffer, op->opcode());
  EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
            op->properties());
  EXPECT_EQ(access, BufferAccessOf(op));

  EXPECT_EQ(4, op->ValueInputCount());
  EXPECT_EQ(1, op->EffectInputCount());
  EXPECT_EQ(1, op->ControlInputCount());
  EXPECT_EQ(6, OperatorProperties::GetTotalInputCount(op));

  EXPECT_EQ(0, op->ValueOutputCount());
  EXPECT_EQ(1, op->EffectOutputCount());
  EXPECT_EQ(0, op->ControlOutputCount());
}


INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
                        SimplifiedBufferAccessOperatorTest,
                        ::testing::ValuesIn(kExternalArrayTypes));


// -----------------------------------------------------------------------------
// Element access operators.


namespace {

const ElementAccess kElementAccesses[] = {
    {kTaggedBase, FixedArray::kHeaderSize, Type::Any(),
     MachineType::AnyTagged(), kFullWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Int8(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Int16(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Int32(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Uint8(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Uint16(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Any(), MachineType::Uint32(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Signed32(), MachineType::Int8(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint8(),
     kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Signed32(), MachineType::Int16(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint16(),
     kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Signed32(), MachineType::Int32(), kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Unsigned32(), MachineType::Uint32(),
     kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Number(),
     MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
     kNoWriteBarrier},
    {kUntaggedBase, 0, Type::Number(),
     MachineType(MachineRepresentation::kFloat64, MachineSemantic::kNone),
     kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
     MachineType::Int8(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
     MachineType::Uint8(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
     MachineType::Int16(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
     MachineType::Uint16(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Signed32(),
     MachineType::Int32(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Unsigned32(),
     MachineType::Uint32(), kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
     MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
     kNoWriteBarrier},
    {kTaggedBase, FixedTypedArrayBase::kDataOffset, Type::Number(),
     MachineType(MachineRepresentation::kFloat32, MachineSemantic::kNone),
     kNoWriteBarrier}};

}  // namespace


class SimplifiedElementAccessOperatorTest
    : public TestWithZone,
      public ::testing::WithParamInterface<ElementAccess> {};


TEST_P(SimplifiedElementAccessOperatorTest, LoadElement) {
  SimplifiedOperatorBuilder simplified(zone());
  const ElementAccess& access = GetParam();
  const Operator* op = simplified.LoadElement(access);

  EXPECT_EQ(IrOpcode::kLoadElement, op->opcode());
  EXPECT_EQ(Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
            op->properties());
  EXPECT_EQ(access, ElementAccessOf(op));

  EXPECT_EQ(2, op->ValueInputCount());
  EXPECT_EQ(1, op->EffectInputCount());
  EXPECT_EQ(1, op->ControlInputCount());
  EXPECT_EQ(4, OperatorProperties::GetTotalInputCount(op));

  EXPECT_EQ(1, op->ValueOutputCount());
  EXPECT_EQ(1, op->EffectOutputCount());
  EXPECT_EQ(0, op->ControlOutputCount());
}


TEST_P(SimplifiedElementAccessOperatorTest, StoreElement) {
  SimplifiedOperatorBuilder simplified(zone());
  const ElementAccess& access = GetParam();
  const Operator* op = simplified.StoreElement(access);

  EXPECT_EQ(IrOpcode::kStoreElement, op->opcode());
  EXPECT_EQ(Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow,
            op->properties());
  EXPECT_EQ(access, ElementAccessOf(op));

  EXPECT_EQ(3, op->ValueInputCount());
  EXPECT_EQ(1, op->EffectInputCount());
  EXPECT_EQ(1, op->ControlInputCount());
  EXPECT_EQ(5, OperatorProperties::GetTotalInputCount(op));

  EXPECT_EQ(0, op->ValueOutputCount());
  EXPECT_EQ(1, op->EffectOutputCount());
  EXPECT_EQ(0, op->ControlOutputCount());
}


INSTANTIATE_TEST_CASE_P(SimplifiedOperatorTest,
                        SimplifiedElementAccessOperatorTest,
                        ::testing::ValuesIn(kElementAccesses));

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