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

// Test embedded constant pool builder code.

#include "src/init/v8.h"

#include "src/codegen/constant-pool.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {

#if defined(V8_TARGET_ARCH_PPC)

const ConstantPoolEntry::Type kPtrType = ConstantPoolEntry::INTPTR;
const ConstantPoolEntry::Type kDblType = ConstantPoolEntry::DOUBLE;
const ConstantPoolEntry::Access kRegAccess = ConstantPoolEntry::REGULAR;
const ConstantPoolEntry::Access kOvflAccess = ConstantPoolEntry::OVERFLOWED;

const int kReachBits = 6;  // Use reach of 64-bytes to test overflow.
const int kReach = 1 << kReachBits;


TEST(ConstantPoolPointers) {
  ConstantPoolBuilder builder(kReachBits, kReachBits);
  const int kRegularCount = kReach / kPointerSize;
  ConstantPoolEntry::Access access;
  int pos = 0;
  intptr_t value = 0;
  bool sharing_ok = true;

  CHECK(builder.IsEmpty());
  while (builder.NextAccess(kPtrType) == kRegAccess) {
    access = builder.AddEntry(pos++, value++, sharing_ok);
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(pos, kRegularCount);

  access = builder.AddEntry(pos, value, sharing_ok);
  CHECK_EQ(access, kOvflAccess);
}


TEST(ConstantPoolDoubles) {
  ConstantPoolBuilder builder(kReachBits, kReachBits);
  const int kRegularCount = kReach / kDoubleSize;
  ConstantPoolEntry::Access access;
  int pos = 0;
  double value = 0.0;

  CHECK(builder.IsEmpty());
  while (builder.NextAccess(kDblType) == kRegAccess) {
    access = builder.AddEntry(pos++, value);
    value += 0.5;
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(pos, kRegularCount);

  access = builder.AddEntry(pos, value);
  CHECK_EQ(access, kOvflAccess);
}


TEST(ConstantPoolMixedTypes) {
  ConstantPoolBuilder builder(kReachBits, kReachBits);
  const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
                             ((kPointerSize < kDoubleSize) ? 1 : 0));
  ConstantPoolEntry::Type type = kPtrType;
  ConstantPoolEntry::Access access;
  int pos = 0;
  intptr_t ptrValue = 0;
  double dblValue = 0.0;
  bool sharing_ok = true;

  CHECK(builder.IsEmpty());
  while (builder.NextAccess(type) == kRegAccess) {
    if (type == kPtrType) {
      access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
      type = kDblType;
    } else {
      access = builder.AddEntry(pos++, dblValue);
      dblValue += 0.5;
      type = kPtrType;
    }
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(pos, kRegularCount);

  access = builder.AddEntry(pos++, ptrValue, sharing_ok);
  CHECK_EQ(access, kOvflAccess);
  access = builder.AddEntry(pos, dblValue);
  CHECK_EQ(access, kOvflAccess);
}


TEST(ConstantPoolMixedReach) {
  const int ptrReachBits = kReachBits + 2;
  const int ptrReach = 1 << ptrReachBits;
  const int dblReachBits = kReachBits;
  const int dblReach = kReach;
  const int dblRegularCount =
      Min(dblReach / kDoubleSize, ptrReach / (kDoubleSize + kPointerSize));
  const int ptrRegularCount =
      ((ptrReach - (dblRegularCount * (kDoubleSize + kPointerSize))) /
       kPointerSize) +
      dblRegularCount;
  ConstantPoolBuilder builder(ptrReachBits, dblReachBits);
  ConstantPoolEntry::Access access;
  int pos = 0;
  intptr_t ptrValue = 0;
  double dblValue = 0.0;
  bool sharing_ok = true;
  int ptrCount = 0;
  int dblCount = 0;

  CHECK(builder.IsEmpty());
  while (builder.NextAccess(kDblType) == kRegAccess) {
    access = builder.AddEntry(pos++, dblValue);
    dblValue += 0.5;
    dblCount++;
    CHECK_EQ(access, kRegAccess);

    access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
    ptrCount++;
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(dblCount, dblRegularCount);

  while (ptrCount < ptrRegularCount) {
    access = builder.AddEntry(pos++, dblValue);
    dblValue += 0.5;
    CHECK_EQ(access, kOvflAccess);

    access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
    ptrCount++;
    CHECK_EQ(access, kRegAccess);
  }
  CHECK_EQ(builder.NextAccess(kPtrType), kOvflAccess);

  access = builder.AddEntry(pos++, ptrValue, sharing_ok);
  CHECK_EQ(access, kOvflAccess);
  access = builder.AddEntry(pos, dblValue);
  CHECK_EQ(access, kOvflAccess);
}


TEST(ConstantPoolSharing) {
  ConstantPoolBuilder builder(kReachBits, kReachBits);
  const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
                             ((kPointerSize < kDoubleSize) ? 1 : 0));
  ConstantPoolEntry::Access access;

  CHECK(builder.IsEmpty());

  ConstantPoolEntry::Type type = kPtrType;
  int pos = 0;
  intptr_t ptrValue = 0;
  double dblValue = 0.0;
  bool sharing_ok = true;
  while (builder.NextAccess(type) == kRegAccess) {
    if (type == kPtrType) {
      access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
      type = kDblType;
    } else {
      access = builder.AddEntry(pos++, dblValue);
      dblValue += 0.5;
      type = kPtrType;
    }
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(pos, kRegularCount);

  type = kPtrType;
  ptrValue = 0;
  dblValue = 0.0;
  while (pos < kRegularCount * 2) {
    if (type == kPtrType) {
      access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
      type = kDblType;
    } else {
      access = builder.AddEntry(pos++, dblValue);
      dblValue += 0.5;
      type = kPtrType;
    }
    CHECK_EQ(access, kRegAccess);
  }

  access = builder.AddEntry(pos++, ptrValue, sharing_ok);
  CHECK_EQ(access, kOvflAccess);
  access = builder.AddEntry(pos, dblValue);
  CHECK_EQ(access, kOvflAccess);
}


TEST(ConstantPoolNoSharing) {
  ConstantPoolBuilder builder(kReachBits, kReachBits);
  const int kRegularCount = (((kReach / (kDoubleSize + kPointerSize)) * 2) +
                             ((kPointerSize < kDoubleSize) ? 1 : 0));
  ConstantPoolEntry::Access access;

  CHECK(builder.IsEmpty());

  ConstantPoolEntry::Type type = kPtrType;
  int pos = 0;
  intptr_t ptrValue = 0;
  double dblValue = 0.0;
  bool sharing_ok = false;
  while (builder.NextAccess(type) == kRegAccess) {
    if (type == kPtrType) {
      access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
      type = kDblType;
    } else {
      access = builder.AddEntry(pos++, dblValue);
      dblValue += 0.5;
      type = kPtrType;
    }
    CHECK_EQ(access, kRegAccess);
  }
  CHECK(!builder.IsEmpty());
  CHECK_EQ(pos, kRegularCount);

  type = kPtrType;
  ptrValue = 0;
  dblValue = 0.0;
  sharing_ok = true;
  while (pos < kRegularCount * 2) {
    if (type == kPtrType) {
      access = builder.AddEntry(pos++, ptrValue++, sharing_ok);
      type = kDblType;
      CHECK_EQ(access, kOvflAccess);
    } else {
      access = builder.AddEntry(pos++, dblValue);
      dblValue += 0.5;
      type = kPtrType;
      CHECK_EQ(access, kRegAccess);
    }
  }

  access = builder.AddEntry(pos++, ptrValue, sharing_ok);
  CHECK_EQ(access, kOvflAccess);
  access = builder.AddEntry(pos, dblValue);
  CHECK_EQ(access, kOvflAccess);
}

#endif  // defined(V8_TARGET_ARCH_PPC)

}  // namespace internal
}  // namespace v8
