/* 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;
	      if (TARGET_CMODEL_LARGE)
		{
	          emit_insn (gen_rtx_SET (t1, gen_rtx_HIGH (Pmode, base)));
	          emit_insn (gen_add3_insn (t1, t1, pic_offset_table_rtx));
	          t2 = gen_rtx_LO_SUM (Pmode, t1, base);
		}
	      else
	        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", "gotha", "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"
