OSDN Git Service

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