/* Subroutines for insn-output.c for Matsushita MN10200 series
   Copyright (C) 1997 Free Software Foundation, Inc.
   Contributed by Jeff Law (law@cygnus.com).

This file is part of GNU CC.

GNU CC 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 2, or (at your option)
any later version.

GNU CC 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 GNU CC; see the file COPYING.  If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.  */

#include "config.h"
#include <stdio.h>
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "real.h"
#include "insn-config.h"
#include "conditions.h"
#include "insn-flags.h"
#include "output.h"
#include "insn-attr.h"
#include "flags.h"
#include "recog.h"
#include "expr.h"
#include "tree.h"
#include "obstack.h"

/* Global registers known to hold the value zero.

   Normally we'd depend on CSE and combine to put zero into a
   register and re-use it.

   However, on the mn10x00 processors we implicitly use the constant
   zero in tst instructions, so we might be able to do better by
   loading the value into a register in the prologue, then re-useing
   that register throughout the function.

   We could perform similar optimizations for other constants, but with
   gcse due soon, it doesn't seem worth the effort.

   These variables hold a rtx for a register known to hold the value
   zero throughout the entire function, or NULL if no register of
   the appropriate class has such a value throughout the life of the
   function.  */
rtx zero_dreg;
rtx zero_areg;

/* Note whether or not we need an out of line epilogue.  */
static int out_of_line_epilogue;

/* Indicate this file was compiled by gcc and what optimization
   level was used.  */
void
asm_file_start (file)
     FILE *file;
{
  fprintf (file, "#\tGCC For the Matsushita MN10200\n");
  if (optimize)
    fprintf (file, "# -O%d\n", optimize);
  else
    fprintf (file, "\n\n");
  output_file_directive (file, main_input_filename);
}

/* Print operand X using operand code CODE to assembly language output file
   FILE.  */

void
print_operand (file, x, code)
     FILE *file;
     rtx x;
     int code;
{
  switch (code)
    {
      case 'b':
      case 'B':
	/* These are normal and reversed branches.  */
	switch (code == 'b' ? GET_CODE (x) : reverse_condition (GET_CODE (x)))
	  {
	  case NE:
	    fprintf (file, "ne");
	    break;
	  case EQ:
	    fprintf (file, "eq");
	    break;
	  case GE:
	    fprintf (file, "ge");
	    break;
	  case GT:
	    fprintf (file, "gt");
	    break;
	  case LE:
	    fprintf (file, "le");
	    break;
	  case LT:
	    fprintf (file, "lt");
	    break;
	  case GEU:
	    fprintf (file, "cc");
	    break;
	  case GTU:
	    fprintf (file, "hi");
	    break;
	  case LEU:
	    fprintf (file, "ls");
	    break;
	  case LTU:
	    fprintf (file, "cs");
	    break;
	  default:
	    abort ();
	  }
	break;
      case 'C':
	/* This is used for the operand to a call instruction;
	   if it's a REG, enclose it in parens, else output
	   the operand normally.  */
	if (GET_CODE (x) == REG)
	  {
	    fputc ('(', file);
	    print_operand (file, x, 0);
	    fputc (')', file);
	  }
	else
	  print_operand (file, x, 0);
	break;
     
      /* These are the least significant word in a 32bit value.
	 'o' allows us to sign extend a constant if doing so
	 makes for more compact code.  */
      case 'L':
      case 'o':
	switch (GET_CODE (x))
	  {
	  case MEM:
	    fputc ('(', file);
	    output_address (XEXP (x, 0));
	    fputc (')', file);
	    break;

	  case REG:
	    fprintf (file, "%s", reg_names[REGNO (x)]);
	    break;

	  case SUBREG:
	    fprintf (file, "%s",
		     reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
	    break;

	  case CONST_DOUBLE:
	    if (code == 'L')
	      {
		long val;
		REAL_VALUE_TYPE rv;

		REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
		REAL_VALUE_TO_TARGET_SINGLE (rv, val);
		print_operand_address (file, GEN_INT (val & 0xffff));
	      }
	    else
	      {
		long val;
		REAL_VALUE_TYPE rv;

		REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
		REAL_VALUE_TO_TARGET_SINGLE (rv, val);

		val &= 0xffff;
		val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
		print_operand_address (file, GEN_INT (val));
	      }
	    break;

	  case CONST_INT:
	    if (code == 'L')
	      print_operand_address (file, GEN_INT ((INTVAL (x) & 0xffff)));
	    else
	      {
	        unsigned int val = INTVAL (x) & 0xffff;
		val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;
		print_operand_address (file, GEN_INT (val));
	      }
	    break;
	  default:
	    abort ();
	  }
	break;

      /* Similarly, but for the most significant word.  */
      case 'H':
      case 'h':
	switch (GET_CODE (x))
	  {
	  case MEM:
	    fputc ('(', file);
	    x = adj_offsettable_operand (x, 2);
	    output_address (XEXP (x, 0));
	    fputc (')', file);
	    break;

	  case REG:
	    fprintf (file, "%s", reg_names[REGNO (x) + 1]);
	    break;

	  case SUBREG:
	    fprintf (file, "%s",
		     reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)] + 1);
	    break;

	  case CONST_DOUBLE:
	    if (code == 'H')
	      {
		long val;
		REAL_VALUE_TYPE rv;

		REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
		REAL_VALUE_TO_TARGET_SINGLE (rv, val);

		print_operand_address (file, GEN_INT ((val >> 16) & 0xffff));
	      }
	    else
	      {
		long val;
		REAL_VALUE_TYPE rv;

		REAL_VALUE_FROM_CONST_DOUBLE (rv, x);
		REAL_VALUE_TO_TARGET_SINGLE (rv, val);

		val = (val >> 16) & 0xffff;
		val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;

		print_operand_address (file, GEN_INT (val));
	      }
	    break;

	  case CONST_INT:
	    if (code == 'H')
	      print_operand_address (file,
				     GEN_INT ((INTVAL (x) >> 16) & 0xffff));
	    else
	      {
	        unsigned int val = (INTVAL (x) >> 16) & 0xffff;
		val = (((val) & 0xffff) ^ (~0x7fff)) + 0x8000;

		print_operand_address (file, GEN_INT (val));
	      }
	    break;
	  default:
	    abort ();
	  }
	break;

      /* Output ~CONST_INT.  */
      case 'N':
	if (GET_CODE (x) != CONST_INT)
	  abort ();
        fprintf (file, "%d", ~INTVAL (x));
        break;

      /* An address which can not be register indirect, if it is
	 register indirect, then turn it into reg + disp.  */
      case 'A':
	if (GET_CODE (x) != MEM)
	  abort ();
	if (GET_CODE (XEXP (x, 0)) == REG)
	  x = gen_rtx (PLUS, PSImode, XEXP (x, 0), GEN_INT (0));
	else
	  x = XEXP (x, 0);
	fputc ('(', file);
	output_address (x);
	fputc (')', file);
	break;

      case 'Z':
        print_operand (file, XEXP (x, 1), 0);
	break;

      /* More cases where we can sign-extend a CONST_INT if it
	 results in more compact code.  */
      case 's':
      case 'S':
	if (GET_CODE (x) == CONST_INT)
	  {
	    int val = INTVAL (x);

	    if (code == 's')
	      x = GEN_INT (((val & 0xffff) ^ (~0x7fff)) + 0x8000);
	    else
	      x = GEN_INT (((val & 0xff) ^ (~0x7f)) + 0x80);
	  }
        /* FALL THROUGH */
      default:
	switch (GET_CODE (x))
	  {
	  case MEM:
	    fputc ('(', file);
	    output_address (XEXP (x, 0));
	    fputc (')', file);
	    break;

	  case REG:
	    fprintf (file, "%s", reg_names[REGNO (x)]);
	    break;

	  case SUBREG:
	    fprintf (file, "%s",
		     reg_names[REGNO (SUBREG_REG (x)) + SUBREG_WORD (x)]);
	    break;

	  case CONST_INT:
	  case CONST_DOUBLE:
	  case SYMBOL_REF:
	  case CONST:
	  case LABEL_REF:
	  case CODE_LABEL:
	    print_operand_address (file, x);
	    break;
	  default:
	    abort ();
	  }
	break;
   }
}

/* Output assembly language output for the address ADDR to FILE.  */

void
print_operand_address (file, addr)
     FILE *file;
     rtx addr;
{
  switch (GET_CODE (addr))
    {
    case REG:
      print_operand (file, addr, 0);
      break;
    case PLUS:
      {
	rtx base, index;
	/* The base and index could be in any order, so we have
	   to figure out which is the base and which is the index.
	   Uses the same code as GO_IF_LEGITIMATE_ADDRESS.  */
	if (REG_P (XEXP (addr, 0))
	    && REG_OK_FOR_BASE_P (XEXP (addr, 0)))
	  base = XEXP (addr, 0), index = XEXP (addr, 1);
	else if (REG_P (XEXP (addr, 1))
	    && REG_OK_FOR_BASE_P (XEXP (addr, 1)))
	  base = XEXP (addr, 1), index = XEXP (addr, 0);
      	else
	  abort ();
	print_operand (file, index, 0);
	fputc (',', file);
	print_operand (file, base, 0);;
	break;
      }
    case SYMBOL_REF:
      output_addr_const (file, addr);
      break;
    default:
      output_addr_const (file, addr);
      break;
    }
}

/* Count the number of tst insns which compare an address register
   with zero.  */
static void 
count_tst_insns (areg_countp)
     int *areg_countp;
{
  rtx insn;

  /* Assume no tst insns exist.  */
  *areg_countp = 0;

  /* If not optimizing, then quit now.  */
  if (!optimize)
    return;

  /* Walk through all the insns.  */
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      rtx pat;

      /* Ignore anything that is not a normal INSN.  */
      if (GET_CODE (insn) != INSN)
	continue;

      /* Ignore anything that isn't a SET.  */
      pat = PATTERN (insn);
      if (GET_CODE (pat) != SET)
	continue;

      /* Check for a tst insn.  */
      if (SET_DEST (pat) == cc0_rtx
	  && GET_CODE (SET_SRC (pat)) == REG
	  && REGNO_REG_CLASS (REGNO (SET_SRC (pat))) == ADDRESS_REGS)
	(*areg_countp)++;
    }
}

/* Return the total size (in bytes) of the current function's frame.
   This is the size of the register save area + the size of locals,
   spills, etc.  */
int
total_frame_size ()
{
  unsigned int size = get_frame_size ();
  unsigned int outgoing_args_size = current_function_outgoing_args_size;
  int i;

  /* First figure out if we're going to use an out of line
     prologue, if so we have to make space for all the
     registers, even if we don't use them.  */
  if (optimize && !current_function_needs_context && !frame_pointer_needed)
    {
      int inline_count, outline_count;

      /* Compute how many bytes an inline prologue would take.

         Each address register store takes two bytes, each data register
	 store takes three bytes.  */
      inline_count = 0;
      if (regs_ever_live[5])
	inline_count += 2;
      if (regs_ever_live[6])
	inline_count += 2;
      if (regs_ever_live[2])
	inline_count += 3;
      if (regs_ever_live[3])
	inline_count += 3;

      /* If this function has any stack, then the stack adjustment
	 will take two (or more) bytes.  */
      if (size || outgoing_args_size
	  || regs_ever_live[5] || regs_ever_live[6]
	  || regs_ever_live[2] || regs_ever_live[3])
      inline_count += 2;

      /* Multiply the current count by two and add one to account for the
	 epilogue insns.  */
      inline_count = inline_count * 2 + 1;
    
      /* Now compute how many bytes an out of line sequence would take.  */
      /* A relaxed jsr will be three bytes.  */
      outline_count = 3;

      /* If there are outgoing arguments, then we will need a stack
	 pointer adjustment after the call to the prologue, two
	 more bytes.  */
      outline_count += (outgoing_args_size == 0 ? 0 : 2);

      /* If there is some local frame to allocate, it will need to be
	 done before the call to the prologue, two more bytes.  */
      if (get_frame_size () != 0)
	outline_count += 2;

      /* Now account for the epilogue, multiply the base count by two,
	 then deal with optimizing away the rts instruction.  */
      outline_count = outline_count * 2 + 1;

      if (get_frame_size () == 0 && outgoing_args_size == 0)
	outline_count -= 1;

      /* If an out of line prologue is smaller, use it.  */
      if (inline_count > outline_count)
	return size + outgoing_args_size + 16;
    }


  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
	  || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
	size += 4;
    }

  return (size + outgoing_args_size);
}

/* Expand the prologue into RTL.  */
void
expand_prologue ()
{
  unsigned int size = total_frame_size ();
  unsigned int outgoing_args_size = current_function_outgoing_args_size;
  int offset, i;

  zero_areg = NULL_RTX;
  zero_dreg = NULL_RTX;

  /* If optimizing, see if we should do an out of line prologue/epilogue
     sequence.

     We don't support out of line prologues if the current function
     needs a context or frame pointer.  */
  if (optimize && !current_function_needs_context && !frame_pointer_needed)
    {
      int inline_count, outline_count, areg_count;

      /* We need to end the current sequence so that count_tst_insns can
	 look at all the insns in this function.  Normally this would be
	 unsafe, but it's OK in the prologue/epilogue expanders.  */
      end_sequence ();

      /* Get a count of the number of tst insns which use address
	 registers (it's not profitable to try and improve tst insns
	 which use data registers).  */
      count_tst_insns (&areg_count);

      /* Now start a new sequence.  */
      start_sequence ();

      /* Compute how many bytes an inline prologue would take.

         Each address register store takes two bytes, each data register
	 store takes three bytes.  */
      inline_count = 0;
      if (regs_ever_live[5])
	inline_count += 2;
      if (regs_ever_live[6])
	inline_count += 2;
      if (regs_ever_live[2])
	inline_count += 3;
      if (regs_ever_live[3])
	inline_count += 3;

      /* If this function has any stack, then the stack adjustment
	 will take two (or more) bytes.  */
      if (size || outgoing_args_size
	  || regs_ever_live[5] || regs_ever_live[6]
	  || regs_ever_live[2] || regs_ever_live[3])
      inline_count += 2;

      /* Multiply the current count by two and add one to account for the
	 epilogue insns.  */
      inline_count = inline_count * 2 + 1;
    
      /* Now compute how many bytes an out of line sequence would take.  */
      /* A relaxed jsr will be three bytes.  */
      outline_count = 3;

      /* If there are outgoing arguments, then we will need a stack
	 pointer adjustment after the call to the prologue, two
	 more bytes.  */
      outline_count += (outgoing_args_size == 0 ? 0 : 2);

      /* If there is some local frame to allocate, it will need to be
	 done before the call to the prologue, two more bytes.  */
      if (get_frame_size () != 0)
	outline_count += 2;

      /* Now account for the epilogue, multiply the base count by two,
	 then deal with optimizing away the rts instruction.  */
      outline_count = outline_count * 2 + 1;

      if (get_frame_size () == 0 && outgoing_args_size == 0)
	outline_count -= 1;
     
      /* If an out of line prologue is smaller, use it.  */
      if (inline_count > outline_count)
	{
	  if (get_frame_size () != 0)
	    emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
				    GEN_INT (-size + outgoing_args_size + 16)));
	  emit_insn (gen_outline_prologue_call ());

	  if (outgoing_args_size)
	    emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
				    GEN_INT (-outgoing_args_size)));
	
	  out_of_line_epilogue = 1;

	  /* Determine if it is profitable to put the value zero into a register
	     for the entire function.  If so, set ZERO_DREG and ZERO_AREG.  */

	  /* First see if we could load the value into a data register
	     since that's the most efficient way.  */
	  if (areg_count > 1
	      && (!regs_ever_live[2] || !regs_ever_live[3]))
	    {
	      if (!regs_ever_live[2])
		{
		  regs_ever_live[2] = 1;
		  zero_dreg = gen_rtx (REG, HImode, 2);
		}
	      if (!regs_ever_live[3])
		{
		  regs_ever_live[3] = 1;
		  zero_dreg = gen_rtx (REG, HImode, 3);
		}
	    }

	  /* Now see if we could load the value into a address register.  */
	  if (zero_dreg == NULL_RTX
	      && areg_count > 2
	      && (!regs_ever_live[5] || !regs_ever_live[6]))
	    {
	      if (!regs_ever_live[5])
		{
		  regs_ever_live[5] = 1;
		  zero_areg = gen_rtx (REG, HImode, 5);
		}
	      if (!regs_ever_live[6])
		{
		  regs_ever_live[6] = 1;
		  zero_areg = gen_rtx (REG, HImode, 6);
		}
	    }

	  if (zero_dreg)
	    emit_move_insn (zero_dreg, const0_rtx);

	  if (zero_areg)
	    emit_move_insn (zero_areg, const0_rtx);

	  return;
	}
    }

  out_of_line_epilogue = 0;

  /* Temporarily stuff the static chain onto the stack so we can
     use a0 as a scratch register during the prologue.  */
  if (current_function_needs_context)
    {
      emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
			      GEN_INT (-4)));
      emit_move_insn (gen_rtx (MEM, PSImode, stack_pointer_rtx),
		      gen_rtx (REG, PSImode, STATIC_CHAIN_REGNUM));
    }

  if (frame_pointer_needed)
    {
      /* Store a2 into a0 temporarily.  */
      emit_move_insn (gen_rtx (REG, PSImode, 4), frame_pointer_rtx);

      /* Set up the frame pointer.  */
      emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
    }

  /* Make any necessary space for the saved registers and local frame.  */
  if (size)
    emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
			    GEN_INT (-size)));

  /* Save the callee saved registers.  They're saved into the top
     of the frame, using the stack pointer.  */
  for (i = 0, offset = outgoing_args_size;
       i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
	  || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
	{
	  int regno;

	  /* If we're saving the frame pointer, then it will be found in
	     register 4 (a0).  */
	  regno = (i == FRAME_POINTER_REGNUM && frame_pointer_needed) ? 4 : i;
	
	  emit_move_insn (gen_rtx (MEM, PSImode,
				   gen_rtx (PLUS, Pmode,
					    stack_pointer_rtx,
					    GEN_INT (offset))),
			  gen_rtx (REG, PSImode, regno));
	  offset += 4;
	}
    }

  /* Now put the static chain back where the rest of the function
     expects to find it.  */
  if (current_function_needs_context)
    {
      emit_move_insn (gen_rtx (REG, PSImode, STATIC_CHAIN_REGNUM),
		      gen_rtx (MEM, PSImode,
			       gen_rtx (PLUS, PSImode, stack_pointer_rtx,
					GEN_INT (size))));
    }
}

/* Expand the epilogue into RTL.  */
void
expand_epilogue ()
{
  unsigned int size;
  unsigned int outgoing_args_size = current_function_outgoing_args_size;
  int offset, i, temp_regno;
  rtx basereg;

  size = total_frame_size ();

  if (DECL_RESULT (current_function_decl)
      && DECL_RTL (DECL_RESULT (current_function_decl))
      && REG_P (DECL_RTL (DECL_RESULT (current_function_decl))))
    temp_regno = (REGNO (DECL_RTL (DECL_RESULT (current_function_decl))) == 4
		  ? 0 : 4);
  else
    temp_regno = 4;

  /* Emit an out of line epilogue sequence if it's profitable to do so.  */
  if (out_of_line_epilogue)
    {
      /* If there were no outgoing arguments and no local frame, then
	 we will be able to omit the rts at the end of this function,
	 so just jump to the epilogue_noreturn routine.  */
      if (get_frame_size () == 0 && outgoing_args_size == 0)
	{
	  emit_jump_insn (gen_outline_epilogue_jump ());
	  return;
	}

      if (outgoing_args_size)
	emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
				GEN_INT (outgoing_args_size)));

      if (temp_regno == 0)
	emit_insn (gen_outline_epilogue_call_d0 ());
      else if (temp_regno == 4)
	emit_insn (gen_outline_epilogue_call_a0 ());

      if (get_frame_size () != 0)
	emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
				GEN_INT (size - outgoing_args_size - 16)));
      emit_jump_insn (gen_return_internal ());
      return;
    }

  /* Registers are restored from the frame pointer if we have one,
     else they're restored from the stack pointer.  Figure out
     the appropriate offset to the register save area for both cases.  */
  if (frame_pointer_needed)
    {
      basereg = frame_pointer_rtx;
      offset = -(size - outgoing_args_size);
    }
  else
    {
      basereg = stack_pointer_rtx;
      offset = outgoing_args_size;
    }

  /* Restore each register.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (regs_ever_live[i] && !call_used_regs[i] && ! fixed_regs[i]
	  || (i == FRAME_POINTER_REGNUM && frame_pointer_needed))
	{
	  int regno;

	  /* Restore the frame pointer (if it exists) into a temporary
	     register.  */
	  regno = ((i == FRAME_POINTER_REGNUM && frame_pointer_needed)
		   ? temp_regno : i);
	
	  emit_move_insn (gen_rtx (REG, PSImode, regno),
			  gen_rtx (MEM, PSImode,
				   gen_rtx (PLUS, Pmode,
					    basereg,
					    GEN_INT (offset))));
	  offset += 4;
	}
    }

  if (frame_pointer_needed)
    {
      /* Deallocate this frame's stack.  */
      emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
      /* Restore the old frame pointer.  */
      emit_move_insn (frame_pointer_rtx, gen_rtx (REG, PSImode, temp_regno));
    }
  else if (size)
    {
      /* Deallocate this function's stack.  */
      emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx,
			      GEN_INT (size)));
    }

  /* If we had to allocate a slot to save the context pointer,
     then it must be deallocated here.  */
  if (current_function_needs_context)
    emit_insn (gen_addpsi3 (stack_pointer_rtx, stack_pointer_rtx, GEN_INT (4)));

  /* Emit the return insn, if this function had no stack, then we
     can use the standard return (which allows more optimizations),
     else we have to use the special one which inhibits optimizations.  */
  if (size == 0 && !current_function_needs_context)
    emit_jump_insn (gen_return ());
  else
    emit_jump_insn (gen_return_internal ());
}

/* Update the condition code from the insn.  */

void
notice_update_cc (body, insn)
     rtx body;
     rtx insn;
{
  switch (get_attr_cc (insn))
    {
    case CC_NONE:
      /* Insn does not affect CC at all.  */
      break;

    case CC_NONE_0HIT:
      /* Insn does not change CC, but the 0'th operand has been changed.  */
      if (cc_status.value1 != 0
	  && reg_overlap_mentioned_p (recog_operand[0], cc_status.value1))
	cc_status.value1 = 0;
      break;

    case CC_SET_ZN:
      /* Insn sets the Z,N flags of CC to recog_operand[0].
	 V,C is in an unusable state.  */
      CC_STATUS_INIT;
      cc_status.flags |= CC_OVERFLOW_UNUSABLE | CC_NO_CARRY;
      cc_status.value1 = recog_operand[0];
      break;

    case CC_SET_ZNV:
      /* Insn sets the Z,N,V flags of CC to recog_operand[0].
	 C is in an unusable state.  */
      CC_STATUS_INIT;
      cc_status.flags |= CC_NO_CARRY;
      cc_status.value1 = recog_operand[0];
      break;

    case CC_COMPARE:
      /* The insn is a compare instruction.  */
      CC_STATUS_INIT;
      cc_status.value1 = SET_SRC (body);
      break;

    case CC_CLOBBER:
      /* Insn doesn't leave CC in a usable state.  */
      CC_STATUS_INIT;
      break;

    default:
      CC_STATUS_INIT;
      break;
    }
}

/* Return true if OP is a valid call operand.  Valid call operands
   are SYMBOL_REFs and REGs.  */
int
call_address_operand (op, mode)
     rtx op;
     enum machine_mode mode;
{
  return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == REG);
}

/* Return true if OP is a memory operand with a constant address.
   A special PSImode move pattern uses this predicate.  */
int
constant_memory_operand (op, mode)
     rtx op;
     enum machine_mode mode;
{
  return GET_CODE (op) == MEM && CONSTANT_ADDRESS_P (XEXP (op, 0));
}

/* What (if any) secondary registers are needed to move IN with mode
   MODE into a register from in register class CLASS. 

   We might be able to simplify this.  */
enum reg_class
secondary_reload_class (class, mode, in, input)
     enum reg_class class;
     enum machine_mode mode;
     rtx in;
     int input;
{
  int regno;

  /* Memory loads less than a full word wide can't have an
     address or stack pointer destination.  They must use
     a data register as an intermediate register.  */
  if (input
      && GET_CODE (in) == MEM
      && (mode == QImode)
      && class == ADDRESS_REGS)
    return DATA_REGS;

  /* Address register stores which are not PSImode need a scratch register.  */
  if (! input
      && GET_CODE (in) == MEM
      && (mode != PSImode)
      && class == ADDRESS_REGS)
    return DATA_REGS;

  /* Otherwise assume no secondary reloads are needed.  */
  return NO_REGS;
}


/* Shifts.

   We devote a fair bit of code to getting efficient shifts since we can only
   shift one bit at a time, and each single bit shift may take multiple
   instructions.

   The basic shift methods:

     * loop shifts -- emit a loop using one (or two on H8/S) bit shifts;
     this is the default.  SHIFT_LOOP

     * inlined shifts -- emit straight line code for the shift; this is
     used when a straight line shift is about the same size or smaller
     than a loop.  We allow the inline version to be slightly longer in
     some cases as it saves a register.  SHIFT_INLINE

     * There other oddballs.  Not worth explaining.  SHIFT_SPECIAL


   HImode shifts:

     1-4    do them inline

     5-7    If ashift, then multiply, else loop.
	
     8-14 - If ashift, then multiply, if lshiftrt, then divide, else loop.
     15   - rotate the bit we want into the carry, clear the destination,
	    (use mov 0,dst, not sub as sub will clobber the carry), then
	    move bit into place.

   Don't Panic, it's not nearly as bad as the H8 shifting code!!!  */

int
nshift_operator (x, mode)
     rtx x;
     enum machine_mode mode;
{
  switch (GET_CODE (x))
    {
    case ASHIFTRT:
    case LSHIFTRT:
    case ASHIFT:
      return 1;

    default:
      return 0;
    }
}

/* Called from the .md file to emit code to do shifts.
   Returns a boolean indicating success
   (currently this is always TRUE).  */

int
expand_a_shift (mode, code, operands)
     enum machine_mode mode;
     int code;
     rtx operands[];
{
  emit_move_insn (operands[0], operands[1]);

  /* need a loop to get all the bits we want  - we generate the
     code at emit time, but need to allocate a scratch reg now  */

  emit_insn (gen_rtx
	     (PARALLEL, VOIDmode,
	      gen_rtvec (2,
			 gen_rtx (SET, VOIDmode, operands[0],
				  gen_rtx (code, mode,
					   operands[0], operands[2])),
			 gen_rtx (CLOBBER, VOIDmode,
				  gen_rtx (SCRATCH, HImode, 0)))));

  return 1;
}

/* Shift algorithm determination.

   There are various ways of doing a shift:
   SHIFT_INLINE: If the amount is small enough, just generate as many one-bit
                 shifts as we need.
   SHIFT_SPECIAL: Hand crafted assembler.
   SHIFT_LOOP:    If the above methods fail, just loop.  */

enum shift_alg
{
  SHIFT_INLINE,
  SHIFT_SPECIAL,
  SHIFT_LOOP,
  SHIFT_MAX
};

/* Symbols of the various shifts which can be used as indices.  */

enum shift_type
  {
    SHIFT_ASHIFT, SHIFT_LSHIFTRT, SHIFT_ASHIFTRT
  };

/* Symbols of the various modes which can be used as indices.  */

enum shift_mode
  {
    HIshift, 
  };

/* For single bit shift insns, record assembler and what bits of the
   condition code are valid afterwards (represented as various CC_FOO
   bits, 0 means CC isn't left in a usable state).  */

struct shift_insn
{
  char *assembler;
  int cc_valid;
};

/* Assembler instruction shift table.

   These tables are used to look up the basic shifts.
   They are indexed by cpu, shift_type, and mode.
*/

static const struct shift_insn shift_one[3][3] =
{
  {
/* SHIFT_ASHIFT */
      { "add\t%0,%0", CC_OVERFLOW_UNUSABLE | CC_NO_CARRY },
  },
/* SHIFT_LSHIFTRT */
  {
      { "lsr\t%0", CC_NO_CARRY },
  },
/* SHIFT_ASHIFTRT */
  {
      { "asr\t%0", CC_NO_CARRY },
  },
};

/* Given CPU, MODE, SHIFT_TYPE, and shift count COUNT, determine the best
   algorithm for doing the shift.  The assembler code is stored in ASSEMBLER.
   We don't achieve maximum efficiency in all cases, but the hooks are here
   to do so.

   For now we just use lots of switch statements.  Since we don't even come
   close to supporting all the cases, this is simplest.  If this function ever
   gets too big, perhaps resort to a more table based lookup.  Of course,
   at this point you may just wish to do it all in rtl.  */

static enum shift_alg
get_shift_alg (shift_type, mode, count, assembler_p, cc_valid_p)
     enum shift_type shift_type;
     enum machine_mode mode;
     int count;
     const char **assembler_p;
     int *cc_valid_p;
{
  /* The default is to loop.  */
  enum shift_alg alg = SHIFT_LOOP;
  enum shift_mode shift_mode;

  /* We don't handle negative shifts or shifts greater than the word size,
     they should have been handled already.  */

  if (count < 0 || count > GET_MODE_BITSIZE (mode))
    abort ();

  switch (mode)
    {
    case HImode:
      shift_mode = HIshift;
      break;
    default:
      abort ();
    }

  /* Assume either SHIFT_LOOP or SHIFT_INLINE.
     It is up to the caller to know that looping clobbers cc.  */
  *assembler_p = shift_one[shift_type][shift_mode].assembler;
  *cc_valid_p = shift_one[shift_type][shift_mode].cc_valid;

  /* Now look for cases we want to optimize.  */

  switch (shift_mode)
    {
    case HIshift:
      if (count <= 4)
	return SHIFT_INLINE;
      else if (count < 15 && shift_type != SHIFT_ASHIFTRT)
	{
	  switch (count)
	    {
	    case 5:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 32,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 32,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 6:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 64,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 64,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 7:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 128,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 128,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 8:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 256,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 256,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 9:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 512,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 512,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 10:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 1024,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 1024,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 11:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 2048,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 2048,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 12:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 4096,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 4096,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 13:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 8192,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 8192,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    case 14:
	      if (shift_type == SHIFT_ASHIFT)
		*assembler_p = "mov 16384,%4\n\tmul %4,%0";
	      else if (shift_type == SHIFT_LSHIFTRT)
		*assembler_p
		  = "sub %4,%4\n\tmov %4,mdr\n\tmov 16384,%4\n\tdivu %4,%0";
	      *cc_valid_p = CC_NO_CARRY;
	      return SHIFT_SPECIAL;
	    }
	}
      else if (count == 15)
	{
          if (shift_type == SHIFT_ASHIFTRT)
            {
              *assembler_p = "add\t%0,%0\n\tsubc\t%0,%0\n";
              *cc_valid_p = CC_NO_CARRY;
              return SHIFT_SPECIAL;
	    }
          if (shift_type == SHIFT_LSHIFTRT)
            {
              *assembler_p = "add\t%0,%0\n\tmov 0,%0\n\trol %0\n";
              *cc_valid_p = CC_NO_CARRY;
              return SHIFT_SPECIAL;
	    }
          if (shift_type == SHIFT_ASHIFT)
            {
              *assembler_p = "ror\t%0\n\tmov 0,%0\n\tror %0\n";
              *cc_valid_p = CC_NO_CARRY;
              return SHIFT_SPECIAL;
	    }
	}
      break;

    default:
      abort ();
    }

  return alg;
}

/* Emit the assembler code for doing shifts.  */

char *
emit_a_shift (insn, operands)
     rtx insn;
     rtx *operands;
{
  static int loopend_lab;
  char *assembler;
  int cc_valid;
  rtx inside = PATTERN (insn);
  rtx shift = operands[3];
  enum machine_mode mode = GET_MODE (shift);
  enum rtx_code code = GET_CODE (shift);
  enum shift_type shift_type;
  enum shift_mode shift_mode;

  loopend_lab++;

  switch (mode)
    {
    case HImode:
      shift_mode = HIshift;
      break;
    default:
      abort ();
    }

  switch (code)
    {
    case ASHIFTRT:
      shift_type = SHIFT_ASHIFTRT;
      break;
    case LSHIFTRT:
      shift_type = SHIFT_LSHIFTRT;
      break;
    case ASHIFT:
      shift_type = SHIFT_ASHIFT;
      break;
    default:
      abort ();
    }

  if (GET_CODE (operands[2]) != CONST_INT)
    {
      /* Indexing by reg, so have to loop and test at top */
      output_asm_insn ("mov	%2,%4", operands);
      output_asm_insn ("cmp	0,%4", operands);
      fprintf (asm_out_file, "\tble	.Lle%d\n", loopend_lab);

      /* Get the assembler code to do one shift.  */
      get_shift_alg (shift_type, mode, 1, &assembler, &cc_valid);
    }
  else
    {
      int n = INTVAL (operands[2]);
      enum shift_alg alg;

      /* If the count is negative, make it 0.  */
      if (n < 0)
	n = 0;
      /* If the count is too big, truncate it.
         ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
	 do the intuitive thing.  */
      else if (n > GET_MODE_BITSIZE (mode))
	n = GET_MODE_BITSIZE (mode);

      alg = get_shift_alg (shift_type, mode, n, &assembler, &cc_valid);


      switch (alg)
	{
	case SHIFT_INLINE:
	  /* Emit one bit shifts.  */
	  while (n > 0)
	    {
	      output_asm_insn (assembler, operands);
	      n -= 1;
	    }

	  /* Keep track of CC.  */
	  if (cc_valid)
	    {
	      cc_status.value1 = operands[0];
	      cc_status.flags |= cc_valid;
	    }
	  return "";

	case SHIFT_SPECIAL:
	  output_asm_insn (assembler, operands);

	  /* Keep track of CC.  */
	  if (cc_valid)
	    {
	      cc_status.value1 = operands[0];
	      cc_status.flags |= cc_valid;
	    }
	  return "";
	}

	{
	  fprintf (asm_out_file, "\tmov	%d,%s\n", n,
		   reg_names[REGNO (operands[4])]);
	  fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
	  output_asm_insn (assembler, operands);
	  output_asm_insn ("add	-1,%4", operands);
	  fprintf (asm_out_file, "\tbne	.Llt%d\n", loopend_lab);
	  return "";
	}
    }

  fprintf (asm_out_file, ".Llt%d:\n", loopend_lab);
  output_asm_insn (assembler, operands);
  output_asm_insn ("add	-1,%4", operands);
  fprintf (asm_out_file, "\tbne	.Llt%d\n", loopend_lab);
  fprintf (asm_out_file, ".Lle%d:\n", loopend_lab);

  return "";
}

/* Return an RTX to represent where a value with mode MODE will be returned
   from a function.  If the result is 0, the argument is pushed.  */

rtx
function_arg (cum, mode, type, named)
     CUMULATIVE_ARGS *cum;
     enum machine_mode mode;
     tree type;
     int named;
{
  rtx result = 0;
  int size, align;

  /* We only support using 2 data registers as argument registers.  */
  int nregs = 2;

  /* Only pass named arguments in registers.  */
  if (!named)
    return NULL_RTX;

  /* Figure out the size of the object to be passed.  We lie and claim
     PSImode values are only two bytes since they fit in a single
     register.  */
  if (mode == BLKmode)
    size = int_size_in_bytes (type);
  else if (mode == PSImode)
    size = 2;
  else
    size = GET_MODE_SIZE (mode);

  /* Figure out the alignment of the object to be passed.  */
    align = size;

  cum->nbytes = (cum->nbytes + 1) & ~1;

  /* Don't pass this arg via a register if all the argument registers
     are used up.  */
  if (cum->nbytes + size > nregs * UNITS_PER_WORD)
    return 0;

  switch (cum->nbytes / UNITS_PER_WORD)
    {
    case 0:
      result = gen_rtx (REG, mode, 0);
      break;
    case 1:
      result = gen_rtx (REG, mode, 1);
      break;
    default:
      result = 0;
    }

  return result;
}

/* Return the number of registers to use for an argument passed partially
   in registers and partially in memory.  */

int
function_arg_partial_nregs (cum, mode, type, named)
     CUMULATIVE_ARGS *cum;
     enum machine_mode mode;
     tree type;
     int named;
{
  int size, align;

  /* We only support using 2 data registers as argument registers.  */
  int nregs = 2;

  return 0;
  /* Only pass named arguments in registers.  */
  if (!named)
    return 0;

  /* Figure out the size of the object to be passed.  */
  if (mode == BLKmode)
    size = int_size_in_bytes (type);
  else if (mode == PSImode)
    size = 2;
  else
    size = GET_MODE_SIZE (mode);

  /* Figure out the alignment of the object to be passed.  */
  align = size;

  cum->nbytes = (cum->nbytes + 1) & ~1;

  /* Don't pass this arg via a register if all the argument registers
     are used up.  */
  if (cum->nbytes > nregs * UNITS_PER_WORD)
    return 0;

  if (cum->nbytes + size <= nregs * UNITS_PER_WORD)
    return 0;

  /* Don't pass this arg via a register if it would be split between
     registers and memory.  */
  if (type == NULL_TREE
      && cum->nbytes + size > nregs * UNITS_PER_WORD)
    return 0;

  return (nregs * UNITS_PER_WORD - cum->nbytes) / UNITS_PER_WORD;
}

char *
output_tst (operand, insn)
     rtx operand, insn;
{
  
  rtx temp;
  int past_call = 0;

  /* Only tst insns using address registers can be optimized.  */
  if (REGNO_REG_CLASS (REGNO (operand)) != ADDRESS_REGS)
    return "cmp 0,%0";

  /* If testing an address register against zero, we can do better if
     we know there's a register already holding the value zero.  First
     see if a global register has been set to zero, else we do a search
     for a register holding zero, if both of those fail, then we use a
     compare against zero.  */
  if (zero_dreg || zero_areg)
    {
      rtx xoperands[2];
      xoperands[0] = operand;
      xoperands[1] = zero_dreg ? zero_dreg : zero_areg;

      output_asm_insn ("cmp %1,%0", xoperands);
      return "";
    }

  /* We can save a byte if we can find a register which has the value
     zero in it.  */
  temp = PREV_INSN (insn);
  while (temp)
    {
      rtx set;

      /* We allow the search to go through call insns.  We record
	 the fact that we've past a CALL_INSN and reject matches which
	 use call clobbered registers.  */
      if (GET_CODE (temp) == CODE_LABEL
	  || GET_CODE (temp) == JUMP_INSN
	  || GET_CODE (temp) == BARRIER)
	break;

      if (GET_CODE (temp) == CALL_INSN)
	past_call = 1;

      if (GET_CODE (temp) == NOTE)
	{
	  temp = PREV_INSN (temp);
	  continue;
	}

      /* It must be an insn, see if it is a simple set. */
      set = single_set (temp);
      if (!set)
	{
	  temp = PREV_INSN (temp);
	  continue;
	}

      /* Are we setting a register to zero?

	 If it's a call clobbered register, have we past a call?  */
      if (REG_P (SET_DEST (set))
	  && SET_SRC (set) == CONST0_RTX (GET_MODE (SET_DEST (set)))
	  && !reg_set_between_p (SET_DEST (set), temp, insn)
	  && (!past_call 
	      || !call_used_regs[REGNO (SET_DEST (set))]))
	{
	  rtx xoperands[2];
	  xoperands[0] = operand;
	  xoperands[1] = SET_DEST (set);

	  output_asm_insn ("cmp %1,%0", xoperands);
	  return "";
	}
      temp = PREV_INSN (temp);
    }
  return "cmp 0,%0";
}

/* Return nonzero if OP is a valid operand for a {zero,sign}_extendpsisi
   instruction.

   It accepts anything that is a general operand or the sum of the
   stack pointer and a general operand.  */
extendpsi_operand (op, mode)
     rtx op;
     enum machine_mode mode;
{
  return (general_operand (op, mode)
	  || (GET_CODE (op) == PLUS
	      && XEXP (op, 0) == stack_pointer_rtx
	      && general_operand (XEXP (op, 1), VOIDmode)));
}
