/* Target-specific code for C family languages.
   Copyright (C) 2015-2021 Free Software Foundation, Inc.

   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 "input.h"
#include "memmodel.h"
#include "tm_p.h"
#include "flags.h"
#include "c-family/c-common.h"
#include "cpplib.h"
#include "c-family/c-pragma.h"
#include "langhooks.h"
#include "target.h"


#define builtin_define(TXT) cpp_define (pfile, TXT)
#define builtin_assert(TXT) cpp_assert (pfile, TXT)


static void
aarch64_def_or_undef (bool def_p, const char *macro, cpp_reader *pfile)
{
  if (def_p)
    cpp_define (pfile, macro);
  else
    cpp_undef (pfile, macro);
}

/* Define the macros that we always expect to have on AArch64.  */

static void
aarch64_define_unconditional_macros (cpp_reader *pfile)
{
  builtin_define ("__aarch64__");
  builtin_define ("__ARM_64BIT_STATE");

  builtin_define ("__ARM_ARCH_ISA_A64");
  builtin_define_with_int_value ("__ARM_ALIGN_MAX_PWR", 28);
  builtin_define_with_int_value ("__ARM_ALIGN_MAX_STACK_PWR", 16);

  /* __ARM_ARCH_8A is not mandated by ACLE but we define it unconditionally
     as interoperability with the same arm macro.  */
  builtin_define ("__ARM_ARCH_8A");

  builtin_define_with_int_value ("__ARM_ARCH_PROFILE",
      AARCH64_ISA_V8_R ? 'R' : 'A');
  builtin_define ("__ARM_FEATURE_CLZ");
  builtin_define ("__ARM_FEATURE_IDIV");
  builtin_define ("__ARM_FEATURE_UNALIGNED");
  builtin_define ("__ARM_PCS_AAPCS64");
  builtin_define_with_int_value ("__ARM_SIZEOF_WCHAR_T", WCHAR_TYPE_SIZE / 8);

  builtin_define ("__GCC_ASM_FLAG_OUTPUTS__");
}

/* Undefine/redefine macros that depend on the current backend state and may
   need to change when a target pragma modifies the backend state.  */

static void
aarch64_update_cpp_builtins (cpp_reader *pfile)
{
  aarch64_def_or_undef (flag_unsafe_math_optimizations, "__ARM_FP_FAST", pfile);

  builtin_define_with_int_value ("__ARM_ARCH", aarch64_architecture_version);

  builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM",
				 flag_short_enums ? 1 : 4);
  aarch64_def_or_undef (TARGET_BIG_END, "__AARCH64EB__", pfile);
  aarch64_def_or_undef (TARGET_BIG_END, "__ARM_BIG_ENDIAN", pfile);
  aarch64_def_or_undef (!TARGET_BIG_END, "__AARCH64EL__", pfile);

  aarch64_def_or_undef (TARGET_FLOAT, "__ARM_FEATURE_FMA", pfile);

  if (TARGET_FLOAT || TARGET_SIMD)
    {
      builtin_define_with_int_value ("__ARM_FP", 0x0E);
      builtin_define ("__ARM_FP16_FORMAT_IEEE");
      builtin_define ("__ARM_FP16_ARGS");
    }
  else
    cpp_undef (pfile, "__ARM_FP");

  aarch64_def_or_undef (TARGET_FP_F16INST,
			"__ARM_FEATURE_FP16_SCALAR_ARITHMETIC", pfile);
  aarch64_def_or_undef (TARGET_SIMD_F16INST,
			"__ARM_FEATURE_FP16_VECTOR_ARITHMETIC", pfile);

  aarch64_def_or_undef (TARGET_SIMD, "__ARM_FEATURE_NUMERIC_MAXMIN", pfile);
  aarch64_def_or_undef (TARGET_SIMD, "__ARM_NEON", pfile);


  aarch64_def_or_undef (TARGET_CRC32, "__ARM_FEATURE_CRC32", pfile);
  aarch64_def_or_undef (TARGET_DOTPROD, "__ARM_FEATURE_DOTPROD", pfile);
  aarch64_def_or_undef (TARGET_COMPLEX, "__ARM_FEATURE_COMPLEX", pfile);
  aarch64_def_or_undef (TARGET_JSCVT, "__ARM_FEATURE_JCVT", pfile);

  cpp_undef (pfile, "__AARCH64_CMODEL_TINY__");
  cpp_undef (pfile, "__AARCH64_CMODEL_SMALL__");
  cpp_undef (pfile, "__AARCH64_CMODEL_LARGE__");

  switch (aarch64_cmodel)
    {
      case AARCH64_CMODEL_TINY:
      case AARCH64_CMODEL_TINY_PIC:
	builtin_define ("__AARCH64_CMODEL_TINY__");
	break;
      case AARCH64_CMODEL_SMALL:
      case AARCH64_CMODEL_SMALL_PIC:
	builtin_define ("__AARCH64_CMODEL_SMALL__");
	break;
      case AARCH64_CMODEL_LARGE:
	builtin_define ("__AARCH64_CMODEL_LARGE__");
	break;
      default:
	break;
    }

  aarch64_def_or_undef (TARGET_ILP32, "_ILP32", pfile);
  aarch64_def_or_undef (TARGET_ILP32, "__ILP32__", pfile);

  aarch64_def_or_undef (TARGET_CRYPTO, "__ARM_FEATURE_CRYPTO", pfile);
  aarch64_def_or_undef (TARGET_SIMD_RDMA, "__ARM_FEATURE_QRDMX", pfile);
  aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE", pfile);
  cpp_undef (pfile, "__ARM_FEATURE_SVE_BITS");
  if (TARGET_SVE)
    {
      int bits;
      if (!BITS_PER_SVE_VECTOR.is_constant (&bits))
	bits = 0;
      builtin_define_with_int_value ("__ARM_FEATURE_SVE_BITS", bits);
    }
  aarch64_def_or_undef (TARGET_SVE, "__ARM_FEATURE_SVE_VECTOR_OPERATORS",
			pfile);
  aarch64_def_or_undef (TARGET_SVE_I8MM,
			"__ARM_FEATURE_SVE_MATMUL_INT8", pfile);
  aarch64_def_or_undef (TARGET_SVE_F32MM,
			"__ARM_FEATURE_SVE_MATMUL_FP32", pfile);
  aarch64_def_or_undef (TARGET_SVE_F64MM,
			"__ARM_FEATURE_SVE_MATMUL_FP64", pfile);
  aarch64_def_or_undef (TARGET_SVE2, "__ARM_FEATURE_SVE2", pfile);
  aarch64_def_or_undef (TARGET_SVE2_AES, "__ARM_FEATURE_SVE2_AES", pfile);
  aarch64_def_or_undef (TARGET_SVE2_BITPERM,
			"__ARM_FEATURE_SVE2_BITPERM", pfile);
  aarch64_def_or_undef (TARGET_SVE2_SHA3, "__ARM_FEATURE_SVE2_SHA3", pfile);
  aarch64_def_or_undef (TARGET_SVE2_SM4, "__ARM_FEATURE_SVE2_SM4", pfile);

  aarch64_def_or_undef (TARGET_LSE, "__ARM_FEATURE_ATOMICS", pfile);
  aarch64_def_or_undef (TARGET_AES, "__ARM_FEATURE_AES", pfile);
  aarch64_def_or_undef (TARGET_SHA2, "__ARM_FEATURE_SHA2", pfile);
  aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA3", pfile);
  aarch64_def_or_undef (TARGET_SHA3, "__ARM_FEATURE_SHA512", pfile);
  aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM3", pfile);
  aarch64_def_or_undef (TARGET_SM4, "__ARM_FEATURE_SM4", pfile);
  aarch64_def_or_undef (TARGET_F16FML, "__ARM_FEATURE_FP16_FML", pfile);

  aarch64_def_or_undef (TARGET_FRINT, "__ARM_FEATURE_FRINT", pfile);
  aarch64_def_or_undef (TARGET_TME, "__ARM_FEATURE_TME", pfile);
  aarch64_def_or_undef (TARGET_RNG, "__ARM_FEATURE_RNG", pfile);
  aarch64_def_or_undef (TARGET_MEMTAG, "__ARM_FEATURE_MEMORY_TAGGING", pfile);

  aarch64_def_or_undef (aarch64_bti_enabled (),
			"__ARM_FEATURE_BTI_DEFAULT", pfile);

  cpp_undef (pfile, "__ARM_FEATURE_PAC_DEFAULT");
  if (aarch64_ra_sign_scope != AARCH64_FUNCTION_NONE)
    {
      int v = 0;
      if (aarch64_ra_sign_key == AARCH64_KEY_A)
	v |= 1;
      if (aarch64_ra_sign_key == AARCH64_KEY_B)
	v |= 2;
      if (aarch64_ra_sign_scope == AARCH64_FUNCTION_ALL)
	v |= 4;
      builtin_define_with_int_value ("__ARM_FEATURE_PAC_DEFAULT", v);
    }

  aarch64_def_or_undef (TARGET_I8MM, "__ARM_FEATURE_MATMUL_INT8", pfile);
  aarch64_def_or_undef (TARGET_BF16_SIMD,
			"__ARM_FEATURE_BF16_VECTOR_ARITHMETIC", pfile);
  aarch64_def_or_undef (TARGET_BF16_FP,
			"__ARM_FEATURE_BF16_SCALAR_ARITHMETIC", pfile);

  /* Not for ACLE, but required to keep "float.h" correct if we switch
     target between implementations that do or do not support ARMv8.2-A
     16-bit floating-point extensions.  */
  cpp_undef (pfile, "__FLT_EVAL_METHOD__");
  builtin_define_with_int_value ("__FLT_EVAL_METHOD__",
				 c_flt_eval_method (true));
  cpp_undef (pfile, "__FLT_EVAL_METHOD_C99__");
  builtin_define_with_int_value ("__FLT_EVAL_METHOD_C99__",
				 c_flt_eval_method (false));
}

/* Implement TARGET_CPU_CPP_BUILTINS.  */

void
aarch64_cpu_cpp_builtins (cpp_reader *pfile)
{
  aarch64_define_unconditional_macros (pfile);
  aarch64_update_cpp_builtins (pfile);
}

/* Hook to validate the current #pragma GCC target and set the state, and
   update the macros based on what was changed.  If ARGS is NULL, then
   POP_TARGET is used to reset the options.  */

static bool
aarch64_pragma_target_parse (tree args, tree pop_target)
{
  /* If args is not NULL then process it and setup the target-specific
     information that it specifies.  */
  if (args)
    {
      if (!aarch64_process_target_attr (args))
	return false;

      aarch64_override_options_internal (&global_options);
    }

  /* args is NULL, restore to the state described in pop_target.  */
  else
    {
      pop_target = pop_target ? pop_target : target_option_default_node;
      cl_target_option_restore (&global_options, &global_options_set,
				TREE_TARGET_OPTION (pop_target));
    }

  target_option_current_node
    = build_target_option_node (&global_options, &global_options_set);

  aarch64_reset_previous_fndecl ();
  /* For the definitions, ensure all newly defined macros are considered
     as used for -Wunused-macros.  There is no point warning about the
     compiler predefined macros.  */
  cpp_options *cpp_opts = cpp_get_options (parse_in);
  unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
  cpp_opts->warn_unused_macros = 0;

  aarch64_update_cpp_builtins (parse_in);

  cpp_opts->warn_unused_macros = saved_warn_unused_macros;

  /* If we're popping or reseting make sure to update the globals so that
     the optab availability predicates get recomputed.  */
  if (pop_target)
    aarch64_save_restore_target_globals (pop_target);

  /* Initialize SIMD builtins if we haven't already.
     Set current_target_pragma to NULL for the duration so that
     the builtin initialization code doesn't try to tag the functions
     being built with the attributes specified by any current pragma, thus
     going into an infinite recursion.  */
  if (TARGET_SIMD)
    {
      tree saved_current_target_pragma = current_target_pragma;
      current_target_pragma = NULL;
      aarch64_init_simd_builtins ();
      current_target_pragma = saved_current_target_pragma;
    }

  return true;
}

/* Implement "#pragma GCC aarch64".  */
static void
aarch64_pragma_aarch64 (cpp_reader *)
{
  tree x;
  if (pragma_lex (&x) != CPP_STRING)
    {
      error ("%<#pragma GCC aarch64%> requires a string parameter");
      return;
    }

  const char *name = TREE_STRING_POINTER (x);
  if (strcmp (name, "arm_sve.h") == 0)
    aarch64_sve::handle_arm_sve_h ();
  else
    error ("unknown %<#pragma GCC aarch64%> option %qs", name);
}

/* Implement TARGET_RESOLVE_OVERLOADED_BUILTIN.  */
static tree
aarch64_resolve_overloaded_builtin (unsigned int uncast_location,
				    tree fndecl, void *uncast_arglist)
{
  vec<tree, va_gc> empty = {};
  location_t location = (location_t) uncast_location;
  vec<tree, va_gc> *arglist = (uncast_arglist
			       ? (vec<tree, va_gc> *) uncast_arglist
			       : &empty);
  unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
  unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
  tree new_fndecl;
  switch (code & AARCH64_BUILTIN_CLASS)
    {
    case AARCH64_BUILTIN_GENERAL:
      return aarch64_resolve_overloaded_builtin_general (location, fndecl,
							 uncast_arglist);
    case AARCH64_BUILTIN_SVE:
      new_fndecl = aarch64_sve::resolve_overloaded_builtin (location, subcode,
							    arglist);
      break;
    }
  if (new_fndecl == NULL_TREE || new_fndecl == error_mark_node)
    return new_fndecl;
  return build_function_call_vec (location, vNULL, new_fndecl, arglist,
				  NULL, fndecl);
}

/* Implement TARGET_CHECK_BUILTIN_CALL.  */
static bool
aarch64_check_builtin_call (location_t loc, vec<location_t> arg_loc,
			    tree fndecl, tree orig_fndecl,
			    unsigned int nargs, tree *args)
{
  unsigned int code = DECL_MD_FUNCTION_CODE (fndecl);
  unsigned int subcode = code >> AARCH64_BUILTIN_SHIFT;
  switch (code & AARCH64_BUILTIN_CLASS)
    {
    case AARCH64_BUILTIN_GENERAL:
      return true;

    case AARCH64_BUILTIN_SVE:
      return aarch64_sve::check_builtin_call (loc, arg_loc, subcode,
					      orig_fndecl, nargs, args);
    }
  gcc_unreachable ();
}

/* Implement REGISTER_TARGET_PRAGMAS.  */

void
aarch64_register_pragmas (void)
{
  /* Update pragma hook to allow parsing #pragma GCC target.  */
  targetm.target_option.pragma_parse = aarch64_pragma_target_parse;

  targetm.resolve_overloaded_builtin = aarch64_resolve_overloaded_builtin;
  targetm.check_builtin_call = aarch64_check_builtin_call;

  c_register_pragma ("GCC", "aarch64", aarch64_pragma_aarch64);
}
