// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/compiler/backend/locations_helpers.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
#include "vm/unit_test.h"

namespace dart {

#define Reg(index) (static_cast<Register>(index))
#define Fpu(index) (static_cast<FpuRegister>(index))

#define ReqReg Location::RequiresRegister()
#define ReqFpu Location::RequiresFpuRegister()
#define RegLoc(index) Location::RegisterLocation(Reg(index))
#define FpuLoc(index) Location::FpuRegisterLocation(Fpu(index))

typedef ZoneGrowableArray<Location> LocationArray;

static LocationArray* MakeLocationArray() {
  LocationArray* arr = new LocationArray();
  return arr;
}

static LocationArray* MakeLocationArray(Location loc0) {
  LocationArray* arr = new LocationArray();
  arr->Add(loc0);
  return arr;
}

static LocationArray* MakeLocationArray(Location loc0, Location loc1) {
  LocationArray* arr = new LocationArray();
  arr->Add(loc0);
  arr->Add(loc1);
  return arr;
}

static void ValidateSummary(LocationSummary* locs,
                            Location expected_output,
                            const LocationArray* expected_inputs,
                            const LocationArray* expected_temps) {
  EXPECT(locs->out(0).Equals(expected_output));
  EXPECT_EQ(expected_inputs->length(), locs->input_count());
  for (intptr_t i = 0; i < expected_inputs->length(); i++) {
    EXPECT(locs->in(i).Equals(expected_inputs->At(i)));
  }
  EXPECT_EQ(expected_temps->length(), locs->temp_count());
  for (intptr_t i = 0; i < expected_temps->length(); i++) {
    EXPECT(locs->temp(i).Equals(expected_temps->At(i)));
  }
}

static void FillSummary(LocationSummary* locs,
                        Location expected_output,
                        const LocationArray* expected_inputs,
                        const LocationArray* expected_temps) {
  locs->set_out(0, expected_output);
  for (intptr_t i = 0; i < expected_inputs->length(); i++) {
    locs->set_in(i, expected_inputs->At(i));
  }
  for (intptr_t i = 0; i < expected_temps->length(); i++) {
    locs->set_temp(i, expected_temps->At(i));
  }
}

class MockInstruction : public ZoneAllocated {
 public:
  virtual ~MockInstruction() {}

  LocationSummary* locs() {
    if (locs_ == NULL) {
      locs_ = MakeLocationSummary(Thread::Current()->zone(), false);
    }
    return locs_;
  }

  virtual LocationSummary* MakeLocationSummary(Zone* zone, bool opt) const = 0;
  virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0;

 private:
  LocationSummary* locs_;
};

#define INSTRUCTION_TEST(Name, Arity, Signature, ExpectedOut, ExpectedIn,      \
                         ExpectedTemp, AllocatedOut, AllocatedIn,              \
                         AllocatedTemp)                                        \
  class Name##Instr : public MockInstruction {                                 \
   public:                                                                     \
    LocationSummary* MakeLocationSummary(Zone* zone, bool opt) const;          \
    void EmitNativeCode(FlowGraphCompiler* compiler);                          \
    virtual intptr_t InputCount() const { return Arity; }                      \
  };                                                                           \
  TEST_CASE(LocationsHelpers_##Name) {                                         \
    const Location expected_out = ExpectedOut;                                 \
    const LocationArray* expected_inputs = MakeLocationArray ExpectedIn;       \
    const LocationArray* expected_temps = MakeLocationArray ExpectedTemp;      \
                                                                               \
    const Location allocated_out = AllocatedOut;                               \
    const LocationArray* allocated_inputs = MakeLocationArray AllocatedIn;     \
    const LocationArray* allocated_temps = MakeLocationArray AllocatedTemp;    \
                                                                               \
    Name##Instr* instr = new Name##Instr();                                    \
    LocationSummary* locs = instr->locs();                                     \
                                                                               \
    ValidateSummary(locs, expected_out, expected_inputs, expected_temps);      \
    FillSummary(locs, allocated_out, allocated_inputs, allocated_temps);       \
                                                                               \
    instr->EmitNativeCode(NULL);                                               \
  }                                                                            \
  DEFINE_BACKEND(Name, Signature)

// Reg -> Reg
INSTRUCTION_TEST(Unary,
                 1,
                 (Register out, Register in),
                 ReqReg,
                 (ReqReg),
                 (),
                 RegLoc(0),
                 (RegLoc(1)),
                 ()) {
  EXPECT_EQ(Reg(0), out);
  EXPECT_EQ(Reg(1), in);
}

// (Reg, Fpu) -> Reg
INSTRUCTION_TEST(Binary1,
                 2,
                 (Register out, Register in0, FpuRegister in1),
                 ReqReg,
                 (ReqReg, Location::RequiresFpuRegister()),
                 (),
                 RegLoc(0),
                 (RegLoc(1), FpuLoc(2)),
                 ()) {
  EXPECT_EQ(Reg(0), out);
  EXPECT_EQ(Reg(1), in0);
  EXPECT_EQ(Fpu(2), in1);
}

// (Fpu, Reg) -> Reg
INSTRUCTION_TEST(Binary2,
                 2,
                 (Register out, FpuRegister in0, Register in1),
                 ReqReg,
                 (ReqFpu, ReqReg),
                 (),
                 RegLoc(0),
                 (FpuLoc(1), RegLoc(2)),
                 ()) {
  EXPECT_EQ(Reg(0), out);
  EXPECT_EQ(Fpu(1), in0);
  EXPECT_EQ(Reg(2), in1);
}

// -> Reg(3)
INSTRUCTION_TEST(FixedOutput,
                 0,
                 (Fixed<Register, Reg(3)> out),
                 RegLoc(3),
                 (),
                 (),
                 RegLoc(3),
                 (),
                 ()) {
  EXPECT_EQ(Reg(3), Reg(out));
}

// Fpu(3) -> Fpu
INSTRUCTION_TEST(FixedInput,
                 1,
                 (FpuRegister out, Fixed<FpuRegister, Fpu(3)> in),
                 ReqFpu,
                 (FpuLoc(3)),
                 (),
                 FpuLoc(0),
                 (FpuLoc(3)),
                 ()) {
  EXPECT_EQ(Fpu(0), out);
  EXPECT_EQ(Fpu(3), Fpu(in));
}

// Reg -> SameAsFirstInput
INSTRUCTION_TEST(SameAsFirstInput,
                 2,
                 (SameAsFirstInput, Register in0, Register in1),
                 Location::SameAsFirstInput(),
                 (ReqReg, ReqReg),
                 (),
                 RegLoc(0),
                 (RegLoc(0), RegLoc(1)),
                 ()) {
  EXPECT_EQ(Reg(0), in0);
  EXPECT_EQ(Reg(1), in1);
}

// {Temps: Fpu, Reg} (Reg, Fpu) -> Reg
INSTRUCTION_TEST(Temps,
                 2,
                 (Register out,
                  Register in0,
                  FpuRegister in1,
                  Temp<FpuRegister> temp0,
                  Temp<Register> temp1),
                 ReqReg,
                 (ReqReg, ReqFpu),
                 (ReqFpu, ReqReg),
                 RegLoc(0),
                 (RegLoc(1), FpuLoc(2)),
                 (FpuLoc(3), RegLoc(4))) {
  EXPECT_EQ(Reg(0), out);
  EXPECT_EQ(Reg(1), in0);
  EXPECT_EQ(Fpu(2), in1);
  EXPECT_EQ(Fpu(3), Fpu(temp0));
  EXPECT_EQ(Reg(4), Reg(temp1));
}

// {Temps: Fpu(3)} -> Fpu
INSTRUCTION_TEST(FixedTemp,
                 0,
                 (FpuRegister out, Temp<Fixed<FpuRegister, Fpu(3)> > temp),
                 ReqFpu,
                 (),
                 (FpuLoc(3)),
                 FpuLoc(4),
                 (),
                 (FpuLoc(3))) {
  EXPECT_EQ(Fpu(4), out);
  EXPECT_EQ(Fpu(3), Fpu(temp));
}

}  // namespace dart
