OSDN Git Service

* target-def.h (TARGET_MUST_PASS_IN_STACK): New.
[pf3gnuchains/gcc-fork.git] / gcc / config / fr30 / fr30.c
1 /* FR30 specific functions.
2    Copyright (C) 1998, 1999, 2000, 2001, 2002, 2004
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, 59 Temple Place - Suite 330,
21    Boston, MA 02111-1307, 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 tree fr30_gimplify_va_arg_expr (tree, tree, tree *, tree *);
127 static bool fr30_must_pass_in_stack (enum machine_mode, tree);
128
129 #define FRAME_POINTER_MASK      (1 << (FRAME_POINTER_REGNUM))
130 #define RETURN_POINTER_MASK     (1 << (RETURN_POINTER_REGNUM))
131
132 /* Tell prologue and epilogue if register REGNO should be saved / restored.
133    The return address and frame pointer are treated separately.
134    Don't consider them here.  */
135 #define MUST_SAVE_REGISTER(regno)      \
136   (   (regno) != RETURN_POINTER_REGNUM \
137    && (regno) != FRAME_POINTER_REGNUM  \
138    &&   regs_ever_live [regno]         \
139    && ! call_used_regs [regno]         )
140
141 #define MUST_SAVE_FRAME_POINTER  (regs_ever_live [FRAME_POINTER_REGNUM]  || frame_pointer_needed)
142 #define MUST_SAVE_RETURN_POINTER (regs_ever_live [RETURN_POINTER_REGNUM] || current_function_profile)
143
144 #if UNITS_PER_WORD == 4
145 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
146 #endif
147 \f
148 /* Initialize the GCC target structure.  */
149 #undef  TARGET_ASM_ALIGNED_HI_OP
150 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
151 #undef  TARGET_ASM_ALIGNED_SI_OP
152 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
153
154 #undef  TARGET_PROMOTE_PROTOTYPES
155 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
156 #undef  TARGET_SETUP_INCOMING_VARARGS
157 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
158 #undef  TARGET_MUST_PASS_IN_STACK
159 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
160
161 #undef  TARGET_GIMPLIFY_VA_ARG_EXPR
162 #define TARGET_GIMPLIFY_VA_ARG_EXPR fr30_gimplify_va_arg_expr
163
164 struct gcc_target targetm = TARGET_INITIALIZER;
165 \f
166 /* Returns the number of bytes offset between FROM_REG and TO_REG
167    for the current function.  As a side effect it fills in the 
168    current_frame_info structure, if the data is available.  */
169 unsigned int
170 fr30_compute_frame_size (int from_reg, int to_reg)
171 {
172   int           regno;
173   unsigned int  return_value;
174   unsigned int  var_size;
175   unsigned int  args_size;
176   unsigned int  pretend_size;
177   unsigned int  reg_size;
178   unsigned int  gmask;
179
180   var_size      = WORD_ALIGN (get_frame_size ());
181   args_size     = WORD_ALIGN (current_function_outgoing_args_size);
182   pretend_size  = current_function_pretend_args_size;
183
184   reg_size      = 0;
185   gmask         = 0;
186
187   /* Calculate space needed for registers.  */
188   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
189     {
190       if (MUST_SAVE_REGISTER (regno))
191         {
192           reg_size += UNITS_PER_WORD;
193           gmask |= 1 << regno;
194         }
195     }
196
197   current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
198   current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
199
200   reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
201                * UNITS_PER_WORD;
202
203   /* Save computed information.  */
204   current_frame_info.pretend_size = pretend_size;
205   current_frame_info.var_size     = var_size;
206   current_frame_info.args_size    = args_size;
207   current_frame_info.reg_size     = reg_size;
208   current_frame_info.frame_size   = args_size + var_size;
209   current_frame_info.total_size   = args_size + var_size + reg_size + pretend_size;
210   current_frame_info.gmask        = gmask;
211   current_frame_info.initialised  = reload_completed;
212
213   /* Calculate the required distance.  */
214   return_value = 0;
215   
216   if (to_reg == STACK_POINTER_REGNUM)
217     return_value += args_size + var_size;
218   
219   if (from_reg == ARG_POINTER_REGNUM)
220     return_value += reg_size;
221
222   return return_value;
223 }
224
225 /* Called after register allocation to add any instructions needed for the
226    prologue.  Using a prologue insn is favored compared to putting all of the
227    instructions in output_function_prologue(), since it allows the scheduler
228    to intermix instructions with the saves of the caller saved registers.  In
229    some cases, it might be necessary to emit a barrier instruction as the last
230    insn to prevent such scheduling.  */
231
232 void
233 fr30_expand_prologue (void)
234 {
235   int regno;
236   rtx insn;
237
238   if (! current_frame_info.initialised)
239     fr30_compute_frame_size (0, 0);
240
241   /* This cases shouldn't happen.  Catch it now.  */
242   if (current_frame_info.total_size == 0
243       && current_frame_info.gmask)
244     abort ();
245
246   /* Allocate space for register arguments if this is a variadic function.  */
247   if (current_frame_info.pretend_size)
248     {
249       int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
250       
251       /* Push argument registers into the pretend arg area.  */
252       for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
253         {
254           insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
255           RTX_FRAME_RELATED_P (insn) = 1;
256         }
257     }
258
259   if (current_frame_info.gmask)
260     {
261       /* Save any needed call-saved regs.  */
262       for (regno = STACK_POINTER_REGNUM; regno--;)
263         {
264           if ((current_frame_info.gmask & (1 << regno)) != 0)
265             {
266               insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
267               RTX_FRAME_RELATED_P (insn) = 1;
268             }
269         }
270     }
271
272   /* Save return address if necessary.  */
273   if (current_frame_info.save_rp)
274     {
275       insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, 
276                                                      RETURN_POINTER_REGNUM)));
277       RTX_FRAME_RELATED_P (insn) = 1;
278     }
279
280   /* Save old frame pointer and create new one, if necessary.  */
281   if (current_frame_info.save_fp)
282     {
283       if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
284         {
285           int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
286           rtx pattern;
287           
288           insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
289           RTX_FRAME_RELATED_P (insn) = 1;
290           
291           pattern = PATTERN (insn);
292           
293           /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
294           if (GET_CODE (pattern) == PARALLEL)
295             {
296               int x;
297               for (x = XVECLEN (pattern, 0); x--;)
298                 {
299                   rtx part = XVECEXP (pattern, 0, x);
300                   
301                   /* One of the insns in the ENTER pattern updates the
302                      frame pointer.  If we do not actually need the frame
303                      pointer in this function then this is a side effect
304                      rather than a desired effect, so we do not mark that
305                      insn as being related to the frame set up.  Doing this
306                      allows us to compile the crash66.C test file in the
307                      G++ testsuite.  */
308                   if (! frame_pointer_needed
309                       && GET_CODE (part) == SET
310                       && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM)
311                     RTX_FRAME_RELATED_P (part) = 0;
312                   else
313                     RTX_FRAME_RELATED_P (part) = 1;
314                 }
315             }
316         }
317       else
318         {
319           insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
320           RTX_FRAME_RELATED_P (insn) = 1;
321
322           if (frame_pointer_needed)
323             {
324               insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
325               RTX_FRAME_RELATED_P (insn) = 1;
326             }
327         }
328     }
329
330   /* Allocate the stack frame.  */
331   if (current_frame_info.frame_size == 0)
332     ; /* Nothing to do.  */
333   else if (current_frame_info.save_fp
334            && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
335     ; /* Nothing to do.  */
336   else if (current_frame_info.frame_size <= 512)
337     {
338       insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size)));
339       RTX_FRAME_RELATED_P (insn) = 1;
340     }
341   else
342     {
343       rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
344       insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
345       RTX_FRAME_RELATED_P (insn) = 1;
346       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
347       RTX_FRAME_RELATED_P (insn) = 1;
348     }
349
350   if (current_function_profile)
351     emit_insn (gen_blockage ());
352 }
353
354 /* Called after register allocation to add any instructions needed for the
355    epilogue.  Using an epilogue insn is favored compared to putting all of the
356    instructions in output_function_epilogue(), since it allows the scheduler
357    to intermix instructions with the restores of the caller saved registers.
358    In some cases, it might be necessary to emit a barrier instruction as the
359    first insn to prevent such scheduling.  */
360 void
361 fr30_expand_epilogue (void)
362 {
363   int regno;
364
365   /* Perform the inversion operations of the prologue.  */
366   if (! current_frame_info.initialised)
367     abort ();
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   if (mode == BLKmode)
430     abort ();
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           if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
595             abort ();
596           fprintf (file, "@%s", reg_names [REGNO (x0)]);
597           break;
598
599         case PLUS:
600           if (GET_CODE (XEXP (x0, 0)) != REG
601               || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
602               || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
603               || GET_CODE (XEXP (x0, 1)) != CONST_INT)
604             {
605               fprintf (stderr, "bad INDEXed address:");
606               debug_rtx (x);
607               output_operand_lossage ("fr30_print_operand: unhandled MEM");
608             }
609           else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
610             {
611               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
612               if (val < -(1 << 9) || val > ((1 << 9) - 4))
613                 {
614                   fprintf (stderr, "frame INDEX out of range:");
615                   debug_rtx (x);
616                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
617                 }
618               fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
619             }
620           else
621             {
622               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
623               if (val < 0 || val > ((1 << 6) - 4))
624                 {
625                   fprintf (stderr, "stack INDEX out of range:");
626                   debug_rtx (x);
627                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
628                 }
629               fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
630             }
631           break;
632           
633         case SYMBOL_REF:
634           output_address (x0);
635           break;
636           
637         default:
638           fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
639           debug_rtx (x);
640           output_operand_lossage ("fr30_print_operand: unhandled MEM");
641           break;
642         }
643       break;
644       
645     case CONST_DOUBLE :
646       /* We handle SFmode constants here as output_addr_const doesn't.  */
647       if (GET_MODE (x) == SFmode)
648         {
649           REAL_VALUE_TYPE d;
650           long l;
651
652           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
653           REAL_VALUE_TO_TARGET_SINGLE (d, l);
654           fprintf (file, "0x%08lx", l);
655           break;
656         }
657
658       /* Fall through.  Let output_addr_const deal with it.  */
659     default:
660       output_addr_const (file, x);
661       break;
662     }
663
664   return;
665 }
666
667 /*}}}*/
668 /*{{{  Function arguments */ 
669
670 /* Return true if we should pass an argument on the stack rather than
671    in registers.  */
672
673 static bool
674 fr30_must_pass_in_stack (enum machine_mode mode, tree type)
675 {
676   if (mode == BLKmode)
677     return true;
678   if (type == NULL)
679     return false;
680   return AGGREGATE_TYPE_P (type);
681 }
682
683 /* Compute the number of word sized registers needed to hold a
684    function argument of mode INT_MODE and tree type TYPE.  */
685 int
686 fr30_num_arg_regs (enum machine_mode mode, tree type)
687 {
688   int size;
689
690   if (targetm.calls.must_pass_in_stack (mode, type))
691     return 0;
692
693   if (type && mode == BLKmode)
694     size = int_size_in_bytes (type);
695   else
696     size = GET_MODE_SIZE (mode);
697
698   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
699 }
700
701 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
702    Returns the number of argument registers required to hold *part* of
703    a parameter of machine mode MODE and tree type TYPE (which may be
704    NULL if the type is not known).  If the argument fits entirely in
705    the argument registers, or entirely on the stack, then 0 is returned.
706    CUM is the number of argument registers already used by earlier
707    parameters to the function.  */
708
709 int
710 fr30_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
711                                  tree type, int named)
712 {
713   /* Unnamed arguments, ie those that are prototyped as ...
714      are always passed on the stack.
715      Also check here to see if all the argument registers are full.  */
716   if (named == 0 || cum >= FR30_NUM_ARG_REGS)
717     return 0;
718
719   /* Work out how many argument registers would be needed if this
720      parameter were to be passed entirely in registers.  If there
721      are sufficient argument registers available (or if no registers
722      are needed because the parameter must be passed on the stack)
723      then return zero, as this parameter does not require partial
724      register, partial stack stack space.  */
725   if (cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
726     return 0;
727   
728   /* Otherwise return the number of registers that would be used.  */
729   return FR30_NUM_ARG_REGS - cum;
730 }
731
732 /* Implement `va_arg'.  */
733
734 static tree
735 fr30_gimplify_va_arg_expr (tree valist, tree type, tree *pre_p, tree *post_p)
736 {
737   if (FUNCTION_ARG_PASS_BY_REFERENCE (dummy, TYPE_MODE (type), type, dummy))
738     return ind_gimplify_va_arg_expr (valist, type, pre_p, post_p);
739   else
740     return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
741 }
742
743 /*}}}*/
744 /*{{{  Operand predicates */ 
745
746 #ifndef Mmode
747 #define Mmode enum machine_mode
748 #endif
749
750 /* Returns true if OPERAND is an integer value suitable for use in
751    an ADDSP instruction.  */
752 int
753 stack_add_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
754 {
755   return
756     (GET_CODE (operand) == CONST_INT
757      && INTVAL (operand) >= -512
758      && INTVAL (operand) <=  508
759      && ((INTVAL (operand) & 3) == 0));
760 }
761
762 /* Returns true if OPERAND is an integer value suitable for use in
763    an ADD por ADD2 instruction, or if it is a register.  */
764 int
765 add_immediate_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
766 {
767   return
768     (GET_CODE (operand) == REG
769      || (GET_CODE (operand) == CONST_INT
770          && INTVAL (operand) >= -16
771          && INTVAL (operand) <=  15));
772 }
773
774 /* Returns true if OPERAND is hard register in the range 8 - 15.  */
775 int
776 high_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
777 {
778   return
779     (GET_CODE (operand) == REG
780      && REGNO (operand) <= 15
781      && REGNO (operand) >= 8);
782 }
783
784 /* Returns true if OPERAND is hard register in the range 0 - 7.  */
785 int
786 low_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
787 {
788   return
789     (GET_CODE (operand) == REG
790      && REGNO (operand) <= 7);
791 }
792
793 /* Returns true if OPERAND is suitable for use in a CALL insn.  */
794 int
795 call_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
796 {
797   return (GET_CODE (operand) == MEM
798           && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
799               || GET_CODE (XEXP (operand, 0)) == REG));
800 }
801
802 /* Returns TRUE if OP is a valid operand of a DImode operation.  */
803 int
804 di_operand (rtx op, Mmode mode)
805 {
806   if (register_operand (op, mode))
807     return TRUE;
808
809   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
810     return FALSE;
811
812   if (GET_CODE (op) == SUBREG)
813     op = SUBREG_REG (op);
814
815   switch (GET_CODE (op))
816     {
817     case CONST_DOUBLE:
818     case CONST_INT:
819       return TRUE;
820
821     case MEM:
822       return memory_address_p (DImode, XEXP (op, 0));
823
824     default:
825       return FALSE;
826     }
827 }
828
829 /* Returns TRUE if OP is a DImode register or MEM.  */
830 int
831 nonimmediate_di_operand (rtx op, Mmode mode)
832 {
833   if (register_operand (op, mode))
834     return TRUE;
835
836   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
837     return FALSE;
838
839   if (GET_CODE (op) == SUBREG)
840     op = SUBREG_REG (op);
841
842   if (GET_CODE (op) == MEM)
843     return memory_address_p (DImode, XEXP (op, 0));
844
845   return FALSE;
846 }
847
848 /* Returns true iff all the registers in the operands array
849    are in descending or ascending order.  */
850 int
851 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
852 {
853   if (descending)
854     {
855       unsigned int prev_regno = 0;
856       
857       while (num_operands --)
858         {
859           if (GET_CODE (operands [num_operands]) != REG)
860             return 0;
861           
862           if (REGNO (operands [num_operands]) < prev_regno)
863             return 0;
864           
865           prev_regno = REGNO (operands [num_operands]);
866         }
867     }
868   else
869     {
870       unsigned int prev_regno = CONDITION_CODE_REGNUM;
871       
872       while (num_operands --)
873         {
874           if (GET_CODE (operands [num_operands]) != REG)
875             return 0;
876           
877           if (REGNO (operands [num_operands]) > prev_regno)
878             return 0;
879           
880           prev_regno = REGNO (operands [num_operands]);
881         }
882     }
883
884   return 1;
885 }
886
887 int
888 fr30_const_double_is_zero (rtx operand)
889 {
890   REAL_VALUE_TYPE d;
891
892   if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
893     return 0;
894
895   REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
896
897   return REAL_VALUES_EQUAL (d, dconst0);
898 }
899
900 /*}}}*/
901 /*{{{  Instruction Output Routines  */
902
903 /* Output a double word move.
904    It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
905    On the FR30 we are constrained by the fact that it does not
906    support offsetable addresses, and so we have to load the
907    address of the secnd word into the second destination register
908    before we can use it.  */
909
910 rtx
911 fr30_move_double (rtx * operands)
912 {
913   rtx src  = operands[1];
914   rtx dest = operands[0];
915   enum rtx_code src_code = GET_CODE (src);
916   enum rtx_code dest_code = GET_CODE (dest);
917   enum machine_mode mode = GET_MODE (dest);
918   rtx val;
919
920   start_sequence ();
921
922   if (dest_code == REG)
923     {
924       if (src_code == REG)
925         {
926           int reverse = (REGNO (dest) == REGNO (src) + 1);
927           
928           /* We normally copy the low-numbered register first.  However, if
929              the first register of operand 0 is the same as the second register
930              of operand 1, we must copy in the opposite order.  */
931           emit_insn (gen_rtx_SET (VOIDmode,
932                                   operand_subword (dest, reverse, TRUE, mode),
933                                   operand_subword (src,  reverse, TRUE, mode)));
934           
935           emit_insn (gen_rtx_SET (VOIDmode,
936                               operand_subword (dest, !reverse, TRUE, mode),
937                               operand_subword (src,  !reverse, TRUE, mode)));
938         }
939       else if (src_code == MEM)
940         {
941           rtx addr = XEXP (src, 0);
942           int dregno = REGNO (dest);
943           rtx dest0;
944           rtx dest1;
945           rtx new_mem;
946           
947           /* If the high-address word is used in the address, we
948              must load it last.  Otherwise, load it first.  */
949           int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
950
951           if (GET_CODE (addr) != REG)
952             abort ();
953           
954           dest0 = operand_subword (dest, reverse, TRUE, mode);
955           dest1 = operand_subword (dest, !reverse, TRUE, mode);
956
957           if (reverse)
958             {
959               emit_insn (gen_rtx_SET (VOIDmode, dest1,
960                                       adjust_address (src, SImode, 0)));
961               emit_insn (gen_rtx_SET (SImode, dest0,
962                                       gen_rtx_REG (SImode, REGNO (addr))));
963               emit_insn (gen_rtx_SET (SImode, dest0,
964                                       plus_constant (dest0, UNITS_PER_WORD)));
965
966               new_mem = gen_rtx_MEM (SImode, dest0);
967               MEM_COPY_ATTRIBUTES (new_mem, src);
968               
969               emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
970             }
971           else
972             {
973               emit_insn (gen_rtx_SET (VOIDmode, dest0,
974                                       adjust_address (src, SImode, 0)));
975               emit_insn (gen_rtx_SET (SImode, dest1,
976                                       gen_rtx_REG (SImode, REGNO (addr))));
977               emit_insn (gen_rtx_SET (SImode, dest1,
978                                       plus_constant (dest1, UNITS_PER_WORD)));
979
980               new_mem = gen_rtx_MEM (SImode, dest1);
981               MEM_COPY_ATTRIBUTES (new_mem, src);
982               
983               emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
984             }
985         }
986       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
987         {
988           rtx words[2];
989           split_double (src, &words[0], &words[1]);
990           emit_insn (gen_rtx_SET (VOIDmode,
991                                   operand_subword (dest, 0, TRUE, mode),
992                                   words[0]));
993       
994           emit_insn (gen_rtx_SET (VOIDmode,
995                                   operand_subword (dest, 1, TRUE, mode),
996                                   words[1]));
997         }
998     }
999   else if (src_code == REG && dest_code == MEM)
1000     {
1001       rtx addr = XEXP (dest, 0);
1002       rtx src0;
1003       rtx src1;
1004
1005       if (GET_CODE (addr) != REG)
1006         abort ();
1007       
1008       src0 = operand_subword (src, 0, TRUE, mode);
1009       src1 = operand_subword (src, 1, TRUE, mode);
1010       
1011       emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
1012                               src0));
1013
1014       if (REGNO (addr) == STACK_POINTER_REGNUM
1015           || REGNO (addr) == FRAME_POINTER_REGNUM)
1016         emit_insn (gen_rtx_SET (VOIDmode,
1017                                 adjust_address (dest, SImode, UNITS_PER_WORD),
1018                                 src1));
1019       else
1020         {
1021           rtx new_mem;
1022           
1023           /* We need a scratch register to hold the value of 'address + 4'.
1024              We ought to allow gcc to find one for us, but for now, just
1025              push one of the source registers.  */
1026           emit_insn (gen_movsi_push (src0));
1027           emit_insn (gen_movsi_internal (src0, addr));
1028           emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1029           
1030           new_mem = gen_rtx_MEM (SImode, src0);
1031           MEM_COPY_ATTRIBUTES (new_mem, dest);
1032           
1033           emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1034           emit_insn (gen_movsi_pop (src0));
1035         }
1036     }
1037   else
1038     /* This should have been prevented by the constraints on movdi_insn.  */
1039     abort ();
1040   
1041   val = get_insns ();
1042   end_sequence ();
1043
1044   return val;
1045 }
1046 /*}}}*/
1047 /* Local Variables: */
1048 /* folded-file: t   */
1049 /* End:             */