/* d-target.cc -- Target interface for the D front end.
   Copyright (C) 2013-2019 Free Software Foundation, Inc.

GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.

GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"

#include "dmd/aggregate.h"
#include "dmd/declaration.h"
#include "dmd/expression.h"
#include "dmd/mangle.h"
#include "dmd/mtype.h"
#include "dmd/tokens.h"
#include "dmd/target.h"

#include "tree.h"
#include "memmodel.h"
#include "fold-const.h"
#include "stor-layout.h"
#include "tm.h"
#include "tm_p.h"
#include "target.h"

#include "d-tree.h"
#include "d-target.h"

/* Implements the Target interface defined by the front end.
   Used for retrieving target-specific information.  */

/* Type size information used by frontend.  */
int Target::ptrsize;
int Target::c_longsize;
int Target::realsize;
int Target::realpad;
int Target::realalignsize;
bool Target::reverseCppOverloads;
bool Target::cppExceptions;
int Target::classinfosize;
unsigned long long Target::maxStaticDataSize;

/* Floating-point constants for for .max, .min, and other properties.  */
template <typename T> real_t Target::FPTypeProperties<T>::max;
template <typename T> real_t Target::FPTypeProperties<T>::min_normal;
template <typename T> real_t Target::FPTypeProperties<T>::nan;
template <typename T> real_t Target::FPTypeProperties<T>::snan;
template <typename T> real_t Target::FPTypeProperties<T>::infinity;
template <typename T> real_t Target::FPTypeProperties<T>::epsilon;
template <typename T> d_int64 Target::FPTypeProperties<T>::dig;
template <typename T> d_int64 Target::FPTypeProperties<T>::mant_dig;
template <typename T> d_int64 Target::FPTypeProperties<T>::max_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::min_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::max_10_exp;
template <typename T> d_int64 Target::FPTypeProperties<T>::min_10_exp;


/* Initialize the floating-point constants for TYPE.  */

template <typename T>
static void
define_float_constants (tree type)
{
  const double log10_2 = 0.30102999566398119521;
  char buf[128];

  /* Get back-end real mode format.  */
  const machine_mode mode = TYPE_MODE (type);
  const real_format *fmt = REAL_MODE_FORMAT (mode);

  /* The largest representable value that's not infinity.  */
  get_max_float (fmt, buf, sizeof (buf));
  real_from_string (&T::max.rv (), buf);

  /* The smallest representable normalized value that's not 0.  */
  snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - 1);
  real_from_string (&T::min_normal.rv (), buf);

  /* Floating-point NaN.  */
  real_nan (&T::nan.rv (), "", 1, mode);

  /* Signalling floating-point NaN.  */
  real_nan (&T::snan.rv (), "", 0, mode);

  /* Floating-point +Infinity if the target supports infinities.  */
  real_inf (&T::infinity.rv ());

  /* The smallest increment to the value 1.  */
  if (fmt->pnan < fmt->p)
    snprintf (buf, sizeof (buf), "0x1p%d", fmt->emin - fmt->p);
  else
    snprintf (buf, sizeof (buf), "0x1p%d", 1 - fmt->p);
  real_from_string (&T::epsilon.rv (), buf);

  /* The number of decimal digits of precision.  */
  T::dig = (fmt->p - 1) * log10_2;

  /* The number of bits in mantissa.  */
  T::mant_dig = fmt->p;

  /* The maximum int value such that 2** (value-1) is representable.  */
  T::max_exp = fmt->emax;

  /* The minimum int value such that 2** (value-1) is representable as a
     normalized value.  */
  T::min_exp = fmt->emin;

  /* The maximum int value such that 10**value is representable.  */
  T::max_10_exp = fmt->emax * log10_2;

  /* The minimum int value such that 10**value is representable as a
     normalized value.  */
  T::min_10_exp = (fmt->emin - 1) * log10_2;
}

/* Initialize all variables of the Target structure.  */

void
Target::_init (void)
{
  /* Map D frontend type and sizes to GCC back-end types.  */
  Target::ptrsize = (POINTER_SIZE / BITS_PER_UNIT);
  Target::realsize = int_size_in_bytes (long_double_type_node);
  Target::realpad = (Target::realsize -
		     (TYPE_PRECISION (long_double_type_node) / BITS_PER_UNIT));
  Target::realalignsize = TYPE_ALIGN_UNIT (long_double_type_node);

  /* Size of run-time TypeInfo object.  */
  Target::classinfosize = 19 * Target::ptrsize;

  /* Allow data sizes up to half of the address space.  */
  Target::maxStaticDataSize = tree_to_shwi (TYPE_MAX_VALUE (ptrdiff_type_node));

  /* Define what type to use for size_t, ptrdiff_t.  */
  if (POINTER_SIZE == 64)
    {
      global.params.isLP64 = true;
      Tsize_t = Tuns64;
      Tptrdiff_t = Tint64;
    }
  else
    {
      Tsize_t = Tuns32;
      Tptrdiff_t = Tint32;
    }

  Type::tsize_t = Type::basic[Tsize_t];
  Type::tptrdiff_t = Type::basic[Tptrdiff_t];
  Type::thash_t = Type::tsize_t;

  /* Set-up target C ABI.  */
  Target::c_longsize = int_size_in_bytes (long_integer_type_node);

  /* Set-up target C++ ABI.  */
  Target::reverseCppOverloads = false;
  Target::cppExceptions = true;

  /* Initialize all compile-time properties for floating-point types.
     Should ensure that our real_t type is able to represent real_value.  */
  gcc_assert (sizeof (real_t) >= sizeof (real_value));

  define_float_constants <Target::FloatProperties> (float_type_node);
  define_float_constants <Target::DoubleProperties> (double_type_node);
  define_float_constants <Target::RealProperties> (long_double_type_node);

  /* Commonly used floating-point constants.  */
  const machine_mode mode = TYPE_MODE (long_double_type_node);
  real_convert (&CTFloat::zero.rv (), mode, &dconst0);
  real_convert (&CTFloat::one.rv (), mode, &dconst1);
  real_convert (&CTFloat::minusone.rv (), mode, &dconstm1);
  real_convert (&CTFloat::half.rv (), mode, &dconsthalf);
}

/* Return GCC memory alignment size for type TYPE.  */

unsigned
Target::alignsize (Type *type)
{
  gcc_assert (type->isTypeBasic ());
  return min_align_of_type (build_ctype (type));
}

/* Return GCC field alignment size for type TYPE.  */

unsigned
Target::fieldalign (Type *type)
{
  /* Work out the correct alignment for the field decl.  */
  unsigned int align = type->alignsize () * BITS_PER_UNIT;

#ifdef BIGGEST_FIELD_ALIGNMENT
  align = MIN (align, (unsigned) BIGGEST_FIELD_ALIGNMENT);
#endif

#ifdef ADJUST_FIELD_ALIGN
  if (type->isTypeBasic ())
    align = ADJUST_FIELD_ALIGN (NULL_TREE, build_ctype (type), align);
#endif

  /* Also controlled by -fpack-struct=  */
  if (maximum_field_alignment)
    align = MIN (align, maximum_field_alignment);

  return align / BITS_PER_UNIT;
}

/* Return size of OS critical section.
   Can't use the sizeof () calls directly since cross compiling is supported
   and would end up using the host sizes rather than the target sizes.  */

unsigned
Target::critsecsize (void)
{
  return targetdm.d_critsec_size ();
}

/* Returns a Type for the va_list type of the target.  */

Type *
Target::va_listType (void)
{
  return Type::tvalist;
}

/* Checks whether the target supports a vector type with total size SZ
   (in bytes) and element type TYPE.  */

int
Target::isVectorTypeSupported (int sz, Type *type)
{
  /* Size must be greater than zero, and a power of two.  */
  if (sz <= 0 || sz & (sz - 1))
    return 2;

  /* __vector(void[]) is treated same as __vector(ubyte[])  */
  if (type == Type::tvoid)
    type = Type::tuns8;

  /* No support for non-trivial types.  */
  if (!type->isTypeBasic ())
    return 3;

  /* If there is no hardware support, check if we can safely emulate it.  */
  tree ctype = build_ctype (type);
  machine_mode mode = TYPE_MODE (ctype);

  if (!targetm.vector_mode_supported_p (mode)
      && !targetm.scalar_mode_supported_p (as_a <scalar_mode> (mode)))
    return 3;

  return 0;
}

/* Checks whether the target supports operation OP for vectors of type TYPE.
   For binary ops T2 is the type of the right-hand operand.
   Returns true if the operation is supported or type is not a vector.  */

bool
Target::isVectorOpSupported (Type *type, TOK op, Type *)
{
  if (type->ty != Tvector)
    return true;

  /* Don't support if type is non-scalar, such as __vector(void[]).  */
  if (!type->isscalar ())
    return false;

  /* Don't support if expression cannot be represented.  */
  switch (op)
    {
    case TOKpow:
    case TOKpowass:
      /* pow() is lowered as a function call.  */
      return false;

    case TOKmod:
    case TOKmodass:
      /* fmod() is lowered as a function call.  */
      if (type->isfloating ())
	return false;
      break;

    case TOKandand:
    case TOKoror:
      /* Logical operators must have a result type of bool.  */
      return false;

    case TOKue:
    case TOKlg:
    case TOKule:
    case TOKul:
    case TOKuge:
    case TOKug:
    case TOKle:
    case TOKlt:
    case TOKge:
    case TOKgt:
    case TOKleg:
    case TOKunord:
    case TOKequal:
    case TOKnotequal:
    case TOKidentity:
    case TOKnotidentity:
      /* Comparison operators must have a result type of bool.  */
      return false;

    default:
      break;
    }

  return true;
}

/* Return the symbol mangling of S for C++ linkage.  */

const char *
Target::toCppMangle (Dsymbol *s)
{
  return toCppMangleItanium (s);
}

/* Return the symbol mangling of CD for C++ linkage.  */

const char *
Target::cppTypeInfoMangle (ClassDeclaration *cd)
{
  return cppTypeInfoMangleItanium (cd);
}

/* For a vendor-specific type, return a string containing the C++ mangling.
   In all other cases, return NULL.  */

const char *
Target::cppTypeMangle (Type *type)
{
  if (type->isTypeBasic () || type->ty == Tvector || type->ty == Tstruct)
    {
      tree ctype = build_ctype (type);
      return targetm.mangle_type (ctype);
    }

  return NULL;
}

/* Return the type that will really be used for passing the given parameter
   ARG to an extern(C++) function.  */

Type *
Target::cppParameterType (Parameter *arg)
{
  Type *t = arg->type->merge2 ();
  if (arg->storageClass & (STCout | STCref))
    t = t->referenceTo ();
  else if (arg->storageClass & STClazy)
    {
      /* Mangle as delegate.  */
      Type *td = TypeFunction::create (NULL, t, 0, LINKd);
      td = TypeDelegate::create (td);
      t = t->merge2 ();
    }

  /* Could be a va_list, which we mangle as a pointer.  */
  if (t->ty == Tsarray && Type::tvalist->ty == Tsarray)
    {
      Type *tb = t->toBasetype ()->mutableOf ();
      if (tb == Type::tvalist)
	{
	  tb = t->nextOf ()->pointerTo ();
	  t = tb->castMod (t->mod);
	}
    }

  return t;
}

/* Checks whether TYPE is a vendor-specific fundamental type.  Stores the result
   in IS_FUNDAMENTAL and returns true if the parameter was set.  */

bool
Target::cppFundamentalType (const Type *, bool &)
{
  return false;
}

/* Return the default system linkage for the target.  */

LINK
Target::systemLinkage (void)
{
  return LINKc;
}
