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