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