/* relax-opt pass of Andes NDS32 cpu for GNU compiler
   Copyright (C) 2012-2021 Free Software Foundation, Inc.
   Contributed by Andes Technology Corporation.

   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 "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "stringpool.h"
#include "attribs.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "optabs.h"		/* For GEN_FCN.  */
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "output.h"
#include "explow.h"
#include "expr.h"
#include "tm-constrs.h"
#include "builtins.h"
#include "cpplib.h"
#include "insn-attr.h"
#include "cfgrtl.h"
#include "tree-pass.h"

using namespace nds32;

/* This is used to create unique relax hint id value.
   The initial value is 0.  */
static int relax_group_id = 0;

/* Group the following pattern as relax candidates:

   1. sethi	$ra, hi20(sym)
      ori	$ra, $ra, lo12(sym)
    ==>
      addi.gp	$ra, sym

   2. sethi	$ra, hi20(sym)
      lwi	$rb, [$ra + lo12(sym)]
    ==>
      lwi.gp	$rb, [(sym)]

   3. sethi	$ra, hi20(sym)
      ori	$ra, $ra, lo12(sym)
      lwi	$rb, [$ra]
      swi	$rc, [$ra]
    ==>
      lwi37	$rb, [(sym)]
      swi37	$rc, [(sym)] */

int
nds32_alloc_relax_group_id ()
{
  return relax_group_id++;
}

/* Return true if is load/store with REG addressing mode
   and memory mode is SImode.  */
static bool
nds32_reg_base_load_store_p (rtx_insn *insn)
{
  rtx mem_src = NULL_RTX;

  switch (get_attr_type (insn))
    {
    case TYPE_LOAD:
      mem_src = SET_SRC (PATTERN (insn));
      break;
    case TYPE_STORE:
      mem_src = SET_DEST (PATTERN (insn));
      break;
    default:
      break;
    }

  /* Find load/store insn with addressing mode is REG.  */
  if (mem_src != NULL_RTX)
    {
      if ((GET_CODE (mem_src) == ZERO_EXTEND)
	  || (GET_CODE (mem_src) == SIGN_EXTEND))
	mem_src = XEXP (mem_src, 0);

      if (GET_CODE (XEXP (mem_src, 0)) == REG)
	return true;
    }

  return false;
}

/* Return true if insn is a sp/fp base or sp/fp plus load-store instruction.  */

static bool
nds32_sp_base_or_plus_load_store_p (rtx_insn *insn)
{
  rtx mem_src = NULL_RTX;

  switch (get_attr_type (insn))
    {
    case TYPE_LOAD:
      mem_src = SET_SRC (PATTERN (insn));
      break;
    case TYPE_STORE:
      mem_src = SET_DEST (PATTERN (insn));
      break;
    default:
      break;
    }
  /* Find load/store insn with addressing mode is REG.  */
  if (mem_src != NULL_RTX)
    {
      if ((GET_CODE (mem_src) == ZERO_EXTEND)
	  || (GET_CODE (mem_src) == SIGN_EXTEND))
	mem_src = XEXP (mem_src, 0);

      if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
	mem_src = XEXP (mem_src, 0);

      if (REG_P (XEXP (mem_src, 0))
	  && ((frame_pointer_needed
	       && REGNO (XEXP (mem_src, 0)) == FP_REGNUM)
	      || REGNO (XEXP (mem_src, 0)) == SP_REGNUM))
	return true;
    }

  return false;
}

/* Return true if is load with [REG + REG/CONST_INT]  addressing mode.  */
static bool
nds32_plus_reg_load_store_p (rtx_insn *insn)
{
  rtx mem_src = NULL_RTX;

  switch (get_attr_type (insn))
    {
    case TYPE_LOAD:
      mem_src = SET_SRC (PATTERN (insn));
      break;
    case TYPE_STORE:
      mem_src = SET_DEST (PATTERN (insn));
      break;
    default:
      break;
    }

  /* Find load/store insn with addressing mode is [REG + REG/CONST].  */
  if (mem_src != NULL_RTX)
    {
      if ((GET_CODE (mem_src) == ZERO_EXTEND)
	  || (GET_CODE (mem_src) == SIGN_EXTEND))
	mem_src = XEXP (mem_src, 0);

      if ((GET_CODE (XEXP (mem_src, 0)) == PLUS))
	mem_src = XEXP (mem_src, 0);
      else
	return false;

      if (GET_CODE (XEXP (mem_src, 0)) == REG)
	return true;

    }

  return false;
}

/* Return true if x is const and the referance is ict symbol.  */
static bool
nds32_ict_const_p (rtx x)
{
  if (GET_CODE (x) == CONST)
    {
      x = XEXP (x, 0);
      return nds32_indirect_call_referenced_p (x);
    }
  return FALSE;
}

/* Group the following pattern as relax candidates:

   GOT:
      sethi	$ra, hi20(sym)
      ori	$ra, $ra, lo12(sym)
      lw	$rb, [$ra + $gp]

   GOTOFF, TLSLE:
      sethi	$ra, hi20(sym)
      ori	$ra, $ra, lo12(sym)
      LS	$rb, [$ra + $gp]

   GOTOFF, TLSLE:
      sethi	$ra, hi20(sym)
      ori	$ra, $ra, lo12(sym)
      add	$rb, $ra, $gp($tp)

   Initial GOT table:
      sethi	$gp,hi20(sym)
      ori	$gp, $gp, lo12(sym)
      add5.pc	$gp  */

static auto_vec<rtx_insn *, 32> nds32_group_infos;
/* Group the PIC and TLS relax candidate instructions for linker.  */
static bool
nds32_pic_tls_group (rtx_insn *def_insn,
		     enum nds32_relax_insn_type relax_type,
		     int sym_type)
{
  df_ref def_record;
  df_link *link;
  rtx_insn *use_insn = NULL;
  rtx pat, new_pat;
  def_record = DF_INSN_DEFS (def_insn);
  for (link = DF_REF_CHAIN (def_record); link; link = link->next)
    {
      if (!DF_REF_INSN_INFO (link->ref))
	continue;

      use_insn = DF_REF_INSN (link->ref);

      /* Skip if define insn and use insn not in the same basic block.  */
      if (!dominated_by_p (CDI_DOMINATORS,
			   BLOCK_FOR_INSN (use_insn),
			   BLOCK_FOR_INSN (def_insn)))
	return FALSE;

      /* Skip if use_insn not active insn.  */
      if (!active_insn_p (use_insn))
	return FALSE;

      switch (relax_type)
	{
	case RELAX_ORI:

	  /* GOTOFF, TLSLE:
	     sethi	$ra, hi20(sym)
	     ori	$ra, $ra, lo12(sym)
	     add	$rb, $ra, $gp($tp)  */
	  if ((sym_type == UNSPEC_TLSLE
	       || sym_type == UNSPEC_GOTOFF)
	      && (recog_memoized (use_insn) == CODE_FOR_addsi3))
	    {
	      pat = XEXP (PATTERN (use_insn), 1);
	      new_pat =
		gen_rtx_UNSPEC (SImode,
				gen_rtvec (2, XEXP (pat, 0), XEXP (pat, 1)),
				UNSPEC_ADD32);
	      validate_replace_rtx (pat, new_pat, use_insn);
	      nds32_group_infos.safe_push (use_insn);
	    }
	  else if (nds32_plus_reg_load_store_p (use_insn)
		   && !nds32_sp_base_or_plus_load_store_p (use_insn))
	    nds32_group_infos.safe_push (use_insn);
	  else
	    return FALSE;
	  break;

	default:
	  return FALSE;
	}
    }
  return TRUE;
}

static int
nds32_pic_tls_symbol_type (rtx x)
{
  x = XEXP (SET_SRC (PATTERN (x)), 1);

  if (GET_CODE (x) == CONST)
    {
      x = XEXP (x, 0);

      if (GET_CODE (x) == PLUS)
	x = XEXP (x, 0);

      return XINT (x, 1);
    }

  return XINT (x, 1);
}

/* Group the relax candidates with group id.  */
static void
nds32_group_insns (rtx_insn *sethi)
{
  df_ref def_record, use_record;
  df_link *link;
  rtx_insn *use_insn = NULL;
  rtx group_id;
  bool valid;

  def_record = DF_INSN_DEFS (sethi);

  for (link = DF_REF_CHAIN (def_record); link; link = link->next)
    {
      if (!DF_REF_INSN_INFO (link->ref))
	continue;

      use_insn = DF_REF_INSN (link->ref);

      /* Skip if define insn and use insn not in the same basic block.  */
      if (!dominated_by_p (CDI_DOMINATORS,
			   BLOCK_FOR_INSN (use_insn),
			   BLOCK_FOR_INSN (sethi)))
	return;

      /* Skip if the low-part used register is from different high-part
	 instructions.  */
      use_record = DF_INSN_USES (use_insn);
      if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
	return;

      /* Skip if use_insn not active insn.  */
      if (!active_insn_p (use_insn))
	return;

     /* Initial use_insn_type.  */
      if (!(recog_memoized (use_insn) == CODE_FOR_lo_sum
	    || nds32_symbol_load_store_p (use_insn)
	    || (nds32_reg_base_load_store_p (use_insn)
		&&!nds32_sp_base_or_plus_load_store_p (use_insn))))
	return;
    }

  group_id = GEN_INT (nds32_alloc_relax_group_id ());
  /* Insert .relax_* directive for sethi.  */
  emit_insn_before (gen_relax_group (group_id), sethi);

  /* Scan the use insns and insert the directive.  */
  for (link = DF_REF_CHAIN (def_record); link; link = link->next)
    {
      if (!DF_REF_INSN_INFO (link->ref))
	continue;

      use_insn = DF_REF_INSN (link->ref);

      /* Insert .relax_* directive.  */
      if (active_insn_p (use_insn))
	emit_insn_before (gen_relax_group (group_id), use_insn);

      /* Find ori ra, ra, unspec(symbol) instruction.  */
      if (use_insn != NULL
	  && recog_memoized (use_insn) == CODE_FOR_lo_sum
	  && !nds32_const_unspec_p (XEXP (SET_SRC (PATTERN (use_insn)), 1)))
	{
	  int sym_type = nds32_pic_tls_symbol_type (use_insn);
	  valid = nds32_pic_tls_group (use_insn, RELAX_ORI, sym_type);

	  /* Insert .relax_* directive.  */
	  while (!nds32_group_infos.is_empty ())
	    {
	      use_insn = nds32_group_infos.pop ();
	      if (valid)
		emit_insn_before (gen_relax_group (group_id), use_insn);
	    }
	}
    }
}

/* Convert relax group id in rtl.  */

static void
nds32_group_tls_insn (rtx insn)
{
  rtx pat = PATTERN (insn);
  rtx unspec_relax_group = XEXP (XVECEXP (pat, 0, 1), 0);
  int group_id = nds32_alloc_relax_group_id ();

  while (GET_CODE (pat) != SET && GET_CODE (pat) == PARALLEL)
    {
      pat = XVECEXP (pat, 0, 0);
    }

  if (GET_CODE (unspec_relax_group) == UNSPEC
      && XINT (unspec_relax_group, 1) == UNSPEC_VOLATILE_RELAX_GROUP)
    {
      XVECEXP (unspec_relax_group, 0, 0) = GEN_INT (group_id);
    }
}

static bool
nds32_float_reg_load_store_p (rtx_insn *insn)
{
  rtx pat = PATTERN (insn);

  if (get_attr_type (insn) == TYPE_FLOAD
      && GET_CODE (pat) == SET
      && (GET_MODE (XEXP (pat, 0)) == SFmode
	  || GET_MODE (XEXP (pat, 0)) == DFmode)
      && MEM_P (XEXP (pat, 1)))
    {
      rtx addr = XEXP (XEXP (pat, 1), 0);

      /* [$ra] */
      if (REG_P (addr))
	return true;
      /* [$ra + offset] */
      if (GET_CODE (addr) == PLUS
	  && REG_P (XEXP (addr, 0))
	  && CONST_INT_P (XEXP (addr, 1)))
	return true;
    }
  return false;
}


/* Group float load-store instructions:
   la $ra, symbol
   flsi $rt, [$ra + offset] */

static void
nds32_group_float_insns (rtx_insn *insn)
{
  df_ref def_record, use_record;
  df_link *link;
  rtx_insn *use_insn = NULL;
  rtx group_id;

  def_record = DF_INSN_DEFS (insn);

  for (link = DF_REF_CHAIN (def_record); link; link = link->next)
    {
      if (!DF_REF_INSN_INFO (link->ref))
	continue;

      use_insn = DF_REF_INSN (link->ref);

      /* Skip if define insn and use insn not in the same basic block.  */
      if (!dominated_by_p (CDI_DOMINATORS,
			   BLOCK_FOR_INSN (use_insn),
			   BLOCK_FOR_INSN (insn)))
	return;

      /* Skip if the low-part used register is from different high-part
	 instructions.  */
      use_record = DF_INSN_USES (use_insn);
      if (DF_REF_CHAIN (use_record) && DF_REF_CHAIN (use_record)->next)
	return;

      /* Skip if use_insn not active insn.  */
      if (!active_insn_p (use_insn))
	return;

      if (!nds32_float_reg_load_store_p (use_insn)
	  || find_post_update_rtx (use_insn) != -1)
	return;
    }

  group_id = GEN_INT (nds32_alloc_relax_group_id ());
  /* Insert .relax_* directive for insn.  */
  emit_insn_before (gen_relax_group (group_id), insn);

  /* Scan the use insns and insert the directive.  */
  for (link = DF_REF_CHAIN (def_record); link; link = link->next)
    {
      if (!DF_REF_INSN_INFO (link->ref))
	continue;

      use_insn = DF_REF_INSN (link->ref);

      /* Insert .relax_* directive.  */
	emit_insn_before (gen_relax_group (group_id), use_insn);
    }
}

/* Group the relax candidate instructions for linker.  */
static void
nds32_relax_group (void)
{
  rtx_insn *insn;

  compute_bb_for_insn ();

  df_chain_add_problem (DF_DU_CHAIN | DF_UD_CHAIN);
  df_insn_rescan_all ();
  df_analyze ();
  df_set_flags (DF_DEFER_INSN_RESCAN);
  calculate_dominance_info (CDI_DOMINATORS);

  insn = get_insns ();
  gcc_assert (NOTE_P (insn));

  for (insn = next_active_insn (insn); insn; insn = next_active_insn (insn))
    {
      if (NONJUMP_INSN_P (insn))
	{
	  /* Find sethi ra, symbol  instruction.  */
	  if (recog_memoized (insn) == CODE_FOR_sethi
	      && nds32_symbolic_operand (XEXP (SET_SRC (PATTERN (insn)), 0),
					 SImode)
	      && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
	    nds32_group_insns (insn);
	  else if (recog_memoized (insn) == CODE_FOR_tls_ie)
	    nds32_group_tls_insn (insn);
	  else if (TARGET_FPU_SINGLE
		   && recog_memoized (insn) == CODE_FOR_move_addr
		   && !nds32_ict_const_p (XEXP (SET_SRC (PATTERN (insn)), 0)))
	    {
	      nds32_group_float_insns (insn);
	    }
	}
      else if (CALL_P (insn) && recog_memoized (insn) == CODE_FOR_tls_desc)
	{
	  nds32_group_tls_insn (insn);
	}
    }

  /* We must call df_finish_pass manually because it should be invoked before
     BB information is destroyed. Hence we cannot set the TODO_df_finish flag
     to the pass manager.  */
  df_insn_rescan_all ();
  df_finish_pass (false);
  free_dominance_info (CDI_DOMINATORS);
}

static unsigned int
nds32_relax_opt (void)
{
  if (TARGET_RELAX_HINT)
    nds32_relax_group ();
  return 1;
}

const pass_data pass_data_nds32_relax_opt =
{
  RTL_PASS,				/* type */
  "relax_opt",				/* name */
  OPTGROUP_NONE,			/* optinfo_flags */
  TV_MACH_DEP,				/* tv_id */
  0,					/* properties_required */
  0,					/* properties_provided */
  0,					/* properties_destroyed */
  0,					/* todo_flags_start */
  TODO_df_finish,			/* todo_flags_finish */
};

class pass_nds32_relax_opt : public rtl_opt_pass
{
public:
  pass_nds32_relax_opt (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_nds32_relax_opt, ctxt)
  {}

  /* opt_pass methods: */
  bool gate (function *) { return TARGET_RELAX_HINT; }
  unsigned int execute (function *) { return nds32_relax_opt (); }
};

rtl_opt_pass *
make_pass_nds32_relax_opt (gcc::context *ctxt)
{
  return new pass_nds32_relax_opt (ctxt);
}
