//===- subzero/src/IceTypes.h - Primitive ICE types -------------*- C++ -*-===//
//
//                        The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares a few properties of the primitive types allowed
/// in Subzero.  Every Subzero source file is expected to include
/// IceTypes.h.
///
//===----------------------------------------------------------------------===//

#ifndef SUBZERO_SRC_ICETYPES_H
#define SUBZERO_SRC_ICETYPES_H

#include "IceDefs.h"
#include "IceTypes.def"

namespace Ice {

enum Type {
#define X(tag, size, align, elts, elty, str) tag,
  ICETYPE_TABLE
#undef X
      IceType_NUM
};

enum TargetArch {
#define X(tag, str, is_elf64, e_machine, e_flags) tag,
  TARGETARCH_TABLE
#undef X
      TargetArch_NUM
};

const char *targetArchString(TargetArch Arch);

inline Ostream &operator<<(Ostream &Stream, TargetArch Arch) {
  return Stream << targetArchString(Arch);
}

/// The list of all target instruction sets. Individual targets will
/// map this to include only what is valid for the target.
enum TargetInstructionSet {
  // Represents baseline that can be assumed for a target (usually "Begin").
  BaseInstructionSet,
  X86InstructionSet_Begin,
  X86InstructionSet_SSE2 = X86InstructionSet_Begin,
  X86InstructionSet_SSE4_1,
  X86InstructionSet_End,
  ARM32InstructionSet_Begin,
  ARM32InstructionSet_Neon = ARM32InstructionSet_Begin,
  ARM32InstructionSet_HWDivArm,
  ARM32InstructionSet_End,
};

enum OptLevel { Opt_m1, Opt_0, Opt_1, Opt_2 };

size_t typeWidthInBytes(Type Ty);
size_t typeAlignInBytes(Type Ty);
size_t typeNumElements(Type Ty);
Type typeElementType(Type Ty);
const char *typeString(Type Ty);

inline Type getPointerType() { return IceType_i32; }

bool isVectorType(Type Ty);

bool isIntegerType(Type Ty); // scalar or vector
bool isScalarIntegerType(Type Ty);
bool isVectorIntegerType(Type Ty);
bool isIntegerArithmeticType(Type Ty);

bool isFloatingType(Type Ty); // scalar or vector
bool isScalarFloatingType(Type Ty);
bool isVectorFloatingType(Type Ty);

/// Returns true if the given type can be used in a load instruction.
bool isLoadStoreType(Type Ty);

/// Returns type generated by applying the compare instructions (icmp and fcmp)
/// to arguments of the given type. Returns IceType_void if compare is not
/// allowed.
Type getCompareResultType(Type Ty);

/// Returns the number of bits in a scalar integer type.
SizeT getScalarIntBitWidth(Type Ty);

/// Check if a type is byte sized (slight optimization over typeWidthInBytes).
inline bool isByteSizedType(Type Ty) {
  bool result = Ty == IceType_i8 || Ty == IceType_i1;
  assert(result == (1 == typeWidthInBytes(Ty)));
  return result;
}

/// Check if Ty is byte sized and specifically i8. Assert that it's not
/// byte sized due to being an i1.
inline bool isByteSizedArithType(Type Ty) {
  assert(Ty != IceType_i1);
  return Ty == IceType_i8;
}

/// Return true if Ty is i32. This asserts that Ty is either i32 or i64.
inline bool isInt32Asserting32Or64(Type Ty) {
  bool result = Ty == IceType_i32;
  assert(result || Ty == IceType_i64);
  return result;
}

/// Return true if Ty is f32. This asserts that Ty is either f32 or f64.
inline bool isFloat32Asserting32Or64(Type Ty) {
  bool result = Ty == IceType_f32;
  assert(result || Ty == IceType_f64);
  return result;
}

template <typename StreamType>
inline StreamType &operator<<(StreamType &Str, const Type &Ty) {
  Str << typeString(Ty);
  return Str;
}

/// Models a type signature for a function.
class FuncSigType {
  FuncSigType &operator=(const FuncSigType &Ty) = delete;

public:
  typedef std::vector<Type> ArgListType;

  /// Creates a function signature type with the given return type.
  /// Parameter types should be added using calls to appendArgType.
  FuncSigType() = default;
  FuncSigType(const FuncSigType &Ty) = default;

  void appendArgType(Type ArgType) { ArgList.push_back(ArgType); }

  Type getReturnType() const { return ReturnType; }
  void setReturnType(Type NewType) { ReturnType = NewType; }
  SizeT getNumArgs() const { return ArgList.size(); }
  Type getArgType(SizeT Index) const {
    assert(Index < ArgList.size());
    return ArgList[Index];
  }
  const ArgListType &getArgList() const { return ArgList; }
  void dump(Ostream &Stream) const;

private:
  /// The return type.
  Type ReturnType = IceType_void;
  /// The list of parameters.
  ArgListType ArgList;
};

inline Ostream &operator<<(Ostream &Stream, const FuncSigType &Sig) {
  Sig.dump(Stream);
  return Stream;
}

} // end of namespace Ice

#endif // SUBZERO_SRC_ICETYPES_H
