Home | History | Annotate | Line # | Download | only in fr30
fr30.cc revision 1.1
      1 /* FR30 specific functions.
      2    Copyright (C) 1998-2022 Free Software Foundation, Inc.
      3    Contributed by Cygnus Solutions.
      4 
      5    This file is part of GCC.
      6 
      7    GCC is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GCC is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GCC; see the file COPYING3.  If not see
     19    <http://www.gnu.org/licenses/>.  */
     20 
     21 /*{{{  Includes */
     22 
     23 #define IN_TARGET_CODE 1
     24 
     25 #include "config.h"
     26 #include "system.h"
     27 #include "coretypes.h"
     28 #include "backend.h"
     29 #include "target.h"
     30 #include "rtl.h"
     31 #include "tree.h"
     32 #include "stringpool.h"
     33 #include "attribs.h"
     34 #include "df.h"
     35 #include "memmodel.h"
     36 #include "emit-rtl.h"
     37 #include "stor-layout.h"
     38 #include "varasm.h"
     39 #include "output.h"
     40 #include "expr.h"
     41 #include "builtins.h"
     42 #include "calls.h"
     43 
     44 /* This file should be included last.  */
     45 #include "target-def.h"
     46 
     47 /*}}}*/
     48 /*{{{  Function Prologues & Epilogues */
     49 
     50 /* The FR30 stack looks like this:
     51 
     52              Before call                       After call
     53    FP ->|                       |       |                       |
     54         +-----------------------+       +-----------------------+       high
     55         |                       |       |                       |       memory
     56         |  local variables,     |       |  local variables,     |
     57         |  reg save area, etc.  |       |  reg save area, etc.  |
     58         |                       |       |                       |
     59         +-----------------------+       +-----------------------+
     60         |                       |       |                       |
     61         | args to the func that |       |  args to this func.   |
     62         | is being called that  |       |                       |
     63    SP ->| do not fit in regs    |       |                       |
     64         +-----------------------+       +-----------------------+
     65                                         |  args that used to be |  \
     66                                         | in regs; only created |   |  pretend_size
     67                                    AP-> |   for vararg funcs    |  /
     68                                         +-----------------------+
     69                                         |                       |  \
     70                                         |  register save area   |   |
     71                                         |                       |   |
     72 					+-----------------------+   |  reg_size
     73                                         |    return address     |   |
     74 					+-----------------------+   |
     75                                    FP ->|   previous frame ptr  |  /
     76                                         +-----------------------+
     77                                         |                       |  \
     78                                         |  local variables      |   |  var_size
     79                                         |                       |  /
     80                                         +-----------------------+
     81                                         |                       |  \
     82      low                                |  room for args to     |   |
     83      memory                             |  other funcs called   |   |  args_size
     84                                         |  from this one        |   |
     85                                    SP ->|                       |  /
     86                                         +-----------------------+
     87 
     88    Note, AP is a fake hard register.  It will be eliminated in favor of
     89    SP or FP as appropriate.
     90 
     91    Note, Some or all of the stack sections above may be omitted if they
     92    are not needed.  */
     93 
     94 /* Structure to be filled in by fr30_compute_frame_size() with register
     95    save masks, and offsets for the current function.  */
     96 struct fr30_frame_info
     97 {
     98   unsigned int total_size;	/* # Bytes that the entire frame takes up.  */
     99   unsigned int pretend_size;	/* # Bytes we push and pretend caller did.  */
    100   unsigned int args_size;	/* # Bytes that outgoing arguments take up.  */
    101   unsigned int reg_size;	/* # Bytes needed to store regs.  */
    102   unsigned int var_size;	/* # Bytes that variables take up.  */
    103   unsigned int frame_size;      /* # Bytes in current frame.  */
    104   unsigned int gmask;		/* Mask of saved registers.  */
    105   unsigned int save_fp;		/* Nonzero if frame pointer must be saved.  */
    106   unsigned int save_rp;		/* Nonzero if return pointer must be saved.  */
    107   int          initialised;	/* Nonzero if frame size already calculated.  */
    108 };
    109 
    110 /* Current frame information calculated by fr30_compute_frame_size().  */
    111 static struct fr30_frame_info 	current_frame_info;
    112 
    113 /* Zero structure to initialize current_frame_info.  */
    114 static struct fr30_frame_info 	zero_frame_info;
    115 
    116 static void fr30_setup_incoming_varargs (cumulative_args_t,
    117 					 const function_arg_info &,
    118 					 int *, int);
    119 static bool fr30_must_pass_in_stack (const function_arg_info &);
    120 static int fr30_arg_partial_bytes (cumulative_args_t,
    121 				   const function_arg_info &);
    122 static rtx fr30_function_arg (cumulative_args_t, const function_arg_info &);
    123 static void fr30_function_arg_advance (cumulative_args_t,
    124 				       const function_arg_info &);
    125 static bool fr30_frame_pointer_required (void);
    126 static rtx fr30_function_value (const_tree, const_tree, bool);
    127 static rtx fr30_libcall_value (machine_mode, const_rtx);
    128 static bool fr30_function_value_regno_p (const unsigned int);
    129 static bool fr30_can_eliminate (const int, const int);
    130 static void fr30_asm_trampoline_template (FILE *);
    131 static void fr30_trampoline_init (rtx, tree, rtx);
    132 static int fr30_num_arg_regs (const function_arg_info &);
    133 
    134 #define FRAME_POINTER_MASK 	(1 << (FRAME_POINTER_REGNUM))
    135 #define RETURN_POINTER_MASK 	(1 << (RETURN_POINTER_REGNUM))
    136 
    137 /* Tell prologue and epilogue if register REGNO should be saved / restored.
    138    The return address and frame pointer are treated separately.
    139    Don't consider them here.  */
    140 #define MUST_SAVE_REGISTER(regno)      \
    141   (   (regno) != RETURN_POINTER_REGNUM \
    142    && (regno) != FRAME_POINTER_REGNUM  \
    143    && df_regs_ever_live_p (regno)      \
    144    && ! call_used_or_fixed_reg_p (regno))
    145 
    146 #define MUST_SAVE_FRAME_POINTER	 (df_regs_ever_live_p (FRAME_POINTER_REGNUM)  || frame_pointer_needed)
    147 #define MUST_SAVE_RETURN_POINTER (df_regs_ever_live_p (RETURN_POINTER_REGNUM) || crtl->profile)
    148 
    149 #if UNITS_PER_WORD == 4
    150 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
    151 #endif
    152 
    153 /* Initialize the GCC target structure.  */
    155 #undef  TARGET_ASM_ALIGNED_HI_OP
    156 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
    157 #undef  TARGET_ASM_ALIGNED_SI_OP
    158 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
    159 
    160 #undef  TARGET_PROMOTE_PROTOTYPES
    161 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
    162 #undef  TARGET_PASS_BY_REFERENCE
    163 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
    164 #undef  TARGET_ARG_PARTIAL_BYTES
    165 #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
    166 #undef  TARGET_FUNCTION_ARG
    167 #define TARGET_FUNCTION_ARG fr30_function_arg
    168 #undef  TARGET_FUNCTION_ARG_ADVANCE
    169 #define TARGET_FUNCTION_ARG_ADVANCE fr30_function_arg_advance
    170 
    171 #undef TARGET_FUNCTION_VALUE
    172 #define TARGET_FUNCTION_VALUE fr30_function_value
    173 #undef TARGET_LIBCALL_VALUE
    174 #define TARGET_LIBCALL_VALUE fr30_libcall_value
    175 #undef TARGET_FUNCTION_VALUE_REGNO_P
    176 #define TARGET_FUNCTION_VALUE_REGNO_P fr30_function_value_regno_p
    177 
    178 #undef  TARGET_SETUP_INCOMING_VARARGS
    179 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
    180 #undef  TARGET_MUST_PASS_IN_STACK
    181 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
    182 
    183 #undef TARGET_FRAME_POINTER_REQUIRED
    184 #define TARGET_FRAME_POINTER_REQUIRED fr30_frame_pointer_required
    185 
    186 #undef TARGET_CAN_ELIMINATE
    187 #define TARGET_CAN_ELIMINATE fr30_can_eliminate
    188 
    189 #undef TARGET_LRA_P
    190 #define TARGET_LRA_P hook_bool_void_false
    191 
    192 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
    193 #define TARGET_ASM_TRAMPOLINE_TEMPLATE fr30_asm_trampoline_template
    194 #undef TARGET_TRAMPOLINE_INIT
    195 #define TARGET_TRAMPOLINE_INIT fr30_trampoline_init
    196 
    197 #undef TARGET_CONSTANT_ALIGNMENT
    198 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
    199 
    200 #undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
    201 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
    202 
    203 struct gcc_target targetm = TARGET_INITIALIZER;
    204 
    205 
    207 /* Worker function for TARGET_CAN_ELIMINATE.  */
    208 
    209 bool
    210 fr30_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
    211 {
    212   return (to == FRAME_POINTER_REGNUM || ! frame_pointer_needed);
    213 }
    214 
    215 /* Returns the number of bytes offset between FROM_REG and TO_REG
    216    for the current function.  As a side effect it fills in the
    217    current_frame_info structure, if the data is available.  */
    218 unsigned int
    219 fr30_compute_frame_size (int from_reg, int to_reg)
    220 {
    221   int 		regno;
    222   unsigned int 	return_value;
    223   unsigned int	var_size;
    224   unsigned int	args_size;
    225   unsigned int	pretend_size;
    226   unsigned int 	reg_size;
    227   unsigned int 	gmask;
    228 
    229   var_size	= WORD_ALIGN (get_frame_size ());
    230   args_size	= WORD_ALIGN (crtl->outgoing_args_size);
    231   pretend_size	= crtl->args.pretend_args_size;
    232 
    233   reg_size	= 0;
    234   gmask		= 0;
    235 
    236   /* Calculate space needed for registers.  */
    237   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
    238     {
    239       if (MUST_SAVE_REGISTER (regno))
    240 	{
    241 	  reg_size += UNITS_PER_WORD;
    242 	  gmask |= 1 << regno;
    243 	}
    244     }
    245 
    246   current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
    247   current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
    248 
    249   reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
    250 	       * UNITS_PER_WORD;
    251 
    252   /* Save computed information.  */
    253   current_frame_info.pretend_size = pretend_size;
    254   current_frame_info.var_size     = var_size;
    255   current_frame_info.args_size    = args_size;
    256   current_frame_info.reg_size	  = reg_size;
    257   current_frame_info.frame_size   = args_size + var_size;
    258   current_frame_info.total_size   = args_size + var_size + reg_size + pretend_size;
    259   current_frame_info.gmask	  = gmask;
    260   current_frame_info.initialised  = reload_completed;
    261 
    262   /* Calculate the required distance.  */
    263   return_value = 0;
    264 
    265   if (to_reg == STACK_POINTER_REGNUM)
    266     return_value += args_size + var_size;
    267 
    268   if (from_reg == ARG_POINTER_REGNUM)
    269     return_value += reg_size;
    270 
    271   return return_value;
    272 }
    273 
    274 /* Called after register allocation to add any instructions needed for the
    275    prologue.  Using a prologue insn is favored compared to putting all of the
    276    instructions in output_function_prologue(), since it allows the scheduler
    277    to intermix instructions with the saves of the caller saved registers.  In
    278    some cases, it might be necessary to emit a barrier instruction as the last
    279    insn to prevent such scheduling.  */
    280 
    281 void
    282 fr30_expand_prologue (void)
    283 {
    284   int regno;
    285   rtx insn;
    286 
    287   if (! current_frame_info.initialised)
    288     fr30_compute_frame_size (0, 0);
    289 
    290   /* This cases shouldn't happen.  Catch it now.  */
    291   gcc_assert (current_frame_info.total_size || !current_frame_info.gmask);
    292 
    293   /* Allocate space for register arguments if this is a variadic function.  */
    294   if (current_frame_info.pretend_size)
    295     {
    296       int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
    297 
    298       /* Push argument registers into the pretend arg area.  */
    299       for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
    300         {
    301 	  insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
    302 	  RTX_FRAME_RELATED_P (insn) = 1;
    303 	}
    304     }
    305 
    306   if (current_frame_info.gmask)
    307     {
    308       /* Save any needed call-saved regs.  */
    309       for (regno = STACK_POINTER_REGNUM; regno--;)
    310 	{
    311 	  if ((current_frame_info.gmask & (1 << regno)) != 0)
    312 	    {
    313 	      insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
    314 	      RTX_FRAME_RELATED_P (insn) = 1;
    315 	    }
    316 	}
    317     }
    318 
    319   /* Save return address if necessary.  */
    320   if (current_frame_info.save_rp)
    321     {
    322       insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode,
    323       						     RETURN_POINTER_REGNUM)));
    324       RTX_FRAME_RELATED_P (insn) = 1;
    325     }
    326 
    327   /* Save old frame pointer and create new one, if necessary.  */
    328   if (current_frame_info.save_fp)
    329     {
    330       if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
    331         {
    332 	  int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
    333 	  rtx pattern;
    334 
    335 	  insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
    336           RTX_FRAME_RELATED_P (insn) = 1;
    337 
    338 	  pattern = PATTERN (insn);
    339 
    340 	  /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
    341           if (GET_CODE (pattern) == PARALLEL)
    342             {
    343               int x;
    344               for (x = XVECLEN (pattern, 0); x--;)
    345 		{
    346 		  rtx part = XVECEXP (pattern, 0, x);
    347 
    348 		  /* One of the insns in the ENTER pattern updates the
    349 		     frame pointer.  If we do not actually need the frame
    350 		     pointer in this function then this is a side effect
    351 		     rather than a desired effect, so we do not mark that
    352 		     insn as being related to the frame set up.  Doing this
    353 		     allows us to compile the crash66.C test file in the
    354 		     G++ testsuite.  */
    355 		  if (! frame_pointer_needed
    356 		      && GET_CODE (part) == SET
    357 		      && SET_DEST (part) == hard_frame_pointer_rtx)
    358 		    RTX_FRAME_RELATED_P (part) = 0;
    359 		  else
    360 		    RTX_FRAME_RELATED_P (part) = 1;
    361 		}
    362             }
    363 	}
    364       else
    365 	{
    366 	  insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
    367           RTX_FRAME_RELATED_P (insn) = 1;
    368 
    369 	  if (frame_pointer_needed)
    370 	    {
    371 	      insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
    372 	      RTX_FRAME_RELATED_P (insn) = 1;
    373 	    }
    374 	}
    375     }
    376 
    377   /* Allocate the stack frame.  */
    378   if (current_frame_info.frame_size == 0)
    379     ; /* Nothing to do.  */
    380   else if (current_frame_info.save_fp
    381 	   && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
    382     ; /* Nothing to do.  */
    383   else if (current_frame_info.frame_size <= 512)
    384     {
    385       insn = emit_insn (gen_add_to_stack
    386 			 (GEN_INT (- (signed) current_frame_info.frame_size)));
    387       RTX_FRAME_RELATED_P (insn) = 1;
    388     }
    389   else
    390     {
    391       rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
    392       insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
    393       RTX_FRAME_RELATED_P (insn) = 1;
    394       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
    395       RTX_FRAME_RELATED_P (insn) = 1;
    396     }
    397 
    398   if (crtl->profile)
    399     emit_insn (gen_blockage ());
    400 }
    401 
    402 /* Called after register allocation to add any instructions needed for the
    403    epilogue.  Using an epilogue insn is favored compared to putting all of the
    404    instructions in output_function_epilogue(), since it allows the scheduler
    405    to intermix instructions with the restores of the caller saved registers.
    406    In some cases, it might be necessary to emit a barrier instruction as the
    407    first insn to prevent such scheduling.  */
    408 void
    409 fr30_expand_epilogue (void)
    410 {
    411   int regno;
    412 
    413   /* Perform the inversion operations of the prologue.  */
    414   gcc_assert (current_frame_info.initialised);
    415 
    416   /* Pop local variables and arguments off the stack.
    417      If frame_pointer_needed is TRUE then the frame pointer register
    418      has actually been used as a frame pointer, and we can recover
    419      the stack pointer from it, otherwise we must unwind the stack
    420      manually.  */
    421   if (current_frame_info.frame_size > 0)
    422     {
    423       if (current_frame_info.save_fp && frame_pointer_needed)
    424 	{
    425 	  emit_insn (gen_leave_func ());
    426 	  current_frame_info.save_fp = 0;
    427 	}
    428       else if (current_frame_info.frame_size <= 508)
    429 	emit_insn (gen_add_to_stack
    430 		   (GEN_INT (current_frame_info.frame_size)));
    431       else
    432 	{
    433 	  rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
    434 	  emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
    435 	  emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
    436 	}
    437     }
    438 
    439   if (current_frame_info.save_fp)
    440     emit_insn (gen_movsi_pop (frame_pointer_rtx));
    441 
    442   /* Pop all the registers that were pushed.  */
    443   if (current_frame_info.save_rp)
    444     emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
    445 
    446   for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
    447     if (current_frame_info.gmask & (1 << regno))
    448       emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
    449 
    450   if (current_frame_info.pretend_size)
    451     emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
    452 
    453   /* Reset state info for each function.  */
    454   current_frame_info = zero_frame_info;
    455 
    456   emit_jump_insn (gen_return_from_func ());
    457 }
    458 
    459 /* Do any needed setup for a variadic function.  We must create a register
    460    parameter block, and then copy any anonymous arguments, plus the last
    461    named argument, from registers into memory.  * copying actually done in
    462    fr30_expand_prologue().
    463 
    464    CUM has not been updated for the last named argument which has type TYPE
    465    and mode MODE, and we rely on this fact.  */
    466 void
    467 fr30_setup_incoming_varargs (cumulative_args_t arg_regs_used_so_far_v,
    468 			     const function_arg_info &arg,
    469 			     int *pretend_size,
    470 			     int second_time ATTRIBUTE_UNUSED)
    471 {
    472   CUMULATIVE_ARGS *arg_regs_used_so_far
    473     = get_cumulative_args (arg_regs_used_so_far_v);
    474   int size;
    475 
    476   /* All BLKmode values are passed by reference.  */
    477   gcc_assert (arg.mode != BLKmode);
    478 
    479   /* ??? This run-time test as well as the code inside the if
    480      statement is probably unnecessary.  */
    481   if (targetm.calls.strict_argument_naming (arg_regs_used_so_far_v))
    482     /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
    483        arg must not be treated as an anonymous arg.  */
    484     /* ??? This is a pointer increment, which makes no sense.  */
    485     arg_regs_used_so_far += fr30_num_arg_regs (arg);
    486 
    487   size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
    488 
    489   if (size <= 0)
    490     return;
    491 
    492   * pretend_size = (size * UNITS_PER_WORD);
    493 }
    494 
    495 /*}}}*/
    496 /*{{{  Printing operands */
    497 
    498 /* Print a memory address as an operand to reference that memory location.  */
    499 
    500 void
    501 fr30_print_operand_address (FILE *stream, rtx address)
    502 {
    503   switch (GET_CODE (address))
    504     {
    505     case SYMBOL_REF:
    506       output_addr_const (stream, address);
    507       break;
    508 
    509     default:
    510       fprintf (stderr, "code = %x\n", GET_CODE (address));
    511       debug_rtx (address);
    512       output_operand_lossage ("fr30_print_operand_address: unhandled address");
    513       break;
    514     }
    515 }
    516 
    517 /* Print an operand.  */
    518 
    519 void
    520 fr30_print_operand (FILE *file, rtx x, int code)
    521 {
    522   rtx x0;
    523 
    524   switch (code)
    525     {
    526     case '#':
    527       /* Output a :D if this instruction is delayed.  */
    528       if (dbr_sequence_length () != 0)
    529 	fputs (":D", file);
    530       return;
    531 
    532     case 'p':
    533       /* Compute the register name of the second register in a hi/lo
    534 	 register pair.  */
    535       if (GET_CODE (x) != REG)
    536 	output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
    537       else
    538 	fprintf (file, "r%d", REGNO (x) + 1);
    539       return;
    540 
    541     case 'b':
    542       /* Convert GCC's comparison operators into FR30 comparison codes.  */
    543       switch (GET_CODE (x))
    544 	{
    545 	case EQ:  fprintf (file, "eq"); break;
    546 	case NE:  fprintf (file, "ne"); break;
    547 	case LT:  fprintf (file, "lt"); break;
    548 	case LE:  fprintf (file, "le"); break;
    549 	case GT:  fprintf (file, "gt"); break;
    550 	case GE:  fprintf (file, "ge"); break;
    551 	case LTU: fprintf (file, "c"); break;
    552 	case LEU: fprintf (file, "ls"); break;
    553 	case GTU: fprintf (file, "hi"); break;
    554 	case GEU: fprintf (file, "nc");  break;
    555 	default:
    556 	  output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
    557 	  break;
    558 	}
    559       return;
    560 
    561     case 'B':
    562       /* Convert GCC's comparison operators into the complimentary FR30
    563 	 comparison codes.  */
    564       switch (GET_CODE (x))
    565 	{
    566 	case EQ:  fprintf (file, "ne"); break;
    567 	case NE:  fprintf (file, "eq"); break;
    568 	case LT:  fprintf (file, "ge"); break;
    569 	case LE:  fprintf (file, "gt"); break;
    570 	case GT:  fprintf (file, "le"); break;
    571 	case GE:  fprintf (file, "lt"); break;
    572 	case LTU: fprintf (file, "nc"); break;
    573 	case LEU: fprintf (file, "hi"); break;
    574 	case GTU: fprintf (file, "ls"); break;
    575 	case GEU: fprintf (file, "c"); break;
    576 	default:
    577 	  output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
    578 	  break;
    579 	}
    580       return;
    581 
    582     case 'A':
    583       /* Print a signed byte value as an unsigned value.  */
    584       if (GET_CODE (x) != CONST_INT)
    585 	output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
    586       else
    587 	{
    588 	  HOST_WIDE_INT val;
    589 
    590 	  val = INTVAL (x);
    591 
    592 	  val &= 0xff;
    593 
    594 	  fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
    595 	}
    596       return;
    597 
    598     case 'x':
    599       if (GET_CODE (x) != CONST_INT
    600 	  || INTVAL (x) < 16
    601 	  || INTVAL (x) > 32)
    602 	output_operand_lossage ("fr30_print_operand: invalid %%x code");
    603       else
    604 	fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
    605       return;
    606 
    607     case 'F':
    608       if (GET_CODE (x) != CONST_DOUBLE)
    609 	output_operand_lossage ("fr30_print_operand: invalid %%F code");
    610       else
    611 	{
    612 	  char str[30];
    613 
    614 	  real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
    615 			   sizeof (str), 0, 1);
    616 	  fputs (str, file);
    617 	}
    618       return;
    619 
    620     case 0:
    621       /* Handled below.  */
    622       break;
    623 
    624     default:
    625       fprintf (stderr, "unknown code = %x\n", code);
    626       output_operand_lossage ("fr30_print_operand: unknown code");
    627       return;
    628     }
    629 
    630   switch (GET_CODE (x))
    631     {
    632     case REG:
    633       fputs (reg_names [REGNO (x)], file);
    634       break;
    635 
    636     case MEM:
    637       x0 = XEXP (x,0);
    638 
    639       switch (GET_CODE (x0))
    640 	{
    641 	case REG:
    642 	  gcc_assert ((unsigned) REGNO (x0) < ARRAY_SIZE (reg_names));
    643 	  fprintf (file, "@%s", reg_names [REGNO (x0)]);
    644 	  break;
    645 
    646 	case PLUS:
    647 	  if (GET_CODE (XEXP (x0, 0)) != REG
    648 	      || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
    649 	      || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
    650 	      || GET_CODE (XEXP (x0, 1)) != CONST_INT)
    651 	    {
    652 	      fprintf (stderr, "bad INDEXed address:");
    653 	      debug_rtx (x);
    654 	      output_operand_lossage ("fr30_print_operand: unhandled MEM");
    655 	    }
    656 	  else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
    657 	    {
    658 	      HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
    659 	      if (val < -(1 << 9) || val > ((1 << 9) - 4))
    660 		{
    661 		  fprintf (stderr, "frame INDEX out of range:");
    662 		  debug_rtx (x);
    663 		  output_operand_lossage ("fr30_print_operand: unhandled MEM");
    664 		}
    665 	      fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
    666 	    }
    667 	  else
    668 	    {
    669 	      HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
    670 	      if (val < 0 || val > ((1 << 6) - 4))
    671 		{
    672 		  fprintf (stderr, "stack INDEX out of range:");
    673 		  debug_rtx (x);
    674 		  output_operand_lossage ("fr30_print_operand: unhandled MEM");
    675 		}
    676 	      fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
    677 	    }
    678 	  break;
    679 
    680 	case SYMBOL_REF:
    681 	  output_address (VOIDmode, x0);
    682 	  break;
    683 
    684 	default:
    685 	  fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
    686 	  debug_rtx (x);
    687 	  output_operand_lossage ("fr30_print_operand: unhandled MEM");
    688 	  break;
    689 	}
    690       break;
    691 
    692     case CONST_DOUBLE :
    693       /* We handle SFmode constants here as output_addr_const doesn't.  */
    694       if (GET_MODE (x) == SFmode)
    695 	{
    696 	  long l;
    697 
    698 	  REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
    699 	  fprintf (file, "0x%08lx", l);
    700 	  break;
    701 	}
    702 
    703       /* FALLTHRU */
    704       /* Let output_addr_const deal with it.  */
    705     default:
    706       output_addr_const (file, x);
    707       break;
    708     }
    709 
    710   return;
    711 }
    712 
    713 /*}}}*/
    714 
    715 /* Implements TARGET_FUNCTION_VALUE.  */
    716 
    717 static rtx
    718 fr30_function_value (const_tree valtype,
    719 		     const_tree fntype_or_decli ATTRIBUTE_UNUSED,
    720 		     bool outgoing ATTRIBUTE_UNUSED)
    721 {
    722   return gen_rtx_REG (TYPE_MODE (valtype), RETURN_VALUE_REGNUM);
    723 }
    724 
    725 /* Implements TARGET_LIBCALL_VALUE.  */
    726 
    727 static rtx
    728 fr30_libcall_value (machine_mode mode,
    729 		    const_rtx fun ATTRIBUTE_UNUSED)
    730 {
    731   return gen_rtx_REG (mode, RETURN_VALUE_REGNUM);
    732 }
    733 
    734 /* Implements TARGET_FUNCTION_VALUE_REGNO_P.  */
    735 
    736 static bool
    737 fr30_function_value_regno_p (const unsigned int regno)
    738 {
    739   return (regno == RETURN_VALUE_REGNUM);
    740 }
    741 
    742 /*{{{  Function arguments */
    743 
    744 /* Return true if we should pass an argument on the stack rather than
    745    in registers.  */
    746 
    747 static bool
    748 fr30_must_pass_in_stack (const function_arg_info &arg)
    749 {
    750   return arg.mode == BLKmode || arg.aggregate_type_p ();
    751 }
    752 
    753 /* Compute the number of word sized registers needed to hold function
    754    argument ARG.  */
    755 static int
    756 fr30_num_arg_regs (const function_arg_info &arg)
    757 {
    758   if (targetm.calls.must_pass_in_stack (arg))
    759     return 0;
    760 
    761   int size = arg.promoted_size_in_bytes ();
    762   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
    763 }
    764 
    765 /* Returns the number of bytes of argument registers required to hold *part*
    766    of argument ARG.  If the argument fits entirely in the argument registers,
    767    or entirely on the stack, then 0 is returned.  CUM is the number of
    768    argument registers already used by earlier parameters to the function.  */
    769 
    770 static int
    771 fr30_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
    772 {
    773   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    774 
    775   /* Unnamed arguments, i.e. those that are prototyped as ...
    776      are always passed on the stack.
    777      Also check here to see if all the argument registers are full.  */
    778   if (!arg.named || *cum >= FR30_NUM_ARG_REGS)
    779     return 0;
    780 
    781   /* Work out how many argument registers would be needed if this
    782      parameter were to be passed entirely in registers.  If there
    783      are sufficient argument registers available (or if no registers
    784      are needed because the parameter must be passed on the stack)
    785      then return zero, as this parameter does not require partial
    786      register, partial stack space.  */
    787   if (*cum + fr30_num_arg_regs (arg) <= FR30_NUM_ARG_REGS)
    788     return 0;
    789 
    790   return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
    791 }
    792 
    793 static rtx
    794 fr30_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
    795 {
    796   CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
    797 
    798   if (!arg.named
    799       || fr30_must_pass_in_stack (arg)
    800       || *cum >= FR30_NUM_ARG_REGS)
    801     return NULL_RTX;
    802   else
    803     return gen_rtx_REG (arg.mode, *cum + FIRST_ARG_REGNUM);
    804 }
    805 
    806 /* Implement TARGET_FUNCTION_ARG_ADVANCE.  */
    807 static void
    808 fr30_function_arg_advance (cumulative_args_t cum,
    809 			   const function_arg_info &arg)
    810 {
    811   if (arg.named)
    812     *get_cumulative_args (cum) += fr30_num_arg_regs (arg);
    813 }
    814 
    815 /*}}}*/
    816 /*{{{  Operand predicates */
    817 
    818 #ifndef Mmode
    819 #define Mmode machine_mode
    820 #endif
    821 
    822 /* Returns true iff all the registers in the operands array
    823    are in descending or ascending order.  */
    824 int
    825 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
    826 {
    827   if (descending)
    828     {
    829       unsigned int prev_regno = 0;
    830 
    831       while (num_operands --)
    832 	{
    833 	  if (GET_CODE (operands [num_operands]) != REG)
    834 	    return 0;
    835 
    836 	  if (REGNO (operands [num_operands]) < prev_regno)
    837 	    return 0;
    838 
    839 	  prev_regno = REGNO (operands [num_operands]);
    840 	}
    841     }
    842   else
    843     {
    844       unsigned int prev_regno = CONDITION_CODE_REGNUM;
    845 
    846       while (num_operands --)
    847 	{
    848 	  if (GET_CODE (operands [num_operands]) != REG)
    849 	    return 0;
    850 
    851 	  if (REGNO (operands [num_operands]) > prev_regno)
    852 	    return 0;
    853 
    854 	  prev_regno = REGNO (operands [num_operands]);
    855 	}
    856     }
    857 
    858   return 1;
    859 }
    860 
    861 int
    862 fr30_const_double_is_zero (rtx operand)
    863 {
    864   if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
    865     return 0;
    866 
    867   return real_equal (CONST_DOUBLE_REAL_VALUE (operand), &dconst0);
    868 }
    869 
    870 /*}}}*/
    871 /*{{{  Instruction Output Routines  */
    872 
    873 /* Output a double word move.
    874    It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
    875    On the FR30 we are constrained by the fact that it does not
    876    support offsetable addresses, and so we have to load the
    877    address of the secnd word into the second destination register
    878    before we can use it.  */
    879 
    880 rtx
    881 fr30_move_double (rtx * operands)
    882 {
    883   rtx src  = operands[1];
    884   rtx dest = operands[0];
    885   enum rtx_code src_code = GET_CODE (src);
    886   enum rtx_code dest_code = GET_CODE (dest);
    887   machine_mode mode = GET_MODE (dest);
    888   rtx val;
    889 
    890   start_sequence ();
    891 
    892   if (dest_code == REG)
    893     {
    894       if (src_code == REG)
    895 	{
    896 	  int reverse = (REGNO (dest) == REGNO (src) + 1);
    897 
    898 	  /* We normally copy the low-numbered register first.  However, if
    899 	     the first register of operand 0 is the same as the second register
    900 	     of operand 1, we must copy in the opposite order.  */
    901 	  emit_insn (gen_rtx_SET (operand_subword (dest, reverse, TRUE, mode),
    902 				  operand_subword (src,  reverse, TRUE, mode)));
    903 
    904 	  emit_insn
    905 	    (gen_rtx_SET (operand_subword (dest, !reverse, TRUE, mode),
    906 			  operand_subword (src,  !reverse, TRUE, mode)));
    907 	}
    908       else if (src_code == MEM)
    909 	{
    910 	  rtx addr = XEXP (src, 0);
    911 	  rtx dest0 = operand_subword (dest, 0, TRUE, mode);
    912 	  rtx dest1 = operand_subword (dest, 1, TRUE, mode);
    913 	  rtx new_mem;
    914 
    915 	  gcc_assert (GET_CODE (addr) == REG);
    916 
    917 	  /* Copy the address before clobbering it.  See PR 34174.  */
    918 	  emit_insn (gen_rtx_SET (dest1, addr));
    919 	  emit_insn (gen_rtx_SET (dest0, adjust_address (src, SImode, 0)));
    920 	  emit_insn (gen_rtx_SET (dest1, plus_constant (SImode, dest1,
    921 							UNITS_PER_WORD)));
    922 
    923 	  new_mem = gen_rtx_MEM (SImode, dest1);
    924 	  MEM_COPY_ATTRIBUTES (new_mem, src);
    925 
    926 	  emit_insn (gen_rtx_SET (dest1, new_mem));
    927 	}
    928       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
    929 	{
    930 	  rtx words[2];
    931 	  split_double (src, &words[0], &words[1]);
    932 	  emit_insn (gen_rtx_SET (operand_subword (dest, 0, TRUE, mode),
    933 				  words[0]));
    934 
    935 	  emit_insn (gen_rtx_SET (operand_subword (dest, 1, TRUE, mode),
    936 				  words[1]));
    937 	}
    938     }
    939   else if (src_code == REG && dest_code == MEM)
    940     {
    941       rtx addr = XEXP (dest, 0);
    942       rtx src0;
    943       rtx src1;
    944 
    945       gcc_assert (GET_CODE (addr) == REG);
    946 
    947       src0 = operand_subword (src, 0, TRUE, mode);
    948       src1 = operand_subword (src, 1, TRUE, mode);
    949 
    950       emit_move_insn (adjust_address (dest, SImode, 0), src0);
    951 
    952       if (REGNO (addr) == STACK_POINTER_REGNUM
    953 	  || REGNO (addr) == FRAME_POINTER_REGNUM)
    954 	emit_insn (gen_rtx_SET (adjust_address (dest, SImode, UNITS_PER_WORD),
    955 				src1));
    956       else
    957 	{
    958 	  rtx new_mem;
    959 	  rtx scratch_reg_r0 = gen_rtx_REG (SImode, 0);
    960 
    961 	  /* We need a scratch register to hold the value of 'address + 4'.
    962 	     We use r0 for this purpose. It is used for example for long
    963 	     jumps and is already marked to not be used by normal register
    964 	     allocation.  */
    965 	  emit_insn (gen_movsi_internal (scratch_reg_r0, addr));
    966 	  emit_insn (gen_addsi_small_int (scratch_reg_r0, scratch_reg_r0,
    967 					  GEN_INT (UNITS_PER_WORD)));
    968 	  new_mem = gen_rtx_MEM (SImode, scratch_reg_r0);
    969 	  MEM_COPY_ATTRIBUTES (new_mem, dest);
    970 	  emit_move_insn (new_mem, src1);
    971 	  emit_insn (gen_blockage ());
    972 	}
    973     }
    974   else
    975     /* This should have been prevented by the constraints on movdi_insn.  */
    976     gcc_unreachable ();
    977 
    978   val = get_insns ();
    979   end_sequence ();
    980 
    981   return val;
    982 }
    983 
    984 /* Implement TARGET_FRAME_POINTER_REQUIRED.  */
    985 
    986 bool
    987 fr30_frame_pointer_required (void)
    988 {
    989   return (flag_omit_frame_pointer == 0 || crtl->args.pretend_args_size > 0);
    990 }
    991 
    992 /*}}}*/
    993 /*{{{  Trampoline Output Routines  */
    994 
    995 /* Implement TARGET_ASM_TRAMPOLINE_TEMPLATE.
    996    On the FR30, the trampoline is:
    997 
    998    nop
    999    ldi:32 STATIC, r12
   1000    nop
   1001    ldi:32 FUNCTION, r0
   1002    jmp    @r0
   1003 
   1004    The no-ops are to guarantee that the static chain and final
   1005    target are 32 bit aligned within the trampoline.  That allows us to
   1006    initialize those locations with simple SImode stores.   The alternative
   1007    would be to use HImode stores.  */
   1008 
   1009 static void
   1010 fr30_asm_trampoline_template (FILE *f)
   1011 {
   1012   fprintf (f, "\tnop\n");
   1013   fprintf (f, "\tldi:32\t#0, %s\n", reg_names [STATIC_CHAIN_REGNUM]);
   1014   fprintf (f, "\tnop\n");
   1015   fprintf (f, "\tldi:32\t#0, %s\n", reg_names [COMPILER_SCRATCH_REGISTER]);
   1016   fprintf (f, "\tjmp\t@%s\n", reg_names [COMPILER_SCRATCH_REGISTER]);
   1017 }
   1018 
   1019 /* Implement TARGET_TRAMPOLINE_INIT.  */
   1020 
   1021 static void
   1022 fr30_trampoline_init (rtx m_tramp, tree fndecl, rtx chain_value)
   1023 {
   1024   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
   1025   rtx mem;
   1026 
   1027   emit_block_move (m_tramp, assemble_trampoline_template (),
   1028 		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
   1029 
   1030   mem = adjust_address (m_tramp, SImode, 4);
   1031   emit_move_insn (mem, chain_value);
   1032   mem = adjust_address (m_tramp, SImode, 12);
   1033   emit_move_insn (mem, fnaddr);
   1034 }
   1035 
   1036 /*}}}*/
   1037 /* Local Variables: */
   1038 /* folded-file: t   */
   1039 /* End:		    */
   1040