// Copyright (c) 2020, 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.

#ifndef RUNTIME_VM_COMPILER_FFI_NATIVE_LOCATION_H_
#define RUNTIME_VM_COMPILER_FFI_NATIVE_LOCATION_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include "platform/assert.h"
#include "vm/compiler/ffi/native_type.h"
#include "vm/compiler/runtime_api.h"
#include "vm/constants.h"
#include "vm/growable_array.h"

#if !defined(FFI_UNIT_TESTS)
#include "vm/compiler/backend/locations.h"
#endif

namespace dart {

class BaseTextBuffer;

namespace compiler {

namespace ffi {

class NativeRegistersLocation;
class NativeFpuRegistersLocation;
class NativeStackLocation;
class MultipleNativeLocations;
class PointerToMemoryLocation;
class BothNativeLocations;

// NativeLocation objects are used in the FFI to describe argument and return
// value locations in all native ABIs that the FFI supports.
//
// NativeLocations contain two NativeTypes.
// * The payload type.
// * The container type, equal to or larger than the payload. If the
//   container is larger than the payload, the upper bits are defined by sign
//   or zero extension.
//   Container type is also used to denote an integer container when floating
//   point values are passed in integer registers.
//
// NativeLocations can express things that dart::Locations cannot express:
// * Multiple consecutive registers.
// * Multiple sizes of FPU registers (e.g. S, D, and Q on Arm32).
// * Arbitrary byte-size stack locations, at byte-size offsets.
//   (The Location class uses word-size offsets.)
// * Pointers to a memory location.
// * Split between multiple registers and stack.
//
// NativeLocations cannot express the following dart::Locations:
// * No PairLocations. Instead, NativeRegistersLocations can have multiple
//   registers, and NativeStackLocations can have arbitrary types.
// * No ConstantLocations.
//
// NativeLocation does not satisfy the invariant of Location: bitwise
// inequality cannot be used to determine disjointness.
class NativeLocation : public ZoneAllocated {
 public:
#if !defined(FFI_UNIT_TESTS)
  static bool LocationCanBeExpressed(Location loc, Representation rep);
  static NativeLocation& FromLocation(Zone* zone,
                                      Location loc,
                                      Representation rep);
  static NativeLocation& FromPairLocation(Zone* zone,
                                          Location loc,
                                          Representation rep,
                                          intptr_t index);
#endif

  // The type of the data at this location.
  const NativeType& payload_type() const { return payload_type_; }

  // The location container size, possibly larger than data.
  //
  // If the container is larger than the data, the remaining bits are _not_
  // undefined. For example a uint8 inside a uint32 has the upper 24 bits set
  // to 0. Effectively allowing the value to be read as uint8, uint16 and
  // uint32.
  const NativeType& container_type() const { return container_type_; }

  virtual NativeLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const = 0;

#if defined(TARGET_ARCH_ARM)
  const NativeLocation& WidenToQFpuRegister(Zone* zone) const;
#endif  // defined(TARGET_ARCH_ARM)

  NativeLocation& WidenTo4Bytes(Zone* zone) const;
  NativeLocation& WidenTo8Bytes(Zone* zone) const;

  virtual bool IsRegisters() const { return false; }
  virtual bool IsFpuRegisters() const { return false; }
  virtual bool IsStack() const { return false; }
  virtual bool IsMultiple() const { return false; }
  virtual bool IsPointerToMemory() const { return false; }
  virtual bool IsBoth() const { return false; }

  virtual bool IsExpressibleAsLocation() const { return false; }
#if !defined(FFI_UNIT_TESTS)
  virtual Location AsLocation() const {
    ASSERT(IsExpressibleAsLocation());
    UNREACHABLE_THIS();
  }
#endif

  virtual void PrintTo(BaseTextBuffer* f) const;
  const char* ToCString(Zone* zone) const;
#if !defined(FFI_UNIT_TESTS)
  const char* ToCString() const;
#endif

  const NativeRegistersLocation& AsRegisters() const;
  const NativeFpuRegistersLocation& AsFpuRegisters() const;
  const NativeStackLocation& AsStack() const;
  const MultipleNativeLocations& AsMultiple() const;
  const PointerToMemoryLocation& AsPointerToMemory() const;
  const BothNativeLocations& AsBoth() const;

  // Retrieve one part from this location when it is split into multiple parts.
  virtual NativeLocation& Split(Zone* zone,
                                intptr_t num_parts,
                                intptr_t index) const {
    UNREACHABLE_THIS();
  }

  // Return the top of the stack in bytes. Recurses over its constituents when
  // MultipleNativeLocations.
  virtual intptr_t StackTopInBytes() const { return 0; }

  // Equality of location, ignores the payload and container native types.
  virtual bool Equals(const NativeLocation& other) const { UNREACHABLE_THIS(); }

  virtual ~NativeLocation() {}

 protected:
  NativeLocation(const NativeType& payload_type,
                 const NativeType& container_type)
      : payload_type_(payload_type), container_type_(container_type) {}

 private:
  const NativeType& payload_type_;
  // The location container size, possibly larger than data.
  //
  // If the container is larger than the data, the remaining bits are _not_
  // undefined. For example a uint8 inside a uint32 has the upper 24 bits set
  // to 0. Effectively allowing the value to be read as uint8, uint16 and
  // uint32.
  const NativeType& container_type_;
};

class NativeRegistersLocation : public NativeLocation {
 public:
  NativeRegistersLocation(const NativeType& payload_type,
                          const NativeType& container_type,
                          ZoneGrowableArray<Register>* registers)
      : NativeLocation(payload_type, container_type), regs_(registers) {}
  NativeRegistersLocation(Zone* zone,
                          const NativeType& payload_type,
                          const NativeType& container_type,
                          Register reg)
      : NativeLocation(payload_type, container_type) {
    regs_ = new (zone) ZoneGrowableArray<Register>(zone, 1);
    regs_->Add(reg);
  }
  NativeRegistersLocation(Zone* zone,
                          const NativeType& payload_type,
                          const NativeType& container_type,
                          Register register1,
                          Register register2)
      : NativeLocation(payload_type, container_type) {
    regs_ = new (zone) ZoneGrowableArray<Register>(zone, 2);
    regs_->Add(register1);
    regs_->Add(register2);
  }
  virtual ~NativeRegistersLocation() {}

  virtual NativeRegistersLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    return *new (zone)
        NativeRegistersLocation(new_payload_type, new_container_type, regs_);
  }

  virtual bool IsRegisters() const { return true; }
  virtual bool IsExpressibleAsLocation() const {
    return num_regs() == 1 || num_regs() == 2;
  }
#if !defined(FFI_UNIT_TESTS)
  virtual Location AsLocation() const;
#endif
  intptr_t num_regs() const { return regs_->length(); }
  Register reg_at(intptr_t index) const { return regs_->At(index); }

  virtual NativeRegistersLocation& Split(Zone* zone,
                                         intptr_t num_parts,
                                         intptr_t index) const;

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual bool Equals(const NativeLocation& other) const;

 private:
  ZoneGrowableArray<Register>* regs_;

  DISALLOW_COPY_AND_ASSIGN(NativeRegistersLocation);
};

enum FpuRegisterKind {
  kQuadFpuReg,    // 16 bytes
  kDoubleFpuReg,  //  8 bytes, a double
  kSingleFpuReg   //  4 bytes, a float
};

intptr_t SizeFromFpuRegisterKind(FpuRegisterKind kind);
FpuRegisterKind FpuRegisterKindFromSize(intptr_t size_in_bytes);

class NativeFpuRegistersLocation : public NativeLocation {
 public:
  NativeFpuRegistersLocation(const NativeType& payload_type,
                             const NativeType& container_type,
                             FpuRegisterKind fpu_reg_kind,
                             intptr_t fpu_register)
      : NativeLocation(payload_type, container_type),
        fpu_reg_kind_(fpu_reg_kind),
        fpu_reg_(fpu_register) {}
  NativeFpuRegistersLocation(const NativeType& payload_type,
                             const NativeType& container_type,
                             FpuRegister fpu_register)
      : NativeLocation(payload_type, container_type),
        fpu_reg_kind_(kQuadFpuReg),
        fpu_reg_(fpu_register) {}
#if defined(TARGET_ARCH_ARM)
  NativeFpuRegistersLocation(const NativeType& payload_type,
                             const NativeType& container_type,
                             DRegister fpu_register)
      : NativeLocation(payload_type, container_type),
        fpu_reg_kind_(kDoubleFpuReg),
        fpu_reg_(fpu_register) {}
  NativeFpuRegistersLocation(const NativeType& payload_type,
                             const NativeType& container_type,
                             SRegister fpu_register)
      : NativeLocation(payload_type, container_type),
        fpu_reg_kind_(kSingleFpuReg),
        fpu_reg_(fpu_register) {}
#endif  // defined(TARGET_ARCH_ARM)
  virtual ~NativeFpuRegistersLocation() {}

  virtual NativeFpuRegistersLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    return *new (zone) NativeFpuRegistersLocation(
        new_payload_type, new_container_type, fpu_reg_kind_, fpu_reg_);
  }
  virtual bool IsFpuRegisters() const { return true; }
  virtual bool IsExpressibleAsLocation() const {
    return fpu_reg_kind_ == kQuadFpuReg;
  }
#if !defined(FFI_UNIT_TESTS)
  virtual Location AsLocation() const {
    ASSERT(IsExpressibleAsLocation());
    return Location::FpuRegisterLocation(fpu_reg());
  }
#endif
  FpuRegisterKind fpu_reg_kind() const { return fpu_reg_kind_; }
  FpuRegister fpu_reg() const {
    ASSERT(fpu_reg_kind_ == kQuadFpuReg);
    return static_cast<FpuRegister>(fpu_reg_);
  }
#if defined(TARGET_ARCH_ARM)
  DRegister fpu_d_reg() const {
    ASSERT(fpu_reg_kind_ == kDoubleFpuReg);
    return static_cast<DRegister>(fpu_reg_);
  }
  SRegister fpu_s_reg() const {
    ASSERT(fpu_reg_kind_ == kSingleFpuReg);
    return static_cast<SRegister>(fpu_reg_);
  }
  DRegister fpu_as_d_reg() const;
  SRegister fpu_as_s_reg() const;

  bool IsLowestBits() const;
#endif  // defined(TARGET_ARCH_ARM)

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual bool Equals(const NativeLocation& other) const;

 private:
  FpuRegisterKind fpu_reg_kind_;
  intptr_t fpu_reg_;
  DISALLOW_COPY_AND_ASSIGN(NativeFpuRegistersLocation);
};

class NativeStackLocation : public NativeLocation {
 public:
  NativeStackLocation(const NativeType& payload_type,
                      const NativeType& container_type,
                      Register base_register,
                      intptr_t offset_in_bytes)
      : NativeLocation(payload_type, container_type),
        base_register_(base_register),
        offset_in_bytes_(offset_in_bytes) {}
  virtual ~NativeStackLocation() {}

  virtual NativeStackLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    return *new (zone) NativeStackLocation(new_payload_type, new_container_type,
                                           base_register_, offset_in_bytes_);
  }

  virtual bool IsStack() const { return true; }
  virtual bool IsExpressibleAsLocation() const {
    const intptr_t size = payload_type().SizeInBytes();
    const intptr_t size_slots = size / compiler::target::kWordSize;
    return offset_in_bytes_ % compiler::target::kWordSize == 0 &&
           size % compiler::target::kWordSize == 0 &&
           (size_slots == 1 || size_slots == 2);
  }

#if !defined(FFI_UNIT_TESTS)
  virtual Location AsLocation() const;

  // ConstantInstr expects DoubleStackSlot for doubles, even on 64-bit systems.
  //
  // So this return a wrong-sized Location on purpose.
  Location AsDoubleStackSlotLocation() const {
    ASSERT(compiler::target::kWordSize == 8);
    return Location::DoubleStackSlot(offset_in_words(), base_register_);
  }
#endif

  virtual NativeStackLocation& Split(Zone* zone,
                                     intptr_t num_parts,
                                     intptr_t index) const;

  virtual intptr_t StackTopInBytes() const {
    return offset_in_bytes() + container_type().SizeInBytes();
  }

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual bool Equals(const NativeLocation& other) const;

  Register base_register() const { return base_register_; }
  intptr_t offset_in_bytes() const { return offset_in_bytes_; }

 private:
  intptr_t offset_in_words() const {
    ASSERT(offset_in_bytes_ % compiler::target::kWordSize == 0);
    return offset_in_bytes_ / compiler::target::kWordSize;
  }

  Register base_register_;
  intptr_t offset_in_bytes_;

  DISALLOW_COPY_AND_ASSIGN(NativeStackLocation);
};

// The location of a pointer pointing to a compound.
//
// For arguments a pointer to a copy of an object. The backing copy of the
// object typically resides on the stack.
//
// For return values a pointer to empty space that should hold the object. This
// space also typically resides on the stack.
class PointerToMemoryLocation : public NativeLocation {
 public:
  PointerToMemoryLocation(const NativeLocation& pointer_location,
                          const NativeCompoundType& object_pointed_to)
      : NativeLocation(object_pointed_to, object_pointed_to),
        pointer_location_(pointer_location),
        pointer_return_location_(pointer_location) {
    ASSERT(pointer_location.IsRegisters() || pointer_location.IsStack());
  }
  PointerToMemoryLocation(const NativeLocation& pointer_location,
                          const NativeLocation& pointer_return_location,
                          const NativeCompoundType& object_pointed_to)
      : NativeLocation(object_pointed_to, object_pointed_to),
        pointer_location_(pointer_location),
        pointer_return_location_(pointer_return_location) {
    ASSERT(pointer_location.IsRegisters() || pointer_location.IsStack());
  }

  virtual ~PointerToMemoryLocation() {}

  virtual bool IsPointerToMemory() const { return true; }

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual bool Equals(const NativeLocation& other) const;

  virtual NativeLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    UNREACHABLE_THIS();
  }

  virtual intptr_t StackTopInBytes() const {
    return pointer_location().StackTopInBytes();
  }

  // The location where the pointer is passed to the function.
  const NativeLocation& pointer_location() const { return pointer_location_; }

  // The location where the pointer is returned from the function.
  const NativeLocation& pointer_return_location() const {
    return pointer_return_location_;
  }

 private:
  const NativeLocation& pointer_location_;
  // The return location is only in use for return values, not for arguments.
  const NativeLocation& pointer_return_location_;

  DISALLOW_COPY_AND_ASSIGN(PointerToMemoryLocation);
};

using NativeLocations = ZoneGrowableArray<const NativeLocation*>;

// A struct broken up over multiple native locations.
class MultipleNativeLocations : public NativeLocation {
 public:
  MultipleNativeLocations(const NativeCompoundType& payload_type,
                          const NativeLocations& locations)
      : NativeLocation(payload_type, payload_type), locations_(locations) {}
  virtual ~MultipleNativeLocations() {}

  virtual bool IsMultiple() const { return true; }

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual NativeLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    UNREACHABLE_THIS();
  }

  virtual intptr_t StackTopInBytes() const;

  const NativeLocations& locations() const { return locations_; }

 private:
  const NativeLocations& locations_;
  DISALLOW_COPY_AND_ASSIGN(MultipleNativeLocations);
};

// The location of a value that is in two locations.
//
// Should only happen on win_x64 with variadic arguments.
class BothNativeLocations : public NativeLocation {
 public:
  BothNativeLocations(const NativeLocation& location0,
                      const NativeLocation& location1)
      : NativeLocation(location0.payload_type(), location0.container_type()),
        location0_(location0),
        location1_(location1) {}
  virtual ~BothNativeLocations() {}

  virtual bool IsBoth() const { return true; }

  virtual void PrintTo(BaseTextBuffer* f) const;

  virtual NativeLocation& WithOtherNativeType(
      Zone* zone,
      const NativeType& new_payload_type,
      const NativeType& new_container_type) const {
    UNREACHABLE_THIS();
  }

  virtual intptr_t StackTopInBytes() const {
    // Only used with registers.
    return 0;
  }

  const NativeLocation& location(intptr_t index) const {
    ASSERT(index == 0 || index == 1);
    if (index == 0) {
      return location0_;
    }
    return location1_;
  }

 private:
  const NativeLocation& location0_;
  const NativeLocation& location1_;
  DISALLOW_COPY_AND_ASSIGN(BothNativeLocations);
};

#if !defined(FFI_UNIT_TESTS)
// Return a memory operand for stack slot locations.
compiler::Address NativeLocationToStackSlotAddress(
    const NativeStackLocation& loc);
#endif

}  // namespace ffi

}  // namespace compiler

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_FFI_NATIVE_LOCATION_H_
