/* Target Code for OpenRISC
   Copyright (C) 2018-2021 Free Software Foundation, Inc.
   Contributed by Stafford Horne based on other ports.

   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 "regs.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "diagnostic-core.h"
#include "output.h"
#include "stor-layout.h"
#include "varasm.h"
#include "calls.h"
#include "expr.h"
#include "builtins.h"
#include "optabs.h"
#include "explow.h"
#include "cfgrtl.h"
#include "alias.h"

/* These 4 are needed to allow using satisfies_constraint_J.  */
#include "insn-config.h"
#include "recog.h"
#include "tm_p.h"
#include "tm-constrs.h"

/* This file should be included last.  */
#include "target-def.h"

/* Per-function machine data.  */
struct GTY(()) machine_function
{
  /* Number of bytes saved on the stack for callee saved registers.  */
  HOST_WIDE_INT callee_saved_reg_size;

  /* Number of bytes saved on the stack for local variables.  */
  HOST_WIDE_INT local_vars_size;

  /* Number of bytes saved on the stack for outgoing/sub-function args.  */
  HOST_WIDE_INT args_size;

  /* The sum of sizes: locals vars, called saved regs, stack pointer
     and an optional frame pointer.
     Used in expand_prologue () and expand_epilogue ().  */
  HOST_WIDE_INT total_size;

  /* Remember where the set_got_placeholder is located.  */
  rtx_insn *set_got_insn;
};

/* Zero initialization is OK for all current fields.  */

static struct machine_function *
or1k_init_machine_status (void)
{
  return ggc_cleared_alloc<machine_function> ();
}


/* Worker for TARGET_OPTION_OVERRIDE.
   We currently only use this to setup init_machine_status.  */

static void
or1k_option_override (void)
{
  /* Set the per-function-data initializer.  */
  init_machine_status = or1k_init_machine_status;
}

/* Returns true if REGNO must be saved for the current function.  */

static bool
callee_saved_regno_p (int regno)
{
  /* Check call-saved registers.  */
  if (!call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno))
    return true;

  switch (regno)
    {
    case HARD_FRAME_POINTER_REGNUM:
      return frame_pointer_needed;

    case LR_REGNUM:
      /* Always save LR if we are saving HFP, producing a walkable
	 stack chain with -fno-omit-frame-pointer.  */
      return (frame_pointer_needed
	      || !crtl->is_leaf
	      || crtl->uses_pic_offset_table
	      || df_regs_ever_live_p (regno));

    case HW_TO_GCC_REGNO (25):
    case HW_TO_GCC_REGNO (27):
    case HW_TO_GCC_REGNO (29):
    case HW_TO_GCC_REGNO (31):
      /* See EH_RETURN_DATA_REGNO.  */
      return crtl->calls_eh_return;

    default:
      return false;
    }
}

/* Worker for TARGET_COMPUTE_FRAME_LAYOUT.
   Compute and populate machine specific function attributes which are globally
   accessible via cfun->machine.  These include the sizes needed for
   stack stored local variables, callee saved registers and space for stack
   arguments which may be passed to a next function.  The values are used for
   the epilogue, prologue and eliminations.

   OpenRISC stack grows downwards and contains:

    ---- previous frame --------
    current func arg[n]
    current func arg[0]   <-- r2 [HFP,AP]
    ---- current stack frame ---  ^  ---\
    return address      r9        |     |
    old frame pointer   r2       (+)    |-- machine->total_size
    callee saved regs             |     | > machine->callee_saved_reg_size
    local variables               |     | > machine->local_vars_size       <-FP
    next function args    <-- r1 [SP]---/ > machine->args_size
    ----------------------------  |
				 (-)
	   (future)               |
				  V

   All of these contents are optional.  */

static void
or1k_compute_frame_layout (void)
{
  HOST_WIDE_INT local_vars_size, args_size, save_reg_size;

  local_vars_size = get_frame_size ();
  local_vars_size = ROUND_UP (local_vars_size, UNITS_PER_WORD);

  args_size = crtl->outgoing_args_size;
  args_size = ROUND_UP (args_size, UNITS_PER_WORD);

  save_reg_size = 0;
  for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (callee_saved_regno_p (regno))
      save_reg_size += UNITS_PER_WORD;

  cfun->machine->local_vars_size = local_vars_size;
  cfun->machine->args_size = args_size;
  cfun->machine->callee_saved_reg_size = save_reg_size;
  cfun->machine->total_size = save_reg_size + local_vars_size + args_size;
}

/* Emit rtl to save register REGNO contents to stack memory at the given OFFSET
   from the current stack pointer.  */

static void
or1k_save_reg (int regno, HOST_WIDE_INT offset)
{
  rtx reg = gen_rtx_REG (Pmode, regno);
  rtx mem = gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx,
						  offset));
  rtx insn = emit_move_insn (mem, reg);
  RTX_FRAME_RELATED_P (insn) = 1;
}

/* Emit rtl to restore register REGNO contents from stack memory at the given
   OFFSET from the current stack pointer.  */

static rtx
or1k_restore_reg (int regno, HOST_WIDE_INT offset, rtx cfa_restores)
{
  rtx reg = gen_rtx_REG (Pmode, regno);
  rtx mem = gen_frame_mem (SImode, plus_constant (Pmode, stack_pointer_rtx,
						  offset));
  emit_move_insn (reg, mem);
  return alloc_reg_note (REG_CFA_RESTORE, reg, cfa_restores);
}

/* Expand the "prologue" pattern.  */

void
or1k_expand_prologue (void)
{
  HOST_WIDE_INT sp_offset = -cfun->machine->total_size;
  HOST_WIDE_INT reg_offset, this_offset;
  rtx insn;

  if (flag_stack_usage_info)
    current_function_static_stack_size = -sp_offset;

  /* Early exit for frameless functions.  */
  if (sp_offset == 0)
    goto fini;

  /* Adjust the stack pointer.  For large stack offsets we will
     do this in multiple parts, before and after saving registers.  */
  reg_offset = (sp_offset + cfun->machine->local_vars_size
		+ cfun->machine->args_size);
  this_offset = MAX (sp_offset, -32764);
  reg_offset -= this_offset;
  sp_offset -= this_offset;

  insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
				      GEN_INT (this_offset)));
  RTX_FRAME_RELATED_P (insn) = 1;

  /* Save callee-saved registers.  */
  for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (regno != HARD_FRAME_POINTER_REGNUM
	&& regno != LR_REGNUM
	&& callee_saved_regno_p (regno))
      {
	or1k_save_reg (regno, reg_offset);
	reg_offset += UNITS_PER_WORD;
      }

  /* Save and update frame pointer.  */
  if (callee_saved_regno_p (HARD_FRAME_POINTER_REGNUM))
    {
      or1k_save_reg (HARD_FRAME_POINTER_REGNUM, reg_offset);
      if (frame_pointer_needed)
	{
	  insn = emit_insn (gen_addsi3 (hard_frame_pointer_rtx,
					stack_pointer_rtx,
					GEN_INT (-this_offset)));
	  RTX_FRAME_RELATED_P (insn) = 1;
	}
      reg_offset += UNITS_PER_WORD;
    }

  /* Save the link register.  */
  if (callee_saved_regno_p (LR_REGNUM))
    {
      or1k_save_reg (LR_REGNUM, reg_offset);
      reg_offset += UNITS_PER_WORD;
    }
  gcc_assert (reg_offset + this_offset == 0);

  /* Allocate the rest of the stack frame, if any.  */
  if (sp_offset != 0)
    {
      if (sp_offset < 2 * -32768)
	{
	  /* For very large offsets, we need a temporary register.  */
	  rtx tmp = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
	  emit_move_insn (tmp, GEN_INT (sp_offset));
	  insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
					      stack_pointer_rtx, tmp));
	  if (!frame_pointer_needed)
	    {
	      RTX_FRAME_RELATED_P (insn) = 1;
	      add_reg_note (insn, REG_CFA_ADJUST_CFA,
			    gen_rtx_SET (stack_pointer_rtx,
					 plus_constant (Pmode,
							stack_pointer_rtx,
							sp_offset)));
	    }
	}
      else
	{
	  /* Otherwise, emit one or two sequential subtracts.  */
	  do
	    {
	      this_offset = MAX (sp_offset, -32768);
	      sp_offset -= this_offset;

	      insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
						  stack_pointer_rtx,
						  GEN_INT (this_offset)));
	      if (!frame_pointer_needed)
		RTX_FRAME_RELATED_P (insn) = 1;
	    }
	  while (sp_offset != 0);
	}
    }

 fini:
  /* Fix up, or remove, the insn that initialized the pic register.  */
  rtx_insn *set_got_insn = cfun->machine->set_got_insn;
  if (crtl->uses_pic_offset_table)
    {
      rtx reg = SET_DEST (PATTERN (set_got_insn));
      rtx_insn *insn = emit_insn_before (gen_set_got (reg), set_got_insn);
      RTX_FRAME_RELATED_P (insn) = 1;
      add_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL_RTX);
    }
  delete_insn (set_got_insn);
}

/* Expand the "epilogue" pattern.  */

void
or1k_expand_epilogue (void)
{
  HOST_WIDE_INT reg_offset, sp_offset;
  rtx insn, cfa_restores = NULL;

  sp_offset = cfun->machine->total_size;
  if (sp_offset == 0)
    return;

  reg_offset = cfun->machine->local_vars_size + cfun->machine->args_size;

  if (sp_offset >= 32768 || cfun->calls_alloca)
    {
      /* The saved registers are out of range of the stack pointer.
	 We need to partially deallocate the stack frame now.  */
      if (frame_pointer_needed)
	{
	  /* Reset the stack pointer to the bottom of the saved regs.  */
	  sp_offset -= reg_offset;
	  reg_offset = 0;
	  insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
					      hard_frame_pointer_rtx,
					      GEN_INT (-sp_offset)));
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_DEF_CFA,
			plus_constant (Pmode, stack_pointer_rtx, sp_offset));
	}
      else if (sp_offset >= 3 * 32768)
	{
	  /* For very large offsets, we need a temporary register.  */
	  rtx tmp = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
	  emit_move_insn (tmp, GEN_INT (reg_offset));
	  insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
					      stack_pointer_rtx, tmp));
	  sp_offset -= reg_offset;
	  reg_offset = 0;
	  RTX_FRAME_RELATED_P (insn) = 1;
	  add_reg_note (insn, REG_CFA_DEF_CFA,
			plus_constant (Pmode, stack_pointer_rtx, sp_offset));
	}
      else
	{
	  /* Otherwise, emit one or two sequential additions.  */
	  do
	    {
	      HOST_WIDE_INT this_offset = MIN (reg_offset, 32764);
	      reg_offset -= this_offset;
	      sp_offset -= this_offset;

	      insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx,
						  stack_pointer_rtx,
						  GEN_INT (this_offset)));
	      RTX_FRAME_RELATED_P (insn) = 1;
	      add_reg_note (insn, REG_CFA_DEF_CFA,
			    plus_constant (Pmode, stack_pointer_rtx,
					   sp_offset));
	    }
	  while (sp_offset >= 32768);
	}
    }

  /* Restore callee-saved registers.  */
  for (int regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
    if (regno != HARD_FRAME_POINTER_REGNUM
	&& regno != LR_REGNUM
	&& callee_saved_regno_p (regno))
      {
	cfa_restores = or1k_restore_reg (regno, reg_offset, cfa_restores);
	reg_offset += UNITS_PER_WORD;
      }

  /* Restore frame pointer.  */
  if (callee_saved_regno_p (HARD_FRAME_POINTER_REGNUM))
    {
      cfa_restores = or1k_restore_reg (HARD_FRAME_POINTER_REGNUM,
				       reg_offset, cfa_restores);
      reg_offset += UNITS_PER_WORD;
    }

  /* Restore link register.  */
  if (callee_saved_regno_p (LR_REGNUM))
    {
      cfa_restores = or1k_restore_reg (LR_REGNUM, reg_offset, cfa_restores);
      reg_offset += UNITS_PER_WORD;
    }
  gcc_assert (reg_offset == sp_offset);

  /* Restore stack pointer.  */
  insn = emit_insn (gen_frame_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
				      GEN_INT (sp_offset)));
  RTX_FRAME_RELATED_P (insn) = 1;
  REG_NOTES (insn) = cfa_restores;
  add_reg_note (insn, REG_CFA_DEF_CFA, stack_pointer_rtx);

  /* Move up to the stack frame of an exception handler.  */
  if (crtl->calls_eh_return)
    emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
			   EH_RETURN_STACKADJ_RTX));
}

/* Worker for TARGET_INIT_PIC_REG.
   Initialize the cfun->machine->set_got_insn rtx and insert it at the entry
   of the current function.  The rtx is just a temporary placeholder for
   the GOT and will be replaced or removed during or1k_expand_prologue.  */

static void
or1k_init_pic_reg (void)
{
  start_sequence ();

  cfun->machine->set_got_insn
    = emit_insn (gen_set_got_tmp (pic_offset_table_rtx));

  rtx_insn *seq = get_insns ();
  end_sequence ();

  edge entry_edge = single_succ_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun));
  insert_insn_on_edge (seq, entry_edge);
  commit_one_edge_insertion (entry_edge);
}

#undef TARGET_INIT_PIC_REG
#define TARGET_INIT_PIC_REG  or1k_init_pic_reg
#undef TARGET_USE_PSEUDO_PIC_REG
#define TARGET_USE_PSEUDO_PIC_REG  hook_bool_void_true

/* Worker for INITIAL_FRAME_ADDRESS_RTX.
   Returns the RTX representing the address of the initial stack frame.  */

rtx
or1k_initial_frame_addr ()
{
  /* Use this to force a stack frame for the current function.  */
  crtl->accesses_prior_frames = 1;
  return arg_pointer_rtx;
}

/* Worker for DYNAMIC_CHAIN_ADDRESS.
   Returns the RTX representing the address of where the caller's frame pointer
   may be stored on the stack.  */

rtx
or1k_dynamic_chain_addr (rtx frame)
{
  return plus_constant (Pmode, frame, -2 * UNITS_PER_WORD);
}

/* Worker for RETURN_ADDR_RTX.
   Returns the RTX representing the address of where the link register may be
   stored on the stack.  */

rtx
or1k_return_addr (int, rtx frame)
{
  return gen_frame_mem (Pmode, plus_constant (Pmode, frame, -UNITS_PER_WORD));
}

/* Worker for TARGET_FRAME_POINTER_REQUIRED.
   Returns true if the current function must use a frame pointer.  */

static bool
or1k_frame_pointer_required ()
{
  /* ??? While IRA checks accesses_prior_frames, reload does not.
     We do want the frame pointer for this case.  */
  return (crtl->accesses_prior_frames || crtl->profile);
}

/* Expand the "eh_return" pattern.
   Used for defining __builtin_eh_return, this will emit RTX to override the
   current function's return address stored on the stack.  The emitted RTX is
   inserted before the epilogue so we can't just update the link register.
   This is used when handling exceptions to jump into the exception handler
   catch block upon return from _Unwind_RaiseException.  */

void
or1k_expand_eh_return (rtx eh_addr)
{
  rtx lraddr;

  lraddr = gen_frame_mem (Pmode, plus_constant (Pmode,
						arg_pointer_rtx,
						-UNITS_PER_WORD));
  /* Set address to volatile to ensure the store doesn't get optimized out.  */
  MEM_VOLATILE_P (lraddr) = true;
  emit_move_insn (lraddr, eh_addr);
}

/* Helper for defining INITIAL_ELIMINATION_OFFSET.
   We allow the following eliminiations:
     FP -> HARD_FP or SP
     AP -> HARD_FP or SP

   HARD_FP and AP are the same which is handled below.  */

HOST_WIDE_INT
or1k_initial_elimination_offset (int from, int to)
{
  HOST_WIDE_INT offset;

  /* Set OFFSET to the offset from the stack pointer.  */
  switch (from)
    {
    /* Incoming args are all the way up at the previous frame.  */
    case ARG_POINTER_REGNUM:
      offset = cfun->machine->total_size;
      break;

    /* Local args grow downward from the saved registers.  */
    case FRAME_POINTER_REGNUM:
      offset = cfun->machine->args_size + cfun->machine->local_vars_size;
      break;

    default:
      gcc_unreachable ();
    }

  if (to == HARD_FRAME_POINTER_REGNUM)
    offset -= cfun->machine->total_size;

  return offset;
}

/* Worker for TARGET_LEGITIMATE_ADDRESS_P.
   Returns true if X is a legitimate address RTX on OpenRISC.  */

static bool
or1k_legitimate_address_p (machine_mode, rtx x, bool strict_p)
{
  rtx base, addend;

  switch (GET_CODE (x))
    {
    case REG:
      base = x;
      break;

    case PLUS:
      base = XEXP (x, 0);
      addend = XEXP (x, 1);
      if (!REG_P (base))
	return false;
      /* Register elimination is going to adjust all of these offsets.
	 We might as well keep them as a unit until then.  */
      if (!strict_p && virtual_frame_reg_operand (base, VOIDmode))
	return CONST_INT_P (addend);
      if (!satisfies_constraint_I (addend))
	return false;
      break;

    case LO_SUM:
      base = XEXP (x, 0);
      if (!REG_P (base))
	return false;
      x = XEXP (x, 1);
      switch (GET_CODE (x))
	{
	case CONST:
	case SYMBOL_REF:
	case LABEL_REF:
	  /* Assume legitimize_address properly categorized
	     the symbol.  Continue to check the base.  */
	  break;

	case UNSPEC:
	  switch (XINT (x, 1))
	    {
	    case UNSPEC_GOT:
	    case UNSPEC_GOTOFF:
	    case UNSPEC_TPOFF:
	    case UNSPEC_GOTTPOFF:
	      /* Assume legitimize_address properly categorized
		 the symbol.  Continue to check the base.  */
	      break;
	    default:
	      return false;
	    }
	  break;

	default:
	  return false;
	}
      break;

    default:
      return false;
    }

  unsigned regno = REGNO (base);
  if (regno >= FIRST_PSEUDO_REGISTER)
    {
      if (strict_p)
	regno = reg_renumber[regno];
      else
	return true;
    }
  if (strict_p)
    return regno <= 31;
  else
    return REGNO_OK_FOR_BASE_P (regno);
}

/* Return the TLS type for TLS symbols, 0 otherwise.  */

static tls_model
or1k_tls_symbolic_operand (rtx op)
{
  rtx sym, addend;
  split_const (op, &sym, &addend);
  if (SYMBOL_REF_P (sym))
    return SYMBOL_REF_TLS_MODEL (sym);
  return TLS_MODEL_NONE;
}

/* Get a reference to the '__tls_get_addr' symbol.  */

static GTY(()) rtx gen_tls_tga;

static rtx
gen_tls_get_addr (void)
{
  if (!gen_tls_tga)
    gen_tls_tga = init_one_libfunc ("__tls_get_addr");
  return gen_tls_tga;
}

/* Emit a call to '__tls_get_addr'.  */

static void
or1k_tls_call (rtx dest, rtx arg)
{
  emit_library_call_value (gen_tls_get_addr (), dest, LCT_CONST,
			   Pmode, arg, Pmode);
}

/* Helper for or1k_legitimize_address_1.  Wrap X in an unspec.  */

static rtx
gen_sym_unspec (rtx x, int kind)
{
  return gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), kind);
}

/* Worker for TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT.
   Split an out-of-range address displacement into hi and lo parts.
   The hi part will have to be loaded into a register separately,
   but the low part will be folded into the memory operand.  */

static bool
or1k_legitimize_address_displacement (rtx *off1, rtx *off2,
				      poly_int64 poly_offset, machine_mode)
{
  HOST_WIDE_INT orig_offset = poly_offset;
  HOST_WIDE_INT lo, hi;

  /* If the displacement is within range of 2 addi insns, prefer that.
     Otherwise split as per normal, at which point the register allocator
     will see that OFF1 is not a valid add3 operand and load it into
     a register, as desired.  */
  if (orig_offset >= 0 && orig_offset < 2 * 32767)
    {
      hi = 32767;
      lo = orig_offset - hi;
    }
  else if (orig_offset < 0 && orig_offset >= 2 * -32768)
    {
      hi = -32768;
      lo = orig_offset - hi;
    }
  else
    {
      lo = sext_hwi (orig_offset, 16);
      hi = orig_offset - lo;
    }

  *off1 = GEN_INT (hi);
  *off2 = GEN_INT (lo);
  return true;
}

#undef  TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT
#define TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT \
  or1k_legitimize_address_displacement

/* Helper function to implement both TARGET_LEGITIMIZE_ADDRESS and expand the
   patterns "movqi", "movqi" and "movsi".  Returns an valid OpenRISC RTX that
   represents the argument X which is an invalid address RTX.  The argument
   SCRATCH may be used as a temporary when building addresses.  */

static rtx
or1k_legitimize_address_1 (rtx x, rtx scratch)
{
  rtx base, addend, t1, t2;
  tls_model tls_kind = TLS_MODEL_NONE;
  bool is_local = true;

  split_const (x, &base, &addend);
  switch (GET_CODE (base))
    {
    default:
      gcc_assert (can_create_pseudo_p ());
      base = force_reg (Pmode, base);
      break;

    case REG:
    case SUBREG:
      break;

    case SYMBOL_REF:
      tls_kind = SYMBOL_REF_TLS_MODEL (base);
      is_local = SYMBOL_REF_LOCAL_P (base);
      /* FALLTHRU */

    case LABEL_REF:
      switch (tls_kind)
	{
	case TLS_MODEL_NONE:
	  t1 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
	  if (!flag_pic)
	    {
	      emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
	      return gen_rtx_LO_SUM (Pmode, t1, x);
	    }
	  else if (is_local)
	    {
	      crtl->uses_pic_offset_table = 1;
	      t2 = gen_sym_unspec (x, UNSPEC_GOTOFF);
	      emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, t2)));
	      emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
	      return gen_rtx_LO_SUM (Pmode, t1, copy_rtx (t2));
	    }
	  else
	    {
	      base = gen_sym_unspec (base, UNSPEC_GOT);
	      crtl->uses_pic_offset_table = 1;
	      t2 = gen_rtx_LO_SUM (Pmode, pic_offset_table_rtx, base);
	      t2 = gen_const_mem (Pmode, t2);
	      emit_insn (gen_rtx_SET (t1, t2));
	      base = t1;
	    }
	  break;

	case TLS_MODEL_GLOBAL_DYNAMIC:
	case TLS_MODEL_LOCAL_DYNAMIC:
	  /* TODO: For now, treat LD as GD.  */
	  t1 = gen_reg_rtx (Pmode);
	  base = gen_sym_unspec (base, UNSPEC_TLSGD);
	  emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
	  emit_insn (gen_rtx_SET (t1, gen_rtx_LO_SUM (Pmode, t1, base)));
	  crtl->uses_pic_offset_table = 1;
	  emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
	  base = gen_reg_rtx (Pmode);
	  or1k_tls_call (base, t1);
	  break;

	case TLS_MODEL_INITIAL_EXEC:
	  t1 = gen_reg_rtx (Pmode);
	  t2 = gen_reg_rtx (Pmode);
	  base = gen_sym_unspec (base, UNSPEC_GOTTPOFF);
	  emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
	  crtl->uses_pic_offset_table = 1;
	  emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
	  t1 = gen_rtx_LO_SUM (Pmode, t1, base);
	  emit_move_insn (t2, gen_const_mem (Pmode, t1));
	  t1 = gen_rtx_REG (Pmode, TLS_REGNUM);
	  emit_insn (gen_add3_insn (t2, t2, t1));
	  base = t2;
	  break;

	case TLS_MODEL_LOCAL_EXEC:
	  x = gen_sym_unspec (x, UNSPEC_TPOFF);
	  t1 = gen_reg_rtx (Pmode);
	  emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, x)));
	  t2 = gen_rtx_REG (Pmode, TLS_REGNUM);
	  emit_insn (gen_add3_insn (t1, t1, t2));
	  return gen_rtx_LO_SUM (Pmode, t1, x);

	default:
	  gcc_unreachable ();
	}
      break;

    /* Accept what we may have already emitted.  */

    case LO_SUM:
    case UNSPEC:
      return x;
    }

  /* If we get here, we still have addend outstanding.  */
  gcc_checking_assert (register_operand (base, Pmode));
  if (addend == const0_rtx)
    return base;
  if (satisfies_constraint_I (addend)
      || virtual_frame_reg_operand (base, VOIDmode))
    return gen_rtx_PLUS (Pmode, base, addend);
  else
    {
      rtx hi, lo;
      bool ok = (or1k_legitimize_address_displacement
		 (&hi, &lo, INTVAL (addend), SImode));
      gcc_assert (ok);

      t2 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
      if (satisfies_constraint_I (hi))
	emit_insn (gen_addsi3 (t2, base, hi));
      else
	{
	  t1 = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : scratch;
	  emit_move_insn (t1, hi);
	  emit_insn (gen_add3_insn (t2, base, t1));
	}
      if (lo == const0_rtx)
	return t2;
      else
	return gen_rtx_PLUS (Pmode, t2, lo);
    }
}

/* Worker for TARGET_LEGITIMIZE_ADDRESS.
   This delegates implementation to or1k_legitimize_address_1.  */

static rtx
or1k_legitimize_address (rtx x, rtx /* oldx */, machine_mode)
{
  return or1k_legitimize_address_1 (x, NULL_RTX);
}

#undef  TARGET_LEGITIMIZE_ADDRESS
#define TARGET_LEGITIMIZE_ADDRESS or1k_legitimize_address

/* Worker for TARGET_DELEGITIMIZE_ADDRESS.
   In the name of slightly smaller debug output, and to cater to
   general assembler lossage, recognize PIC+GOTOFF and turn it back
   into a direct symbol reference.  */

static rtx
or1k_delegitimize_address (rtx x)
{
  if (GET_CODE (x) == UNSPEC)
    {
      /* The LO_SUM to which X was attached has been stripped.
	 Since the only legitimate address we could have been computing
	 is that of the symbol, assume that's what we've done.  */
      if (XINT (x, 1) == UNSPEC_GOTOFF)
	return XVECEXP (x, 0, 0);
    }
  else if (MEM_P (x))
    {
      rtx addr = XEXP (x, 0);
      if (GET_CODE (addr) == LO_SUM
	  && XEXP (addr, 0) == pic_offset_table_rtx)
	{
	  rtx inner = XEXP (addr, 1);
	  if (GET_CODE (inner) == UNSPEC
	      && XINT (inner, 1) == UNSPEC_GOT)
	    return XVECEXP (inner, 0, 0);
	}
    }
  return delegitimize_mem_from_attrs (x);
}

#undef  TARGET_DELEGITIMIZE_ADDRESS
#define TARGET_DELEGITIMIZE_ADDRESS or1k_delegitimize_address

/* Worker for TARGET_CANNOT_FORCE_CONST_MEM.
   Primarily this is required for TLS symbols, but given that our move
   patterns *ought* to be able to handle any symbol at any time, we
   should never be spilling symbolic operands to the constant pool, ever.  */

static bool
or1k_cannot_force_const_mem (machine_mode, rtx x)
{
  rtx_code code = GET_CODE (x);
  return (code == SYMBOL_REF
	  || code == LABEL_REF
	  || code == CONST
	  || code == HIGH);
}

#undef  TARGET_CANNOT_FORCE_CONST_MEM
#define TARGET_CANNOT_FORCE_CONST_MEM or1k_cannot_force_const_mem

/* Worker for TARGET_LEGITIMATE_CONSTANT_P.
   Returns true is the RTX X represents a constant that can be used as an
   immediate operand in OpenRISC.  */

static bool
or1k_legitimate_constant_p (machine_mode, rtx x)
{
  switch (GET_CODE (x))
    {
    case CONST_INT:
    case CONST_WIDE_INT:
    case HIGH:
      /* We construct these, rather than spilling to memory.  */
      return true;

    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
      /* These may need to be split and not reconstructed.  */
      return or1k_tls_symbolic_operand (x) == TLS_MODEL_NONE;

    default:
      return false;
    }
}

#undef  TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p

/* Worker for TARGET_PASS_BY_REFERENCE.
   Returns true if an argument ARG should be passed by reference as
   required by the OpenRISC ABI.  On OpenRISC structures, unions and
   arguments larger than 64-bits are passed by reference.  */

static bool
or1k_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
{
  if (arg.aggregate_type_p ())
    return true;
  HOST_WIDE_INT size = arg.type_size_in_bytes ();
  return size < 0 || size > 8;
}

/* Worker for TARGET_FUNCTION_VALUE.
   Returns an RTX representing the location where function return values will
   be stored.  On OpenRISC this is the register r11.  64-bit return value's
   upper 32-bits are returned in r12, this is automatically done by GCC.  */

static rtx
or1k_function_value (const_tree valtype,
		     const_tree /* fn_decl_or_type */,
		     bool /* outgoing */)
{
  return gen_rtx_REG (TYPE_MODE (valtype), RV_REGNUM);
}

/* Worker for TARGET_LIBCALL_VALUE.
   Returns an RTX representing the location where function return values to
   external libraries will be stored.  On OpenRISC this the same as local
   function calls.  */

static rtx
or1k_libcall_value (machine_mode mode,
		    const_rtx /* fun */)
{
  return gen_rtx_REG (mode, RV_REGNUM);
}


/* Worker for TARGET_FUNCTION_VALUE_REGNO_P.
   Returns true if REGNO is a valid register for storing a function return
   value.  */

static bool
or1k_function_value_regno_p (const unsigned int regno)
{
  return (regno == RV_REGNUM);
}

/* Worker for TARGET_STRICT_ARGUMENT_NAMING.
   Return true always as on OpenRISC the last argument in a variatic function
   is named.  */

static bool
or1k_strict_argument_naming (cumulative_args_t /* ca */)
{
  return true;
}

#undef  TARGET_STRICT_ARGUMENT_NAMING
#define TARGET_STRICT_ARGUMENT_NAMING or1k_strict_argument_naming

/* Worker for TARGET_FUNCTION_ARG.
   Return the next register to be used to hold a function argument or NULL_RTX
   if there's no more space.  Arugment CUM_V represents the current argument
   offset, zero for the first function argument.  OpenRISC function arguments
   maybe be passed in registers r3 to r8.  */

static rtx
or1k_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
{
  /* Handle the special marker for the end of the arguments.  */
  if (arg.end_marker_p ())
    return NULL_RTX;

  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int nreg = CEIL (GET_MODE_SIZE (arg.mode), UNITS_PER_WORD);

  /* Note that all large arguments are passed by reference.  */
  gcc_assert (nreg <= 2);
  if (arg.named && *cum + nreg <= 6)
    return gen_rtx_REG (arg.mode, *cum + 3);
  else
    return NULL_RTX;
}

/* Worker for TARGET_FUNCTION_ARG_ADVANCE.
   Update the cumulative args descriptor CUM_V to advance past the next function
   argument.  Note, this is not called for arguments passed on the stack.  */

static void
or1k_function_arg_advance (cumulative_args_t cum_v,
			   const function_arg_info &arg)
{
  CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
  int nreg = CEIL (GET_MODE_SIZE (arg.mode), UNITS_PER_WORD);

  /* Note that all large arguments are passed by reference.  */
  gcc_assert (nreg <= 2);
  if (arg.named)
    *cum += nreg;
}

/* worker function for TARGET_RETURN_IN_MEMORY.
   Returns true if the argument of TYPE should be returned in memory.  On
   OpenRISC this is any value larger than 64-bits.  */

static bool
or1k_return_in_memory (const_tree type, const_tree /* fntype */)
{
  const HOST_WIDE_INT size = int_size_in_bytes (type);
  return (size == -1 || size > (2 * UNITS_PER_WORD));
}

/* Print reloc (x + add).  */

static void
output_addr_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, const char *reloc)
{
  if (*reloc)
    {
      fputs (reloc, stream);
      fputc ('(', stream);
    }
  output_addr_const (stream, x);
  if (add)
    {
      if (add > 0)
	fputc ('+', stream);
      fprintf (stream, HOST_WIDE_INT_PRINT_DEC, add);
    }
  if (*reloc)
    fputc (')', stream);
}

enum reloc_kind
{
  RKIND_LO,
  RKIND_HI,
  RKIND_MAX
};

enum reloc_type
{
  RTYPE_DIRECT,
  RTYPE_GOT,
  RTYPE_GOTOFF,
  RTYPE_TPOFF,
  RTYPE_GOTTPOFF,
  RTYPE_TLSGD,
  RTYPE_MAX
};

static void
print_reloc (FILE *stream, rtx x, HOST_WIDE_INT add, reloc_kind kind)
{
  /* All data relocations.  A NULL in this table indicates a form that
     we expect to never generate, while "" indicates a form that requires
     no special markup.  */
  static const char * const relocs[RKIND_MAX][RTYPE_MAX] = {
    { "lo", "got", "gotofflo", "tpofflo", "gottpofflo", "tlsgdlo" },
    { "ha", NULL,  "gotoffha", "tpoffha", "gottpoffha", "tlsgdhi" },
  };
  reloc_type type = RTYPE_DIRECT;

  if (GET_CODE (x) == UNSPEC)
    {
      switch (XINT (x, 1))
	{
	case UNSPEC_GOT:
	  type = RTYPE_GOT;
	  break;
	case UNSPEC_GOTOFF:
	  type = RTYPE_GOTOFF;
	  break;
	case UNSPEC_TPOFF:
	  type = RTYPE_TPOFF;
	  break;
	case UNSPEC_GOTTPOFF:
	  type = RTYPE_GOTTPOFF;
	  break;
	case UNSPEC_TLSGD:
	  type = RTYPE_TLSGD;
	  break;
	default:
	  output_operand_lossage ("invalid relocation");
	  return;
	}
      x = XVECEXP (x, 0, 0);
    }

  const char *reloc = relocs[kind][type];
  if (reloc == NULL)
    output_operand_lossage ("invalid relocation");
  else
    output_addr_reloc (stream, x, add, reloc);
}

/* Worker for TARGET_PRINT_OPERAND_ADDRESS.
   Prints the argument ADDR, an address RTX, to the file FILE.  The output is
   formed as expected by the OpenRISC assembler.  Examples:

     RTX							      OUTPUT
     (reg:SI 3)							       0(r3)
     (plus:SI (reg:SI 3) (const_int 4))				     0x4(r3)
     (lo_sum:SI (reg:SI 3) (symbol_ref:SI ("x"))))		   lo(x)(r3)  */

static void
or1k_print_operand_address (FILE *file, machine_mode, rtx addr)
{
  rtx offset;

  switch (GET_CODE (addr))
    {
    case REG:
      fputc ('0', file);
      break;

    case PLUS:
      offset = XEXP (addr, 1);
      addr = XEXP (addr, 0);
      gcc_assert (CONST_INT_P (offset));
      if (GET_CODE (addr) == LO_SUM)
	{
	  print_reloc (file, XEXP (addr, 1), INTVAL (offset), RKIND_LO);
	  addr = XEXP (addr, 0);
	}
      else
	output_addr_const (file, offset);
      break;

    case LO_SUM:
      offset = XEXP (addr, 1);
      addr = XEXP (addr, 0);
      print_reloc (file, offset, 0, RKIND_LO);
      break;

    default:
      output_addr_const (file, addr);
      return;
    }

  fprintf (file, "(%s)", reg_names[REGNO (addr)]);
}

/* Worker for TARGET_PRINT_OPERAND.
   Print operand X, an RTX, to the file FILE.  The output is formed as expected
   by the OpenRISC assember.  CODE is the letter following a '%' in an
   instrunction template used to control the RTX output.  Example(s):

     CODE   RTX                   OUTPUT     COMMENT
     0      (reg:SI 3)                r3     output an operand
     r      (reg:SI 3)                r3     output a register or const zero
     H      (reg:SI 3)                r4     output the high pair register
     h      (symbol_ref:SI ("x"))  ha(x)     output a signed high relocation
     L      (symbol_ref:SI ("x"))  lo(x)     output a low relocation

   Note, '#' is a special code used to fill the branch delay slot with an l.nop
   instruction.  The l.nop (no-op) instruction is only outputted when the delay
   slot has not been filled.  */

static void
or1k_print_operand (FILE *file, rtx x, int code)
{
  rtx operand = x;

  switch (code)
    {
    case '#':
      /* Conditionally add a nop in unfilled delay slot.  */
      if (final_sequence == NULL)
	fputs ("\n\t l.nop\n", file);
      break;

    case 'r':
      if (REG_P (x))
	fprintf (file, "%s", reg_names[REGNO (operand)]);
      else if (x == CONST0_RTX (GET_MODE (x)))
	fprintf (file, "r0");
      else
	output_operand_lossage ("invalid %%r value");
      break;

    case 'H':
      if (REG_P (x))
	fprintf (file, "%s", reg_names[REGNO (operand) + 1]);
      else
	output_operand_lossage ("invalid %%H value");
      break;

    case 'd':
      if (REG_P (x))
	{
	  if (GET_MODE (x) == DFmode || GET_MODE (x) == DImode)
	    fprintf (file, "%s,%s", reg_names[REGNO (operand)],
				    reg_names[REGNO (operand) + 1]);
	  else
	    fprintf (file, "%s", reg_names[REGNO (operand)]);
	}
      else
	output_operand_lossage ("invalid %%d value");
      break;

    case 'h':
      print_reloc (file, x, 0, RKIND_HI);
      break;
    case 'L':
      print_reloc (file, x, 0, RKIND_LO);
      break;
    case 'P':
      if (!flag_pic || SYMBOL_REF_LOCAL_P (x))
	output_addr_const (file, x);
      else
	output_addr_reloc (file, x, 0, "plt");
      break;

    case 0:
      /* Print an operand as without a modifier letter.  */
      switch (GET_CODE (operand))
	{
	case REG:
	  if (REGNO (operand) > 31)
	    internal_error ("internal error: bad register: %d",
			    REGNO (operand));
	  fprintf (file, "%s", reg_names[REGNO (operand)]);
	  break;

	case MEM:
	  output_address (GET_MODE (XEXP (operand, 0)), XEXP (operand, 0));
	  break;

	case CODE_LABEL:
	case LABEL_REF:
	  output_asm_label (operand);
	  break;

	default:
	  /* No need to handle all strange variants, let output_addr_const
	     do it for us.  */
	  if (CONSTANT_P (operand))
	    output_addr_const (file, operand);
	  else
	    internal_error ("unexpected operand: %d", GET_CODE (operand));
	  break;
	}
      break;

    default:
      output_operand_lossage ("unknown operand letter: '%c'", code);
      break;
    }
}

/* Worker for TARGET_TRAMPOLINE_INIT.
   This is called to initialize a trampoline.  The argument M_TRAMP is an RTX
   for the memory block to be initialized with trampoline code.  The argument
   FNDECL contains the definition of the nested function to be called, we use
   this to get the function's address.  The argument CHAIN is an RTX for the
   static chain value to be passed to the nested function.  */

static void
or1k_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
{
  const unsigned movhi_r13 = (0x06u << 26) | (13 << 21);
  const unsigned movhi_r11 = (0x06u << 26) | (11 << 21);
  const unsigned ori_r13_r13 = (0x2a << 26) | (13 << 21) | (13 << 16);
  const unsigned ori_r11_r11 = (0x2a << 26) | (11 << 21) | (11 << 16);
  const unsigned jr_r13 = (0x11 << 26) | (13 << 11);
  rtx tramp[5], fnaddr, f_hi, f_lo, c_hi, c_lo;

  fnaddr = force_operand (XEXP (DECL_RTL (fndecl), 0), NULL);
  f_hi = expand_binop (SImode, lshr_optab, fnaddr, GEN_INT (16),
		       NULL, true, OPTAB_DIRECT);
  f_lo = expand_binop (SImode, and_optab, fnaddr, GEN_INT (0xffff),
		       NULL, true, OPTAB_DIRECT);

  chain = force_operand (chain, NULL);
  c_hi = expand_binop (SImode, lshr_optab, chain, GEN_INT (16),
		       NULL, true, OPTAB_DIRECT);
  c_lo = expand_binop (SImode, and_optab, chain, GEN_INT (0xffff),
		       NULL, true, OPTAB_DIRECT);

  /* We want to generate

	l.movhi r13,hi(nested_func)
	l.movhi r11,hi(static_chain)
	l.ori	r13,r13,lo(nested_func)
	l.jr	r13
	 l.ori	r11,r11,lo(static_chain)
   */
  tramp[0] = expand_binop (SImode, ior_optab, f_hi,
			   gen_int_mode (movhi_r13, SImode),
			   f_hi, true, OPTAB_DIRECT);
  tramp[1] = expand_binop (SImode, ior_optab, c_hi,
			   gen_int_mode (movhi_r11, SImode),
			   c_hi, true, OPTAB_DIRECT);
  tramp[2] = expand_binop (SImode, ior_optab, f_lo,
			   gen_int_mode (ori_r13_r13, SImode),
			   f_lo, true, OPTAB_DIRECT);
  tramp[4] = expand_binop (SImode, ior_optab, c_lo,
			   gen_int_mode (ori_r11_r11, SImode),
			   c_lo, true, OPTAB_DIRECT);
  tramp[3] = gen_int_mode (jr_r13, SImode);

  for (int i = 0; i < 5; ++i)
    {
      rtx mem = adjust_address (m_tramp, SImode, i * 4);
      emit_move_insn (mem, tramp[i]);
    }

  /* Flushing the trampoline from the instruction cache needs
     to be done here. */
}

/* Worker for TARGET_HARD_REGNO_MODE_OK.
   Returns true if the hard register REGNO is ok for storing values of mode
   MODE.  */

static bool
or1k_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
{
  /* For OpenRISC, GENERAL_REGS can hold anything, while
     FLAG_REGS are really single bits within SP[SR].  */
  if (REGNO_REG_CLASS (regno) == FLAG_REGS)
    return mode == BImode;
  return true;
}

#undef TARGET_HARD_REGNO_MODE_OK
#define TARGET_HARD_REGNO_MODE_OK or1k_hard_regno_mode_ok

/* Worker for TARGET_CAN_CHANGE_MODE_CLASS.
   Returns true if its ok to change a register in class RCLASS from mode FROM to
   mode TO.  In general OpenRISC registers, other than special flags, handle all
   supported classes.  */

static bool
or1k_can_change_mode_class (machine_mode from, machine_mode to,
			    reg_class_t rclass)
{
  if (rclass == FLAG_REGS)
    return from == to;
  return true;
}

#undef TARGET_CAN_CHANGE_MODE_CLASS
#define TARGET_CAN_CHANGE_MODE_CLASS or1k_can_change_mode_class

/* Expand the patterns "movqi", "movqi" and "movsi".  The argument OP0 is the
   destination and OP1 is the source.  This expands to set OP0 to OP1.  OpenRISC
   cannot do memory to memory assignments so for those cases we force one
   argument to a register.  Constants that can't fit into a 16-bit immediate are
   split.  Symbols are legitimized using split relocations.  */

void
or1k_expand_move (machine_mode mode, rtx op0, rtx op1)
{
  if (MEM_P (op0))
    {
      if (!const0_operand (op1, mode))
	op1 = force_reg (mode, op1);
    }
  else if (mode == QImode || mode == HImode)
    {
      /* ??? Maybe promote MEMs and CONST_INT to SImode,
	 and then squish back with gen_lowpart.  */
    }
  else
    {
      switch (GET_CODE (op1))
	{
	case CONST_INT:
	  if (!input_operand (op1, mode))
	    {
	      HOST_WIDE_INT i = INTVAL (op1);
	      HOST_WIDE_INT lo = i & 0xffff;
	      HOST_WIDE_INT hi = i ^ lo;
	      rtx subtarget = op0;

	      if (!cse_not_expected && can_create_pseudo_p ())
		subtarget = gen_reg_rtx (SImode);
	      emit_insn (gen_rtx_SET (subtarget, GEN_INT (hi)));
	      emit_insn (gen_iorsi3 (op0, subtarget, GEN_INT (lo)));
	      return;
	    }
	  break;

	case CONST:
	case SYMBOL_REF:
	case LABEL_REF:
	  op1 = or1k_legitimize_address_1 (op1, op0);
	  break;

	default:
	  break;
	}
    }
  emit_insn (gen_rtx_SET (op0, op1));
}

/* Used to expand patterns "movsicc", "movqicc", "movhicc", "cstoresi4" and
   "cbranchsi4".
   Expands a comparison where OPERANDS is an array of RTX describing the
   comparison.  The first argument OPERANDS[0] is the operator and OPERANDS[1]
   and OPERANDS[2] are the operands.  Split out the compare into SR[F] and
   return a new operation in OPERANDS[0].  The inputs OPERANDS[1] and
   OPERANDS[2] are not directly used, only overridden.  */

void
or1k_expand_compare (rtx *operands)
{
  rtx sr_f = gen_rtx_REG (BImode, SR_F_REGNUM);
  rtx righthand_op = XEXP (operands[0], 1);
  rtx_code cmp_code = GET_CODE (operands[0]);
  bool flag_check_ne = true;

  /* Integer RTL may receive an immediate in argument 1 of the compare, this is
     not supported unless we have l.sf*i instructions, force them into
     registers.  */
  if (!TARGET_SFIMM && CONST_INT_P (righthand_op))
    XEXP (operands[0], 1) = force_reg (SImode, righthand_op);

  /* Normalize comparison operators to ones OpenRISC support.  */
  switch (cmp_code)
    {
      case LTGT:
	cmp_code = UNEQ;
	flag_check_ne = false;
	break;

      case ORDERED:
	cmp_code = UNORDERED;
	flag_check_ne = false;
	break;

      default:
	break;
    }

  /* Emit the given comparison into the Flag bit.  */
  PUT_MODE (operands[0], BImode);
  PUT_CODE (operands[0], cmp_code);
  emit_insn (gen_rtx_SET (sr_f, operands[0]));

  /* Adjust the operands for use in the caller.  */
  operands[0] = flag_check_ne ? gen_rtx_NE (VOIDmode, sr_f, const0_rtx)
			      : gen_rtx_EQ (VOIDmode, sr_f, const0_rtx);
  operands[1] = sr_f;
  operands[2] = const0_rtx;
 }

/* Expand the patterns "call", "sibcall", "call_value" and "sibcall_value".
   Expands a function call where argument RETVAL is an optional RTX providing
   return value storage, the argument FNADDR is and RTX describing the function
   to call, the argument CALLARG1 is the number or registers used as operands
   and the argument SIBCALL should be true if this is a nested function call.
   If FNADDR is a non local symbol and FLAG_PIC is enabled this will generate
   a PLT call.  */

void
or1k_expand_call (rtx retval, rtx fnaddr, rtx callarg1, bool sibcall)
{
  rtx call, use = NULL;

  /* Calls via the PLT require the PIC register.  */
  if (flag_pic
      && GET_CODE (XEXP (fnaddr, 0)) == SYMBOL_REF
      && !SYMBOL_REF_LOCAL_P (XEXP (fnaddr, 0)))
    {
      crtl->uses_pic_offset_table = 1;
      rtx hard_pic = gen_rtx_REG (Pmode, REAL_PIC_OFFSET_TABLE_REGNUM);
      emit_move_insn (hard_pic, pic_offset_table_rtx);
      use_reg (&use, hard_pic);
    }

  if (!call_insn_operand (XEXP (fnaddr, 0), Pmode))
    {
      fnaddr = copy_to_mode_reg (Pmode, XEXP (fnaddr, 0));
      fnaddr = gen_rtx_MEM (SImode, fnaddr);
    }

  call = gen_rtx_CALL (VOIDmode, fnaddr, callarg1);
  if (retval)
    call = gen_rtx_SET (retval, call);

  /* Normal calls clobber LR.  This is required in order to
     prevent e.g. a prologue store of LR being placed into
     the delay slot of the call, after it has been updated.  */
  if (!sibcall)
    {
      rtx clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, LR_REGNUM));
      call = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, call, clob));
    }
  call = emit_call_insn (call);

  CALL_INSN_FUNCTION_USAGE (call) = use;
}

/* Worker for TARGET_FUNCTION_OK_FOR_SIBCALL.
   Returns true if the function declared by DECL is ok for calling as a nested
   function.  */

static bool
or1k_function_ok_for_sibcall (tree decl, tree /* exp */)
{
  /* We can sibcall to any function if not PIC.  */
  if (!flag_pic)
    return true;

  /* We can sibcall any indirect function.  */
  if (decl == NULL)
    return true;

  /* If the call may go through the PLT, we need r16 live.  */
  return targetm.binds_local_p (decl);
}

#undef TARGET_FUNCTION_OK_FOR_SIBCALL
#define TARGET_FUNCTION_OK_FOR_SIBCALL or1k_function_ok_for_sibcall

/* Worker for TARGET_RTX_COSTS.  */

static bool
or1k_rtx_costs (rtx x, machine_mode mode, int outer_code, int /* opno */,
		int *total, bool /* speed */)
{
  switch (GET_CODE (x))
    {
    case CONST_INT:
      if (x == const0_rtx)
	*total = 0;
      else if ((outer_code == PLUS || outer_code == XOR || outer_code == MULT)
	       && satisfies_constraint_I (x))
	*total = 0;
      else if ((outer_code == AND || outer_code == IOR)
	       && satisfies_constraint_K (x))
	*total = 0;
      else if (satisfies_constraint_I (x)
	       || satisfies_constraint_K (x)
	       || satisfies_constraint_M (x))
	*total = 2;
      else
	*total = COSTS_N_INSNS (2);
      return true;

    case CONST_DOUBLE:
      *total = (x == CONST0_RTX (mode) ? 0 : COSTS_N_INSNS (2));
      return true;

    case HIGH:
      /* This is effectively an 'M' constraint.  */
      *total = 2;
      return true;

    case LO_SUM:
      /* This is effectively an 'I' constraint.  */
      *total = (outer_code == MEM ? 0 : 2);
      return true;

    case CONST:
    case SYMBOL_REF:
    case LABEL_REF:
      if (outer_code == LO_SUM || outer_code == HIGH)
	*total = 0;
      else
	{
	  /* ??? Extra cost for GOT or TLS symbols.  */
	  *total = COSTS_N_INSNS (1 + (outer_code != MEM));
	}
      return true;

    case PLUS:
      if (outer_code == MEM)
	*total = 0;
      break;

    default:
      break;
    }
  return false;
}

#undef TARGET_RTX_COSTS
#define TARGET_RTX_COSTS or1k_rtx_costs


/* A subroutine of the atomic operation splitters.  Jump to LABEL if
   COND is true.  Mark the jump as unlikely to be taken.  */

static void
emit_unlikely_jump (rtx_code code, rtx label)
{
  rtx x;

  x = gen_rtx_REG (BImode, SR_F_REGNUM);
  x = gen_rtx_fmt_ee (code, VOIDmode, x, const0_rtx);
  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
  emit_jump_insn (gen_rtx_SET (pc_rtx, x));

  // Disable this for now -- producing verify_cfg failures on probabilities.
  // int very_unlikely = REG_BR_PROB_BASE / 100 - 1;
  // add_int_reg_note (insn, REG_BR_PROB, very_unlikely);
}

/* A subroutine of the atomic operation splitters.
   Emit a raw comparison for A CODE B.  */

static void
emit_compare (rtx_code code, rtx a, rtx b)
{
  emit_insn (gen_rtx_SET (gen_rtx_REG (BImode, SR_F_REGNUM),
			  gen_rtx_fmt_ee (code, BImode, a, b)));
}

/* A subroutine of the atomic operation splitters.
   Emit a load-locked instruction in MODE.  */

static void
emit_load_locked (machine_mode mode, rtx reg, rtx mem)
{
  gcc_assert (mode == SImode);
  emit_insn (gen_load_locked_si (reg, mem));
}

/* A subroutine of the atomic operation splitters.
   Emit a store-conditional instruction in MODE.  */

static void
emit_store_conditional (machine_mode mode, rtx mem, rtx val)
{
  gcc_assert (mode == SImode);
  emit_insn (gen_store_conditional_si (mem, val));
}

/* A subroutine of the various atomic expanders.  For sub-word operations,
   we must adjust things to operate on SImode.  Given the original MEM,
   return a new aligned memory.  Also build and return the quantities by
   which to shift and mask.  */

static rtx
or1k_adjust_atomic_subword (rtx orig_mem, rtx *pshift, rtx *pmask)
{
  rtx addr, align, shift, mask, mem;
  machine_mode mode = GET_MODE (orig_mem);

  addr = XEXP (orig_mem, 0);
  addr = force_reg (Pmode, addr);

  /* Aligned memory containing subword.  Generate a new memory.  We
     do not want any of the existing MEM_ATTR data, as we're now
     accessing memory outside the original object.  */
  align = expand_binop (Pmode, and_optab, addr, GEN_INT (-4),
			NULL_RTX, 1, OPTAB_LIB_WIDEN);
  mem = gen_rtx_MEM (SImode, align);
  MEM_VOLATILE_P (mem) = MEM_VOLATILE_P (orig_mem);
  if (MEM_ALIAS_SET (orig_mem) == ALIAS_SET_MEMORY_BARRIER)
    set_mem_alias_set (mem, ALIAS_SET_MEMORY_BARRIER);

  /* Shift amount for subword relative to aligned word.  */
  rtx mode_mask = GEN_INT (mode == QImode ? 3 : 2);
  shift = expand_binop (SImode, and_optab, gen_lowpart (SImode, addr),
			mode_mask, NULL_RTX, 1, OPTAB_LIB_WIDEN);
  if (BYTES_BIG_ENDIAN)
    shift = expand_binop (SImode, xor_optab, shift, mode_mask,
			  shift, 1, OPTAB_LIB_WIDEN);
  shift = expand_binop (SImode, ashl_optab, shift, GEN_INT (3),
			shift, 1, OPTAB_LIB_WIDEN);
  *pshift = shift;

  /* Mask for insertion.  */
  mask = expand_binop (SImode, ashl_optab, GEN_INT (GET_MODE_MASK (mode)),
		       shift, NULL_RTX, 1, OPTAB_LIB_WIDEN);
  *pmask = mask;

  return mem;
}

/* A subroutine of the various atomic expanders.  For sub-word operations,
   complete the operation by shifting result to the lsb of the SImode
   temporary and then extracting the result in MODE with a SUBREG.  */

static void
or1k_finish_atomic_subword (machine_mode mode, rtx o, rtx n, rtx shift)
{
  n = expand_binop (SImode, lshr_optab, n, shift,
		    NULL_RTX, 1, OPTAB_LIB_WIDEN);
  emit_move_insn (o, gen_lowpart (mode, n));
}

/* Expand an atomic compare and swap operation.
   Emits the RTX to perform a compare and swap operation.  This function takes
   8 RTX arguments in the OPERANDS array.  The compare and swap operation
   loads a value from memory (OPERANDS[2]) and compares it with an expected
   value (OPERANDS[3]), if the values are equal it stores a new value
   (OPERANDS[4]) to memory.  The argument OPERANDS[0] represents a boolean
   result which will be set to true if the operation succeeds.  A return value
   (OPERANDS[1]) will be set to what was loaded from memory.  The argument
   OPERAND[5] is used to indicate if the compare and swap is to be treated as
   weak.  OpenRISC does not use OPERANDS[5] or OPERANDS[6] which provide memory
   model details.
   For OpenRISC this emits RTX which will translate to assembly using the
   'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions.  */

void
or1k_expand_atomic_compare_and_swap (rtx operands[])
{
  rtx boolval, retval, mem, oldval, newval;
  rtx label1, label2;
  machine_mode mode;
  bool is_weak;

  boolval = operands[0];
  retval = operands[1];
  mem = operands[2];
  oldval = operands[3];
  newval = operands[4];
  is_weak = (INTVAL (operands[5]) != 0);
  mode = GET_MODE (mem);

  if (reg_overlap_mentioned_p (retval, oldval))
    oldval = copy_to_reg (oldval);

  label1 = NULL_RTX;
  /* If strong, create a label to try again.  */
  if (!is_weak)
    {
      label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
      emit_label (XEXP (label1, 0));
    }
  label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());

  emit_load_locked (mode, retval, mem);
  emit_compare (EQ, retval, oldval);
  emit_unlikely_jump (EQ, label2);
  emit_store_conditional (mode, mem, newval);

  /* If strong, jump back to try again on fails.  */
  if (!is_weak)
    emit_unlikely_jump (EQ, label1);
  emit_label (XEXP (label2, 0));

  /* In all cases, SR_F contains 1 on success, and 0 on failure.  */
  emit_insn (gen_sne_sr_f (boolval));
}

void
or1k_expand_atomic_compare_and_swap_qihi (rtx operands[])
{
  rtx boolval, orig_retval, retval, scratch, mem, oldval, newval;
  rtx label1, label2, mask, shift;
  machine_mode mode;
  bool is_weak;

  boolval = operands[0];
  orig_retval = operands[1];
  mem = operands[2];
  oldval = operands[3];
  newval = operands[4];
  is_weak = (INTVAL (operands[5]) != 0);
  mode = GET_MODE (mem);

  mem = or1k_adjust_atomic_subword (mem, &shift, &mask);

  /* Shift and mask OLDVAL and NEWVAL into position with the word.  */
  if (oldval != const0_rtx)
    {
      oldval = convert_modes (SImode, mode, oldval, 1);
      oldval = expand_binop (SImode, ashl_optab, oldval, shift,
			     NULL_RTX, 1, OPTAB_LIB_WIDEN);
    }
  if (newval != const0_rtx)
    {
      newval = convert_modes (SImode, mode, newval, 1);
      newval = expand_binop (SImode, ashl_optab, newval, shift,
			     NULL_RTX, 1, OPTAB_LIB_WIDEN);
    }

  label1 = NULL_RTX;
  if (!is_weak)
    {
      label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
      emit_label (XEXP (label1, 0));
    }
  label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());

  scratch = gen_reg_rtx (SImode);
  emit_load_locked (SImode, scratch, mem);

  retval = expand_binop (SImode, and_optab, scratch, mask,
			 NULL_RTX, 1, OPTAB_LIB_WIDEN);
  scratch = expand_binop (SImode, xor_optab, scratch, retval,
			  scratch, 1, OPTAB_LIB_WIDEN);

  emit_compare (EQ, retval, oldval);
  emit_unlikely_jump (EQ, label2);

  if (newval != const0_rtx)
    scratch = expand_binop (SImode, ior_optab, scratch, newval,
			    scratch, 1, OPTAB_LIB_WIDEN);

  emit_store_conditional (SImode, mem, scratch);

  if (!is_weak)
    emit_unlikely_jump (EQ, label1);
  emit_label (XEXP (label2, 0));

  or1k_finish_atomic_subword (mode, orig_retval, retval, shift);

  /* In all cases, SR_F contains 1 on success, and 0 on failure.  */
  emit_insn (gen_sne_sr_f (boolval));
}

/* Expand an atomic exchange operation.
   Emits the RTX to perform an exchange operation.  This function takes 4 RTX
   arguments in the OPERANDS array.  The exchange operation atomically loads a
   value from memory (OPERANDS[1]) to a return value (OPERANDS[0]) and stores a
   new value (OPERANDS[2]) back to the memory location.
   Another argument (OPERANDS[3]) is used to indicate the memory model and
   is not used by OpenRISC.
   For OpenRISC this emits RTX which will translate to assembly using the
   'l.lwa' (load word atomic) and 'l.swa' (store word atomic) instructions.  */

void
or1k_expand_atomic_exchange (rtx operands[])
{
  rtx retval, mem, val, label;
  machine_mode mode;

  retval = operands[0];
  mem = operands[1];
  val = operands[2];
  mode = GET_MODE (mem);

  if (reg_overlap_mentioned_p (retval, val))
    val = copy_to_reg (val);

  label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  emit_load_locked (mode, retval, mem);
  emit_store_conditional (mode, mem, val);
  emit_unlikely_jump (EQ, label);
}

void
or1k_expand_atomic_exchange_qihi (rtx operands[])
{
  rtx orig_retval, retval, mem, val, scratch;
  rtx label, mask, shift;
  machine_mode mode;

  orig_retval = operands[0];
  mem = operands[1];
  val = operands[2];
  mode = GET_MODE (mem);

  mem = or1k_adjust_atomic_subword (mem, &shift, &mask);

  /* Shift and mask VAL into position with the word.  */
  if (val != const0_rtx)
    {
      val = convert_modes (SImode, mode, val, 1);
      val = expand_binop (SImode, ashl_optab, val, shift,
			  NULL_RTX, 1, OPTAB_LIB_WIDEN);
    }

  label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  scratch = gen_reg_rtx (SImode);
  emit_load_locked (SImode, scratch, mem);

  retval = expand_binop (SImode, and_optab, scratch, mask,
			 NULL_RTX, 1, OPTAB_LIB_WIDEN);
  scratch = expand_binop (SImode, xor_optab, scratch, retval,
			  scratch, 1, OPTAB_LIB_WIDEN);
  if (val != const0_rtx)
    scratch = expand_binop (SImode, ior_optab, scratch, val,
			    scratch, 1, OPTAB_LIB_WIDEN);

  emit_store_conditional (SImode, mem, scratch);
  emit_unlikely_jump (EQ, label);

  or1k_finish_atomic_subword (mode, orig_retval, retval, shift);
}

/* Expand an atomic fetch-and-operate pattern.  CODE is the binary operation
   to perform (with MULT as a stand-in for NAND).  MEM is the memory on which
   to operate.  VAL is the second operand of the binary operator.  BEFORE and
   AFTER are optional locations to return the value of MEM either before of
   after the operation.  */

void
or1k_expand_atomic_op (rtx_code code, rtx mem, rtx val,
		       rtx orig_before, rtx orig_after)
{
  machine_mode mode = GET_MODE (mem);
  rtx before = orig_before, after = orig_after;
  rtx label;

  label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  if (before == NULL_RTX)
    before = gen_reg_rtx (mode);

  emit_load_locked (mode, before, mem);

  if (code == MULT)
    {
      after = expand_binop (mode, and_optab, before, val,
			    after, 1, OPTAB_LIB_WIDEN);
      after = expand_unop (mode, one_cmpl_optab, after, after, 1);
    }
  else
    after = expand_simple_binop (mode, code, before, val,
				 after, 1, OPTAB_LIB_WIDEN);

  emit_store_conditional (mode, mem, after);
  emit_unlikely_jump (EQ, label);

  if (orig_before)
    emit_move_insn (orig_before, before);
  if (orig_after)
    emit_move_insn (orig_after, after);
}

void
or1k_expand_atomic_op_qihi (rtx_code code, rtx mem, rtx val,
			    rtx orig_before, rtx orig_after)
{
  machine_mode mode = GET_MODE (mem);
  rtx label, mask, shift, x;
  rtx before, after, scratch;

  mem = or1k_adjust_atomic_subword (mem, &shift, &mask);

  /* Shift and mask VAL into position with the word.  */
  val = convert_modes (SImode, mode, val, 1);
  val = expand_binop (SImode, ashl_optab, val, shift,
		      NULL_RTX, 1, OPTAB_LIB_WIDEN);

  switch (code)
    {
    case IOR:
    case XOR:
      /* We've already zero-extended VAL.  That is sufficient to
	 make certain that it does not affect other bits.  */
      break;

    case AND:
    case MULT: /* NAND */
      /* If we make certain that all of the other bits in VAL are
	 set, that will be sufficient to not affect other bits.  */
      x = expand_unop (SImode, one_cmpl_optab, mask, NULL_RTX, 1);
      val = expand_binop (SImode, ior_optab, val, x,
			  val, 1, OPTAB_LIB_WIDEN);
      break;

    case PLUS:
    case MINUS:
      /* These will all affect bits outside the field and need
	 adjustment via MASK within the loop.  */
      break;

    default:
      gcc_unreachable ();
    }

  label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
  emit_label (XEXP (label, 0));

  before = scratch = gen_reg_rtx (SImode);
  emit_load_locked (SImode, before, mem);

  switch (code)
    {
    case IOR:
    case XOR:
    case AND:
      after = expand_simple_binop (SImode, code, before, val,
				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
      scratch = after;
      break;

    case PLUS:
    case MINUS:
      before = expand_binop (SImode, and_optab, scratch, mask,
			     NULL_RTX, 1, OPTAB_LIB_WIDEN);
      scratch = expand_binop (SImode, xor_optab, scratch, before,
			      scratch, 1, OPTAB_LIB_WIDEN);
      after = expand_simple_binop (SImode, code, before, val,
				   NULL_RTX, 1, OPTAB_LIB_WIDEN);
      after = expand_binop (SImode, and_optab, after, mask,
			    after, 1, OPTAB_LIB_WIDEN);
      scratch = expand_binop (SImode, ior_optab, scratch, after,
			      scratch, 1, OPTAB_LIB_WIDEN);
      break;

    case MULT: /* NAND */
      after = expand_binop (SImode, and_optab, before, val,
			    NULL_RTX, 1, OPTAB_LIB_WIDEN);
      after = expand_binop (SImode, xor_optab, after, mask,
			    after, 1, OPTAB_LIB_WIDEN);
      scratch = after;
      break;

    default:
      gcc_unreachable ();
    }

  emit_store_conditional (SImode, mem, scratch);
  emit_unlikely_jump (EQ, label);

  if (orig_before)
    or1k_finish_atomic_subword (mode, orig_before, before, shift);
  if (orig_after)
    or1k_finish_atomic_subword (mode, orig_after, after, shift);
}

/* Worker for TARGET_ASM_OUTPUT_MI_THUNK.
   Output the assembler code for a thunk function.  THUNK_DECL is the
   declaration for the thunk function itself, FUNCTION is the decl for
   the target function.  DELTA is an immediate constant offset to be
   added to THIS.  If VCALL_OFFSET is nonzero, the word at address
   (*THIS + VCALL_OFFSET) should be additionally added to THIS.  */

static void
or1k_output_mi_thunk (FILE *file, tree thunk_fndecl,
		      HOST_WIDE_INT delta, HOST_WIDE_INT vcall_offset,
		      tree function)
{
  const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk_fndecl));
  rtx this_rtx, funexp;
  rtx_insn *insn;

  reload_completed = 1;
  epilogue_completed = 1;

  emit_note (NOTE_INSN_PROLOGUE_END);

  /* Find the "this" pointer.  Normally in r3, but if the function
     returns a structure, the structure return pointer is in r3 and
     the "this" pointer is in r4 instead.  */
  if (aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function))
    this_rtx = gen_rtx_REG (Pmode, 4);
  else
    this_rtx = gen_rtx_REG (Pmode, 3);

  /* Add DELTA.  When possible use a plain add, otherwise load it
     into a register first.  */
  if (delta)
    {
      rtx delta_rtx = GEN_INT (delta);

      if (!satisfies_constraint_I (delta_rtx))
	{
	  rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
	  emit_move_insn (scratch, delta_rtx);
	  delta_rtx = scratch;
	}

      /* THIS_RTX += DELTA.  */
      emit_insn (gen_add2_insn (this_rtx, delta_rtx));
    }

  /* Add the word at address (*THIS_RTX + VCALL_OFFSET).  */
  if (vcall_offset)
    {
      rtx scratch = gen_rtx_REG (Pmode, PE_TMP_REGNUM);
      HOST_WIDE_INT lo = sext_hwi (vcall_offset, 16);
      HOST_WIDE_INT hi = vcall_offset - lo;
      rtx tmp;

      /* SCRATCH = *THIS_RTX.  */
      tmp = gen_rtx_MEM (Pmode, this_rtx);
      emit_move_insn (scratch, tmp);

      if (hi != 0)
	{
	  rtx scratch2 = gen_rtx_REG (Pmode, RV_REGNUM);
	  emit_move_insn (scratch2, GEN_INT (hi));
	  emit_insn (gen_add2_insn (scratch, scratch2));
	}

      /* SCRATCH = *(*THIS_RTX + VCALL_OFFSET).  */
      tmp = plus_constant (Pmode, scratch, lo);
      tmp = gen_rtx_MEM (Pmode, tmp);
      emit_move_insn (scratch, tmp);

      /* THIS_RTX += *(*THIS_RTX + VCALL_OFFSET).  */
      emit_insn (gen_add2_insn (this_rtx, scratch));
    }

  /* Generate a tail call to the target function.  */
  if (!TREE_USED (function))
    {
      assemble_external (function);
      TREE_USED (function) = 1;
    }
  funexp = XEXP (DECL_RTL (function), 0);

  /* The symbol will be a local alias and therefore always binds local.  */
  gcc_assert (SYMBOL_REF_LOCAL_P (funexp));

  funexp = gen_rtx_MEM (FUNCTION_MODE, funexp);
  insn = emit_call_insn (gen_sibcall (funexp, const0_rtx));
  SIBLING_CALL_P (insn) = 1;
  emit_barrier ();

  /* Run just enough of rest_of_compilation to get the insns emitted.
     There's not really enough bulk here to make other passes such as
     instruction scheduling worth while.  */
  insn = get_insns ();
  shorten_branches (insn);
  assemble_start_function (thunk_fndecl, fnname);
  final_start_function (insn, file, 1);
  final (insn, file, 1);
  final_end_function ();
  assemble_end_function (thunk_fndecl, fnname);

  reload_completed = 0;
  epilogue_completed = 0;
}

#undef  TARGET_ASM_OUTPUT_MI_THUNK
#define TARGET_ASM_OUTPUT_MI_THUNK or1k_output_mi_thunk
#undef  TARGET_ASM_CAN_OUTPUT_MI_THUNK
#define TARGET_ASM_CAN_OUTPUT_MI_THUNK \
  hook_bool_const_tree_hwi_hwi_const_tree_true

#undef  TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE or1k_option_override

#undef  TARGET_COMPUTE_FRAME_LAYOUT
#define TARGET_COMPUTE_FRAME_LAYOUT or1k_compute_frame_layout

#undef  TARGET_LEGITIMATE_ADDRESS_P
#define TARGET_LEGITIMATE_ADDRESS_P or1k_legitimate_address_p

#undef  TARGET_HAVE_TLS
#define TARGET_HAVE_TLS true

#undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed

/* Calling Conventions.  */
#undef  TARGET_FUNCTION_VALUE
#define TARGET_FUNCTION_VALUE or1k_function_value
#undef  TARGET_LIBCALL_VALUE
#define TARGET_LIBCALL_VALUE or1k_libcall_value
#undef  TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P or1k_function_value_regno_p
#undef  TARGET_FUNCTION_ARG
#define TARGET_FUNCTION_ARG or1k_function_arg
#undef  TARGET_FUNCTION_ARG_ADVANCE
#define TARGET_FUNCTION_ARG_ADVANCE or1k_function_arg_advance
#undef  TARGET_RETURN_IN_MEMORY
#define TARGET_RETURN_IN_MEMORY or1k_return_in_memory
#undef  TARGET_PASS_BY_REFERENCE
#define TARGET_PASS_BY_REFERENCE or1k_pass_by_reference
#undef  TARGET_TRAMPOLINE_INIT
#define TARGET_TRAMPOLINE_INIT or1k_trampoline_init
#undef  TARGET_FRAME_POINTER_REQUIRED
#define TARGET_FRAME_POINTER_REQUIRED or1k_frame_pointer_required
#undef  TARGET_CUSTOM_FUNCTION_DESCRIPTORS
#define TARGET_CUSTOM_FUNCTION_DESCRIPTORS 1

/* Assembly generation.  */
#undef  TARGET_PRINT_OPERAND
#define TARGET_PRINT_OPERAND or1k_print_operand
#undef  TARGET_PRINT_OPERAND_ADDRESS
#define TARGET_PRINT_OPERAND_ADDRESS or1k_print_operand_address

/* Section anchor support.  */
#undef  TARGET_MIN_ANCHOR_OFFSET
#define TARGET_MIN_ANCHOR_OFFSET  -32768
#undef  TARGET_MAX_ANCHOR_OFFSET
#define TARGET_MAX_ANCHOR_OFFSET  32767

struct gcc_target targetm = TARGET_INITIALIZER;

#include "gt-or1k.h"
