OSDN Git Service

* target.h (struct gcc_target): Add calls.pass_by_reference.
[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 bool fr30_must_pass_in_stack (enum machine_mode, tree);
127
128 #define FRAME_POINTER_MASK      (1 << (FRAME_POINTER_REGNUM))
129 #define RETURN_POINTER_MASK     (1 << (RETURN_POINTER_REGNUM))
130
131 /* Tell prologue and epilogue if register REGNO should be saved / restored.
132    The return address and frame pointer are treated separately.
133    Don't consider them here.  */
134 #define MUST_SAVE_REGISTER(regno)      \
135   (   (regno) != RETURN_POINTER_REGNUM \
136    && (regno) != FRAME_POINTER_REGNUM  \
137    &&   regs_ever_live [regno]         \
138    && ! call_used_regs [regno]         )
139
140 #define MUST_SAVE_FRAME_POINTER  (regs_ever_live [FRAME_POINTER_REGNUM]  || frame_pointer_needed)
141 #define MUST_SAVE_RETURN_POINTER (regs_ever_live [RETURN_POINTER_REGNUM] || current_function_profile)
142
143 #if UNITS_PER_WORD == 4
144 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
145 #endif
146 \f
147 /* Initialize the GCC target structure.  */
148 #undef  TARGET_ASM_ALIGNED_HI_OP
149 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
150 #undef  TARGET_ASM_ALIGNED_SI_OP
151 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
152
153 #undef  TARGET_PROMOTE_PROTOTYPES
154 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
155 #undef  TARGET_PASS_BY_REFERENCE
156 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
157
158 #undef  TARGET_SETUP_INCOMING_VARARGS
159 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
160 #undef  TARGET_MUST_PASS_IN_STACK
161 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
162
163 struct gcc_target targetm = TARGET_INITIALIZER;
164 \f
165 /* Returns the number of bytes offset between FROM_REG and TO_REG
166    for the current function.  As a side effect it fills in the 
167    current_frame_info structure, if the data is available.  */
168 unsigned int
169 fr30_compute_frame_size (int from_reg, int to_reg)
170 {
171   int           regno;
172   unsigned int  return_value;
173   unsigned int  var_size;
174   unsigned int  args_size;
175   unsigned int  pretend_size;
176   unsigned int  reg_size;
177   unsigned int  gmask;
178
179   var_size      = WORD_ALIGN (get_frame_size ());
180   args_size     = WORD_ALIGN (current_function_outgoing_args_size);
181   pretend_size  = current_function_pretend_args_size;
182
183   reg_size      = 0;
184   gmask         = 0;
185
186   /* Calculate space needed for registers.  */
187   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
188     {
189       if (MUST_SAVE_REGISTER (regno))
190         {
191           reg_size += UNITS_PER_WORD;
192           gmask |= 1 << regno;
193         }
194     }
195
196   current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
197   current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
198
199   reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
200                * UNITS_PER_WORD;
201
202   /* Save computed information.  */
203   current_frame_info.pretend_size = pretend_size;
204   current_frame_info.var_size     = var_size;
205   current_frame_info.args_size    = args_size;
206   current_frame_info.reg_size     = reg_size;
207   current_frame_info.frame_size   = args_size + var_size;
208   current_frame_info.total_size   = args_size + var_size + reg_size + pretend_size;
209   current_frame_info.gmask        = gmask;
210   current_frame_info.initialised  = reload_completed;
211
212   /* Calculate the required distance.  */
213   return_value = 0;
214   
215   if (to_reg == STACK_POINTER_REGNUM)
216     return_value += args_size + var_size;
217   
218   if (from_reg == ARG_POINTER_REGNUM)
219     return_value += reg_size;
220
221   return return_value;
222 }
223
224 /* Called after register allocation to add any instructions needed for the
225    prologue.  Using a prologue insn is favored compared to putting all of the
226    instructions in output_function_prologue(), since it allows the scheduler
227    to intermix instructions with the saves of the caller saved registers.  In
228    some cases, it might be necessary to emit a barrier instruction as the last
229    insn to prevent such scheduling.  */
230
231 void
232 fr30_expand_prologue (void)
233 {
234   int regno;
235   rtx insn;
236
237   if (! current_frame_info.initialised)
238     fr30_compute_frame_size (0, 0);
239
240   /* This cases shouldn't happen.  Catch it now.  */
241   if (current_frame_info.total_size == 0
242       && current_frame_info.gmask)
243     abort ();
244
245   /* Allocate space for register arguments if this is a variadic function.  */
246   if (current_frame_info.pretend_size)
247     {
248       int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
249       
250       /* Push argument registers into the pretend arg area.  */
251       for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
252         {
253           insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
254           RTX_FRAME_RELATED_P (insn) = 1;
255         }
256     }
257
258   if (current_frame_info.gmask)
259     {
260       /* Save any needed call-saved regs.  */
261       for (regno = STACK_POINTER_REGNUM; regno--;)
262         {
263           if ((current_frame_info.gmask & (1 << regno)) != 0)
264             {
265               insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
266               RTX_FRAME_RELATED_P (insn) = 1;
267             }
268         }
269     }
270
271   /* Save return address if necessary.  */
272   if (current_frame_info.save_rp)
273     {
274       insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, 
275                                                      RETURN_POINTER_REGNUM)));
276       RTX_FRAME_RELATED_P (insn) = 1;
277     }
278
279   /* Save old frame pointer and create new one, if necessary.  */
280   if (current_frame_info.save_fp)
281     {
282       if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
283         {
284           int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
285           rtx pattern;
286           
287           insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
288           RTX_FRAME_RELATED_P (insn) = 1;
289           
290           pattern = PATTERN (insn);
291           
292           /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
293           if (GET_CODE (pattern) == PARALLEL)
294             {
295               int x;
296               for (x = XVECLEN (pattern, 0); x--;)
297                 {
298                   rtx part = XVECEXP (pattern, 0, x);
299                   
300                   /* One of the insns in the ENTER pattern updates the
301                      frame pointer.  If we do not actually need the frame
302                      pointer in this function then this is a side effect
303                      rather than a desired effect, so we do not mark that
304                      insn as being related to the frame set up.  Doing this
305                      allows us to compile the crash66.C test file in the
306                      G++ testsuite.  */
307                   if (! frame_pointer_needed
308                       && GET_CODE (part) == SET
309                       && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM)
310                     RTX_FRAME_RELATED_P (part) = 0;
311                   else
312                     RTX_FRAME_RELATED_P (part) = 1;
313                 }
314             }
315         }
316       else
317         {
318           insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
319           RTX_FRAME_RELATED_P (insn) = 1;
320
321           if (frame_pointer_needed)
322             {
323               insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
324               RTX_FRAME_RELATED_P (insn) = 1;
325             }
326         }
327     }
328
329   /* Allocate the stack frame.  */
330   if (current_frame_info.frame_size == 0)
331     ; /* Nothing to do.  */
332   else if (current_frame_info.save_fp
333            && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
334     ; /* Nothing to do.  */
335   else if (current_frame_info.frame_size <= 512)
336     {
337       insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size)));
338       RTX_FRAME_RELATED_P (insn) = 1;
339     }
340   else
341     {
342       rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
343       insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
344       RTX_FRAME_RELATED_P (insn) = 1;
345       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
346       RTX_FRAME_RELATED_P (insn) = 1;
347     }
348
349   if (current_function_profile)
350     emit_insn (gen_blockage ());
351 }
352
353 /* Called after register allocation to add any instructions needed for the
354    epilogue.  Using an epilogue insn is favored compared to putting all of the
355    instructions in output_function_epilogue(), since it allows the scheduler
356    to intermix instructions with the restores of the caller saved registers.
357    In some cases, it might be necessary to emit a barrier instruction as the
358    first insn to prevent such scheduling.  */
359 void
360 fr30_expand_epilogue (void)
361 {
362   int regno;
363
364   /* Perform the inversion operations of the prologue.  */
365   if (! current_frame_info.initialised)
366     abort ();
367
368   /* Pop local variables and arguments off the stack.
369      If frame_pointer_needed is TRUE then the frame pointer register
370      has actually been used as a frame pointer, and we can recover
371      the stack pointer from it, otherwise we must unwind the stack
372      manually.  */
373   if (current_frame_info.frame_size > 0)
374     {
375       if (current_frame_info.save_fp && frame_pointer_needed)
376         {
377           emit_insn (gen_leave_func ());
378           current_frame_info.save_fp = 0;
379         }
380       else if (current_frame_info.frame_size <= 508)
381         emit_insn (gen_add_to_stack
382                    (GEN_INT (current_frame_info.frame_size)));
383       else
384         {
385           rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
386           emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
387           emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
388         }
389     }
390   
391   if (current_frame_info.save_fp)
392     emit_insn (gen_movsi_pop (frame_pointer_rtx));
393   
394   /* Pop all the registers that were pushed.  */
395   if (current_frame_info.save_rp)
396     emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
397     
398   for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
399     if (current_frame_info.gmask & (1 << regno))
400       emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
401   
402   if (current_frame_info.pretend_size)
403     emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
404
405   /* Reset state info for each function.  */
406   current_frame_info = zero_frame_info;
407
408   emit_jump_insn (gen_return_from_func ());
409 }
410
411 /* Do any needed setup for a variadic function.  We must create a register
412    parameter block, and then copy any anonymous arguments, plus the last
413    named argument, from registers into memory.  * copying actually done in
414    fr30_expand_prologue().
415
416    ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
417    which has type TYPE and mode MODE, and we rely on this fact.  */
418 void
419 fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far,
420                              enum machine_mode mode,
421                              tree type ATTRIBUTE_UNUSED,
422                              int *pretend_size,
423                              int second_time ATTRIBUTE_UNUSED)
424 {
425   int size;
426
427   /* All BLKmode values are passed by reference.  */
428   if (mode == BLKmode)
429     abort ();
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           if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
594             abort ();
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 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
701    Returns the number of argument registers required to hold *part* of
702    a parameter of machine mode MODE and tree type TYPE (which may be
703    NULL if the type is not known).  If the argument fits entirely in
704    the argument registers, or entirely on the stack, then 0 is returned.
705    CUM is the number of argument registers already used by earlier
706    parameters to the function.  */
707
708 int
709 fr30_function_arg_partial_nregs (CUMULATIVE_ARGS cum, enum machine_mode mode,
710                                  tree type, int named)
711 {
712   /* Unnamed arguments, ie those that are prototyped as ...
713      are always passed on the stack.
714      Also check here to see if all the argument registers are full.  */
715   if (named == 0 || cum >= FR30_NUM_ARG_REGS)
716     return 0;
717
718   /* Work out how many argument registers would be needed if this
719      parameter were to be passed entirely in registers.  If there
720      are sufficient argument registers available (or if no registers
721      are needed because the parameter must be passed on the stack)
722      then return zero, as this parameter does not require partial
723      register, partial stack stack space.  */
724   if (cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
725     return 0;
726   
727   /* Otherwise return the number of registers that would be used.  */
728   return FR30_NUM_ARG_REGS - cum;
729 }
730
731 /*}}}*/
732 /*{{{  Operand predicates */ 
733
734 #ifndef Mmode
735 #define Mmode enum machine_mode
736 #endif
737
738 /* Returns true if OPERAND is an integer value suitable for use in
739    an ADDSP instruction.  */
740 int
741 stack_add_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
742 {
743   return
744     (GET_CODE (operand) == CONST_INT
745      && INTVAL (operand) >= -512
746      && INTVAL (operand) <=  508
747      && ((INTVAL (operand) & 3) == 0));
748 }
749
750 /* Returns true if OPERAND is an integer value suitable for use in
751    an ADD por ADD2 instruction, or if it is a register.  */
752 int
753 add_immediate_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
754 {
755   return
756     (GET_CODE (operand) == REG
757      || (GET_CODE (operand) == CONST_INT
758          && INTVAL (operand) >= -16
759          && INTVAL (operand) <=  15));
760 }
761
762 /* Returns true if OPERAND is hard register in the range 8 - 15.  */
763 int
764 high_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
765 {
766   return
767     (GET_CODE (operand) == REG
768      && REGNO (operand) <= 15
769      && REGNO (operand) >= 8);
770 }
771
772 /* Returns true if OPERAND is hard register in the range 0 - 7.  */
773 int
774 low_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
775 {
776   return
777     (GET_CODE (operand) == REG
778      && REGNO (operand) <= 7);
779 }
780
781 /* Returns true if OPERAND is suitable for use in a CALL insn.  */
782 int
783 call_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
784 {
785   return (GET_CODE (operand) == MEM
786           && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
787               || GET_CODE (XEXP (operand, 0)) == REG));
788 }
789
790 /* Returns TRUE if OP is a valid operand of a DImode operation.  */
791 int
792 di_operand (rtx op, Mmode mode)
793 {
794   if (register_operand (op, mode))
795     return TRUE;
796
797   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
798     return FALSE;
799
800   if (GET_CODE (op) == SUBREG)
801     op = SUBREG_REG (op);
802
803   switch (GET_CODE (op))
804     {
805     case CONST_DOUBLE:
806     case CONST_INT:
807       return TRUE;
808
809     case MEM:
810       return memory_address_p (DImode, XEXP (op, 0));
811
812     default:
813       return FALSE;
814     }
815 }
816
817 /* Returns TRUE if OP is a DImode register or MEM.  */
818 int
819 nonimmediate_di_operand (rtx op, Mmode mode)
820 {
821   if (register_operand (op, mode))
822     return TRUE;
823
824   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
825     return FALSE;
826
827   if (GET_CODE (op) == SUBREG)
828     op = SUBREG_REG (op);
829
830   if (GET_CODE (op) == MEM)
831     return memory_address_p (DImode, XEXP (op, 0));
832
833   return FALSE;
834 }
835
836 /* Returns true iff all the registers in the operands array
837    are in descending or ascending order.  */
838 int
839 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
840 {
841   if (descending)
842     {
843       unsigned int prev_regno = 0;
844       
845       while (num_operands --)
846         {
847           if (GET_CODE (operands [num_operands]) != REG)
848             return 0;
849           
850           if (REGNO (operands [num_operands]) < prev_regno)
851             return 0;
852           
853           prev_regno = REGNO (operands [num_operands]);
854         }
855     }
856   else
857     {
858       unsigned int prev_regno = CONDITION_CODE_REGNUM;
859       
860       while (num_operands --)
861         {
862           if (GET_CODE (operands [num_operands]) != REG)
863             return 0;
864           
865           if (REGNO (operands [num_operands]) > prev_regno)
866             return 0;
867           
868           prev_regno = REGNO (operands [num_operands]);
869         }
870     }
871
872   return 1;
873 }
874
875 int
876 fr30_const_double_is_zero (rtx operand)
877 {
878   REAL_VALUE_TYPE d;
879
880   if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
881     return 0;
882
883   REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
884
885   return REAL_VALUES_EQUAL (d, dconst0);
886 }
887
888 /*}}}*/
889 /*{{{  Instruction Output Routines  */
890
891 /* Output a double word move.
892    It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
893    On the FR30 we are constrained by the fact that it does not
894    support offsetable addresses, and so we have to load the
895    address of the secnd word into the second destination register
896    before we can use it.  */
897
898 rtx
899 fr30_move_double (rtx * operands)
900 {
901   rtx src  = operands[1];
902   rtx dest = operands[0];
903   enum rtx_code src_code = GET_CODE (src);
904   enum rtx_code dest_code = GET_CODE (dest);
905   enum machine_mode mode = GET_MODE (dest);
906   rtx val;
907
908   start_sequence ();
909
910   if (dest_code == REG)
911     {
912       if (src_code == REG)
913         {
914           int reverse = (REGNO (dest) == REGNO (src) + 1);
915           
916           /* We normally copy the low-numbered register first.  However, if
917              the first register of operand 0 is the same as the second register
918              of operand 1, we must copy in the opposite order.  */
919           emit_insn (gen_rtx_SET (VOIDmode,
920                                   operand_subword (dest, reverse, TRUE, mode),
921                                   operand_subword (src,  reverse, TRUE, mode)));
922           
923           emit_insn (gen_rtx_SET (VOIDmode,
924                               operand_subword (dest, !reverse, TRUE, mode),
925                               operand_subword (src,  !reverse, TRUE, mode)));
926         }
927       else if (src_code == MEM)
928         {
929           rtx addr = XEXP (src, 0);
930           int dregno = REGNO (dest);
931           rtx dest0;
932           rtx dest1;
933           rtx new_mem;
934           
935           /* If the high-address word is used in the address, we
936              must load it last.  Otherwise, load it first.  */
937           int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
938
939           if (GET_CODE (addr) != REG)
940             abort ();
941           
942           dest0 = operand_subword (dest, reverse, TRUE, mode);
943           dest1 = operand_subword (dest, !reverse, TRUE, mode);
944
945           if (reverse)
946             {
947               emit_insn (gen_rtx_SET (VOIDmode, dest1,
948                                       adjust_address (src, SImode, 0)));
949               emit_insn (gen_rtx_SET (SImode, dest0,
950                                       gen_rtx_REG (SImode, REGNO (addr))));
951               emit_insn (gen_rtx_SET (SImode, dest0,
952                                       plus_constant (dest0, UNITS_PER_WORD)));
953
954               new_mem = gen_rtx_MEM (SImode, dest0);
955               MEM_COPY_ATTRIBUTES (new_mem, src);
956               
957               emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
958             }
959           else
960             {
961               emit_insn (gen_rtx_SET (VOIDmode, dest0,
962                                       adjust_address (src, SImode, 0)));
963               emit_insn (gen_rtx_SET (SImode, dest1,
964                                       gen_rtx_REG (SImode, REGNO (addr))));
965               emit_insn (gen_rtx_SET (SImode, dest1,
966                                       plus_constant (dest1, UNITS_PER_WORD)));
967
968               new_mem = gen_rtx_MEM (SImode, dest1);
969               MEM_COPY_ATTRIBUTES (new_mem, src);
970               
971               emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
972             }
973         }
974       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
975         {
976           rtx words[2];
977           split_double (src, &words[0], &words[1]);
978           emit_insn (gen_rtx_SET (VOIDmode,
979                                   operand_subword (dest, 0, TRUE, mode),
980                                   words[0]));
981       
982           emit_insn (gen_rtx_SET (VOIDmode,
983                                   operand_subword (dest, 1, TRUE, mode),
984                                   words[1]));
985         }
986     }
987   else if (src_code == REG && dest_code == MEM)
988     {
989       rtx addr = XEXP (dest, 0);
990       rtx src0;
991       rtx src1;
992
993       if (GET_CODE (addr) != REG)
994         abort ();
995       
996       src0 = operand_subword (src, 0, TRUE, mode);
997       src1 = operand_subword (src, 1, TRUE, mode);
998       
999       emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
1000                               src0));
1001
1002       if (REGNO (addr) == STACK_POINTER_REGNUM
1003           || REGNO (addr) == FRAME_POINTER_REGNUM)
1004         emit_insn (gen_rtx_SET (VOIDmode,
1005                                 adjust_address (dest, SImode, UNITS_PER_WORD),
1006                                 src1));
1007       else
1008         {
1009           rtx new_mem;
1010           
1011           /* We need a scratch register to hold the value of 'address + 4'.
1012              We ought to allow gcc to find one for us, but for now, just
1013              push one of the source registers.  */
1014           emit_insn (gen_movsi_push (src0));
1015           emit_insn (gen_movsi_internal (src0, addr));
1016           emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1017           
1018           new_mem = gen_rtx_MEM (SImode, src0);
1019           MEM_COPY_ATTRIBUTES (new_mem, dest);
1020           
1021           emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1022           emit_insn (gen_movsi_pop (src0));
1023         }
1024     }
1025   else
1026     /* This should have been prevented by the constraints on movdi_insn.  */
1027     abort ();
1028   
1029   val = get_insns ();
1030   end_sequence ();
1031
1032   return val;
1033 }
1034 /*}}}*/
1035 /* Local Variables: */
1036 /* folded-file: t   */
1037 /* End:             */