/* Subroutines for loongarch-specific option handling.
   Copyright (C) 2021-2022 Free Software Foundation, Inc.
   Contributed by Loongson Ltd.

This file is part of GCC.

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

#define IN_TARGET_CODE 1

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "obstack.h"
#include "diagnostic-core.h"
#include "loongarch-cpu.h"
#include "loongarch-opts.h"
#include "loongarch-str.h"

struct loongarch_target la_target;

/* ABI-related configuration.  */
#define ABI_COUNT (sizeof(abi_priority_list)/sizeof(struct loongarch_abi))
static const struct loongarch_abi
abi_priority_list[] = {
    {ABI_BASE_LP64D, ABI_EXT_BASE},
    {ABI_BASE_LP64F, ABI_EXT_BASE},
    {ABI_BASE_LP64S, ABI_EXT_BASE},
};

/* Initialize enabled_abi_types from TM_MULTILIB_LIST.  */
#ifdef LA_DISABLE_MULTILIB
#define MULTILIB_LIST_LEN 1
#else
#define MULTILIB_LIST_LEN (sizeof (tm_multilib_list) / sizeof (int) / 2)
static const int tm_multilib_list[] = { TM_MULTILIB_LIST };
#endif
static int enabled_abi_types[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES] = { 0 };

#define isa_required(ABI) (abi_minimal_isa[(ABI).base][(ABI).ext])
extern "C" const struct loongarch_isa
abi_minimal_isa[N_ABI_BASE_TYPES][N_ABI_EXT_TYPES];

static inline int
is_multilib_enabled (struct loongarch_abi abi)
{
  return enabled_abi_types[abi.base][abi.ext];
}

static void
init_enabled_abi_types ()
{
#ifdef LA_DISABLE_MULTILIB
  enabled_abi_types[DEFAULT_ABI_BASE][DEFAULT_ABI_EXT] = 1;
#else
  int abi_base, abi_ext;
  for (unsigned int i = 0; i < MULTILIB_LIST_LEN; i++)
    {
      abi_base = tm_multilib_list[i << 1];
      abi_ext = tm_multilib_list[(i << 1) + 1];
      enabled_abi_types[abi_base][abi_ext] = 1;
    }
#endif
}

/* Switch masks.  */
#undef M
#define M(NAME) OPTION_MASK_##NAME
const int loongarch_switch_mask[N_SWITCH_TYPES] = {
  /* SW_SOFT_FLOAT */    M(FORCE_SOFTF),
  /* SW_SINGLE_FLOAT */  M(FORCE_F32),
  /* SW_DOUBLE_FLOAT */  M(FORCE_F64),
};
#undef M

/* String processing.  */
static struct obstack msg_obstack;
#define APPEND_STRING(STR) obstack_grow (&msg_obstack, STR, strlen(STR));
#define APPEND1(CH) obstack_1grow(&msg_obstack, CH);

static const char* abi_str (struct loongarch_abi abi);
static const char* isa_str (const struct loongarch_isa *isa, char separator);
static const char* arch_str (const struct loongarch_target *target);
static const char* multilib_enabled_abi_list ();

/* Misc */
static struct loongarch_abi isa_default_abi (const struct loongarch_isa *isa);
static int isa_base_compat_p (const struct loongarch_isa *set1,
			      const struct loongarch_isa *set2);
static int isa_fpu_compat_p (const struct loongarch_isa *set1,
			     const struct loongarch_isa *set2);
static int abi_compat_p (const struct loongarch_isa *isa,
			 struct loongarch_abi abi);
static int abi_default_cpu_arch (struct loongarch_abi abi);

/* Checking configure-time defaults.  */
#ifndef DEFAULT_ABI_BASE
#error missing definition of DEFAULT_ABI_BASE in ${tm_defines}.
#endif

#ifndef DEFAULT_ABI_EXT
#error missing definition of DEFAULT_ABI_EXT in ${tm_defines}.
#endif

#ifndef DEFAULT_CPU_ARCH
#error missing definition of DEFAULT_CPU_ARCH in ${tm_defines}.
#endif

#ifndef DEFAULT_ISA_EXT_FPU
#error missing definition of DEFAULT_ISA_EXT_FPU in ${tm_defines}.
#endif

/* Handle combinations of -m machine option values
   (see loongarch.opt and loongarch-opts.h).  */
void
loongarch_config_target (struct loongarch_target *target,
			 HOST_WIDE_INT opt_switches,
			 int opt_arch, int opt_tune, int opt_fpu,
			 int opt_abi_base, int opt_abi_ext,
			 int opt_cmodel, int follow_multilib_list)
{
  struct loongarch_target t;

  if (!target)
    return;

  /* Initialization */
  init_enabled_abi_types ();
  obstack_init (&msg_obstack);

  struct {
    int arch, tune, fpu, abi_base, abi_ext, cmodel;
  } constrained = {
      M_OPT_ABSENT(opt_arch)     ? 0 : 1,
      M_OPT_ABSENT(opt_tune)     ? 0 : 1,
      M_OPT_ABSENT(opt_fpu)      ? 0 : 1,
      M_OPT_ABSENT(opt_abi_base) ? 0 : 1,
      M_OPT_ABSENT(opt_abi_ext)  ? 0 : 1,
      M_OPT_ABSENT(opt_cmodel)   ? 0 : 1,
  };

#define on(NAME) ((loongarch_switch_mask[(SW_##NAME)] & opt_switches) \
		  && (on_switch = (SW_##NAME), 1))
  int on_switch;

  /* 1.  Target ABI */
  t.abi.base = constrained.abi_base ? opt_abi_base : DEFAULT_ABI_BASE;

  t.abi.ext = constrained.abi_ext ? opt_abi_ext : DEFAULT_ABI_EXT;

  /* Extra switch handling.  */
  if (on (SOFT_FLOAT) || on (SINGLE_FLOAT) || on (DOUBLE_FLOAT))
    {
      switch (on_switch)
	{
	  case SW_SOFT_FLOAT:
	    opt_fpu = ISA_EXT_NOFPU;
	    break;

	  case SW_SINGLE_FLOAT:
	    opt_fpu = ISA_EXT_FPU32;
	    break;

	  case SW_DOUBLE_FLOAT:
	    opt_fpu = ISA_EXT_FPU64;
	    break;

	  default:
	    gcc_unreachable();
	}
      constrained.fpu = 1;

      /* The target ISA is not ready yet, but (isa_required (t.abi)
	 + forced fpu) is enough for computing the forced base ABI.  */
      struct loongarch_isa default_isa = isa_required (t.abi);
      struct loongarch_isa force_isa = default_isa;
      struct loongarch_abi force_abi = t.abi;
      force_isa.fpu = opt_fpu;
      force_abi.base = isa_default_abi (&force_isa).base;

      if (constrained.abi_base && (t.abi.base != force_abi.base))
	inform (UNKNOWN_LOCATION,
		"%<-m%s%> overrides %<-m%s=%s%>, adjusting ABI to %qs",
		loongarch_switch_strings[on_switch],
		OPTSTR_ABI_BASE, loongarch_abi_base_strings[t.abi.base],
		abi_str (force_abi));

      t.abi.base = force_abi.base;
    }

#ifdef LA_DISABLE_MULTILIB
  if (follow_multilib_list)
    if (t.abi.base != DEFAULT_ABI_BASE || t.abi.ext != DEFAULT_ABI_EXT)
      {
	static const struct loongarch_abi default_abi
	  = {DEFAULT_ABI_BASE, DEFAULT_ABI_EXT};

	warning (0, "ABI changed (%qs to %qs) while multilib is disabled",
		 abi_str (default_abi), abi_str (t.abi));
      }
#endif

  /* 2.  Target CPU */
  t.cpu_arch = constrained.arch ? opt_arch : DEFAULT_CPU_ARCH;

  t.cpu_tune = constrained.tune ? opt_tune
    : (constrained.arch ? DEFAULT_CPU_ARCH : DEFAULT_CPU_TUNE);

#ifdef __loongarch__
  /* For native compilers, gather local CPU information
     and fill the "CPU_NATIVE" index of arrays defined in
     loongarch-cpu.c.  */

  t.cpu_native = fill_native_cpu_config (t.cpu_arch == CPU_NATIVE,
					 t.cpu_tune == CPU_NATIVE);

#else
  if (t.cpu_arch == CPU_NATIVE)
    fatal_error (UNKNOWN_LOCATION,
		 "%qs does not work on a cross compiler",
		 "-m" OPTSTR_ARCH "=" STR_CPU_NATIVE);

  else if (t.cpu_tune == CPU_NATIVE)
    fatal_error (UNKNOWN_LOCATION,
		 "%qs does not work on a cross compiler",
		 "-m" OPTSTR_TUNE "=" STR_CPU_NATIVE);
#endif

  /* 3.  Target ISA */
config_target_isa:

  /* Get default ISA from "-march" or its default value.  */
  t.isa = loongarch_cpu_default_isa[LARCH_ACTUAL_ARCH];

  /* Apply incremental changes.  */
  /* "-march=native" overrides the default FPU type.  */
  t.isa.fpu = constrained.fpu ? opt_fpu :
    ((t.cpu_arch == CPU_NATIVE && constrained.arch) ?
     t.isa.fpu : DEFAULT_ISA_EXT_FPU);


  /* 4.  ABI-ISA compatibility */
  /* Note:
     - There IS a unique default -march value for each ABI type
       (config.gcc: triplet -> abi -> default arch).

     - If the base ABI is incompatible with the default arch,
       try using the default -march it implies (and mark it
       as "constrained" this time), then re-apply step 3.  */

  struct loongarch_abi abi_tmp;
  const struct loongarch_isa* isa_min;

  abi_tmp = t.abi;
  isa_min = &isa_required (abi_tmp);

  if (isa_base_compat_p (&t.isa, isa_min)); /* OK.  */
  else if (!constrained.arch)
    {
      /* Base architecture can only be implied by -march,
	 so we adjust that first if it is not constrained.  */
      int fallback_arch = abi_default_cpu_arch (t.abi);

      if (t.cpu_arch == CPU_NATIVE)
	warning (0, "your native CPU architecture (%qs) "
		 "does not support %qs ABI, falling back to %<-m%s=%s%>",
		 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
		 loongarch_cpu_strings[fallback_arch]);
      else
	warning (0, "default CPU architecture (%qs) "
		 "does not support %qs ABI, falling back to %<-m%s=%s%>",
		 arch_str (&t), abi_str (t.abi), OPTSTR_ARCH,
		 loongarch_cpu_strings[fallback_arch]);

      t.cpu_arch = fallback_arch;
      constrained.arch = 1;
      goto config_target_isa;
    }
  else if (!constrained.abi_base)
    {
      /* If -march is given while -mabi is not,
	 try selecting another base ABI type.  */
      abi_tmp.base = isa_default_abi (&t.isa).base;
    }
  else
    goto fatal;

  if (isa_fpu_compat_p (&t.isa, isa_min)); /* OK.  */
  else if (!constrained.fpu)
    t.isa.fpu = isa_min->fpu;
  else if (!constrained.abi_base)
    /* If -march is compatible with the default ABI
       while -mfpu is not.  */
    abi_tmp.base = isa_default_abi (&t.isa).base;
  else
    goto fatal;

  if (0)
fatal:
    fatal_error (UNKNOWN_LOCATION,
		 "unable to implement ABI %qs with instruction set %qs",
		 abi_str (t.abi), isa_str (&t.isa, '/'));


  /* Using the fallback ABI.  */
  if (abi_tmp.base != t.abi.base || abi_tmp.ext != t.abi.ext)
    {
      /* This flag is only set in the GCC driver.  */
      if (follow_multilib_list)
	{

	  /* Continue falling back until we find a feasible ABI type
	     enabled by TM_MULTILIB_LIST.  */
	  if (!is_multilib_enabled (abi_tmp))
	    {
	      for (unsigned int i = 0; i < ABI_COUNT; i++)
		{
		  if (is_multilib_enabled (abi_priority_list[i])
		      && abi_compat_p (&t.isa, abi_priority_list[i]))
		    {
		      abi_tmp = abi_priority_list[i];

		      warning (0, "ABI %qs cannot be implemented due to "
			       "limited instruction set %qs, "
			       "falling back to %qs", abi_str (t.abi),
			       isa_str (&t.isa, '/'), abi_str (abi_tmp));

		      goto fallback;
		    }
		}

	      /* Otherwise, keep using abi_tmp with a warning.  */
#ifdef LA_DISABLE_MULTILIB
	      warning (0, "instruction set %qs cannot implement "
		       "default ABI %qs, falling back to %qs",
		       isa_str (&t.isa, '/'), abi_str (t.abi),
		       abi_str (abi_tmp));
#else
	      warning (0, "no multilib-enabled ABI (%qs) can be implemented "
		       "with instruction set %qs, falling back to %qs",
		       multilib_enabled_abi_list (),
		       isa_str (&t.isa, '/'), abi_str (abi_tmp));
#endif
	    }
	}

fallback:
      t.abi = abi_tmp;
    }
  else if (follow_multilib_list)
    {
      if (!is_multilib_enabled (t.abi))
	{
	  inform (UNKNOWN_LOCATION,
		  "ABI %qs is not enabled at configure-time, "
		  "the linker might report an error", abi_str (t.abi));

	  inform (UNKNOWN_LOCATION, "ABI with startfiles: %s",
		  multilib_enabled_abi_list ());
	}
    }


  /* 5.  Target code model */
  t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL;

  switch (t.cmodel)
    {
    case CMODEL_TINY:
    case CMODEL_TINY_STATIC:
    case CMODEL_LARGE:
      warning (0, "%qs is not supported, now cmodel is set to %qs",
	       loongarch_cmodel_strings[t.cmodel], "normal");
      t.cmodel = CMODEL_NORMAL;
      break;

    case CMODEL_NORMAL:
    case CMODEL_MEDIUM:
    case CMODEL_EXTREME:
      break;

    default:
      gcc_unreachable ();
    }

  /* Cleanup and return.  */
  obstack_free (&msg_obstack, NULL);
  *target = t;
}

/* Returns the default ABI for the given instruction set.  */
static inline struct loongarch_abi
isa_default_abi (const struct loongarch_isa *isa)
{
  struct loongarch_abi abi;

  switch (isa->fpu)
    {
      case ISA_EXT_FPU64:
	if (isa->base == ISA_BASE_LA64V100)
	  abi.base = ABI_BASE_LP64D;
	break;

      case ISA_EXT_FPU32:
	if (isa->base == ISA_BASE_LA64V100)
	  abi.base = ABI_BASE_LP64F;
	break;

      case ISA_EXT_NOFPU:
	if (isa->base == ISA_BASE_LA64V100)
	  abi.base = ABI_BASE_LP64S;
	break;

      default:
	gcc_unreachable ();
    }

  abi.ext = ABI_EXT_BASE;
  return abi;
}

/* Check if set2 is a subset of set1.  */
static inline int
isa_base_compat_p (const struct loongarch_isa *set1,
		   const struct loongarch_isa *set2)
{
  switch (set2->base)
    {
      case ISA_BASE_LA64V100:
	return (set1->base == ISA_BASE_LA64V100);

      default:
	gcc_unreachable ();
    }
}

static inline int
isa_fpu_compat_p (const struct loongarch_isa *set1,
		  const struct loongarch_isa *set2)
{
  switch (set2->fpu)
    {
      case ISA_EXT_FPU64:
	return set1->fpu == ISA_EXT_FPU64;

      case ISA_EXT_FPU32:
	return set1->fpu == ISA_EXT_FPU32 || set1->fpu == ISA_EXT_FPU64;

      case ISA_EXT_NOFPU:
	return 1;

      default:
	gcc_unreachable ();
    }

}

static inline int
abi_compat_p (const struct loongarch_isa *isa, struct loongarch_abi abi)
{
  int compatible = 1;
  const struct loongarch_isa *isa2 = &isa_required (abi);

  /* Append conditionals for new ISA components below.  */
  compatible = compatible && isa_base_compat_p (isa, isa2);
  compatible = compatible && isa_fpu_compat_p (isa, isa2);
  return compatible;
}

/* The behavior of this function should be consistent
   with config.gcc.  */
static inline int
abi_default_cpu_arch (struct loongarch_abi abi)
{
  switch (abi.base)
    {
      case ABI_BASE_LP64D:
      case ABI_BASE_LP64F:
      case ABI_BASE_LP64S:
	if (abi.ext == ABI_EXT_BASE)
	  return CPU_LOONGARCH64;
    }
  gcc_unreachable ();
}

static const char*
abi_str (struct loongarch_abi abi)
{
  /* "/base" can be omitted.  */
  if (abi.ext == ABI_EXT_BASE)
    return (const char*)
      obstack_copy0 (&msg_obstack, loongarch_abi_base_strings[abi.base],
		     strlen (loongarch_abi_base_strings[abi.base]));
  else
    {
      APPEND_STRING (loongarch_abi_base_strings[abi.base])
      APPEND1 ('/')
      APPEND_STRING (loongarch_abi_ext_strings[abi.ext])
      APPEND1 ('\0')

      return XOBFINISH (&msg_obstack, const char *);
    }
}

static const char*
isa_str (const struct loongarch_isa *isa, char separator)
{
  APPEND_STRING (loongarch_isa_base_strings[isa->base])
  APPEND1 (separator)

  if (isa->fpu == ISA_EXT_NOFPU)
    {
      APPEND_STRING ("no" OPTSTR_ISA_EXT_FPU)
    }
  else
    {
      APPEND_STRING (OPTSTR_ISA_EXT_FPU)
      APPEND_STRING (loongarch_isa_ext_strings[isa->fpu])
    }
  APPEND1 ('\0')

  /* Add more here.  */

  return XOBFINISH (&msg_obstack, const char *);
}

static const char*
arch_str (const struct loongarch_target *target)
{
  if (target->cpu_arch == CPU_NATIVE)
    {
      if (target->cpu_native == CPU_NATIVE)
	{
	  /* Describe a native CPU with unknown PRID.  */
	  const char* isa_string = isa_str (&target->isa, ',');
	  APPEND_STRING ("PRID: 0x")
	  APPEND_STRING (get_native_prid_str ())
	  APPEND_STRING (", ISA features: ")
	  APPEND_STRING (isa_string)
	  APPEND1 ('\0')
	}
      else
	APPEND_STRING (loongarch_cpu_strings[target->cpu_native]);
    }
  else
    APPEND_STRING (loongarch_cpu_strings[target->cpu_arch]);

  APPEND1 ('\0')
  return XOBFINISH (&msg_obstack, const char *);
}

static const char*
multilib_enabled_abi_list ()
{
  int enabled_abi_idx[MULTILIB_LIST_LEN] = { 0 };
  const char* enabled_abi_str[MULTILIB_LIST_LEN] = { NULL };
  unsigned int j = 0;

  for (unsigned int i = 0; i < ABI_COUNT && j < MULTILIB_LIST_LEN; i++)
    {
      if (enabled_abi_types[abi_priority_list[i].base]
	  [abi_priority_list[i].ext])
	{
	  enabled_abi_idx[j++] = i;
	}
    }

  for (unsigned int k = 0; k < j; k++)
    {
      enabled_abi_str[k] = abi_str (abi_priority_list[enabled_abi_idx[k]]);
    }

  for (unsigned int k = 0; k < j - 1; k++)
    {
      APPEND_STRING (enabled_abi_str[k])
      APPEND1 (',')
      APPEND1 (' ')
    }
  APPEND_STRING (enabled_abi_str[j - 1])
  APPEND1 ('\0')

  return XOBFINISH (&msg_obstack, const char *);
}
