OSDN Git Service

* target.h (targetm.calls.arg_partial_bytes): 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 bool fr30_must_pass_in_stack (enum machine_mode, tree);
127 static int fr30_arg_partial_bytes (CUMULATIVE_ARGS *, enum machine_mode,
128                                    tree, bool);
129
130
131 #define FRAME_POINTER_MASK      (1 << (FRAME_POINTER_REGNUM))
132 #define RETURN_POINTER_MASK     (1 << (RETURN_POINTER_REGNUM))
133
134 /* Tell prologue and epilogue if register REGNO should be saved / restored.
135    The return address and frame pointer are treated separately.
136    Don't consider them here.  */
137 #define MUST_SAVE_REGISTER(regno)      \
138   (   (regno) != RETURN_POINTER_REGNUM \
139    && (regno) != FRAME_POINTER_REGNUM  \
140    &&   regs_ever_live [regno]         \
141    && ! call_used_regs [regno]         )
142
143 #define MUST_SAVE_FRAME_POINTER  (regs_ever_live [FRAME_POINTER_REGNUM]  || frame_pointer_needed)
144 #define MUST_SAVE_RETURN_POINTER (regs_ever_live [RETURN_POINTER_REGNUM] || current_function_profile)
145
146 #if UNITS_PER_WORD == 4
147 #define WORD_ALIGN(SIZE) (((SIZE) + 3) & ~3)
148 #endif
149 \f
150 /* Initialize the GCC target structure.  */
151 #undef  TARGET_ASM_ALIGNED_HI_OP
152 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
153 #undef  TARGET_ASM_ALIGNED_SI_OP
154 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
155
156 #undef  TARGET_PROMOTE_PROTOTYPES
157 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
158 #undef  TARGET_PASS_BY_REFERENCE
159 #define TARGET_PASS_BY_REFERENCE hook_pass_by_reference_must_pass_in_stack
160 #undef  TARGET_ARG_PARTIAL_BYTES
161 #define TARGET_ARG_PARTIAL_BYTES fr30_arg_partial_bytes
162
163 #undef  TARGET_SETUP_INCOMING_VARARGS
164 #define TARGET_SETUP_INCOMING_VARARGS fr30_setup_incoming_varargs
165 #undef  TARGET_MUST_PASS_IN_STACK
166 #define TARGET_MUST_PASS_IN_STACK fr30_must_pass_in_stack
167
168 struct gcc_target targetm = TARGET_INITIALIZER;
169 \f
170 /* Returns the number of bytes offset between FROM_REG and TO_REG
171    for the current function.  As a side effect it fills in the 
172    current_frame_info structure, if the data is available.  */
173 unsigned int
174 fr30_compute_frame_size (int from_reg, int to_reg)
175 {
176   int           regno;
177   unsigned int  return_value;
178   unsigned int  var_size;
179   unsigned int  args_size;
180   unsigned int  pretend_size;
181   unsigned int  reg_size;
182   unsigned int  gmask;
183
184   var_size      = WORD_ALIGN (get_frame_size ());
185   args_size     = WORD_ALIGN (current_function_outgoing_args_size);
186   pretend_size  = current_function_pretend_args_size;
187
188   reg_size      = 0;
189   gmask         = 0;
190
191   /* Calculate space needed for registers.  */
192   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno ++)
193     {
194       if (MUST_SAVE_REGISTER (regno))
195         {
196           reg_size += UNITS_PER_WORD;
197           gmask |= 1 << regno;
198         }
199     }
200
201   current_frame_info.save_fp = MUST_SAVE_FRAME_POINTER;
202   current_frame_info.save_rp = MUST_SAVE_RETURN_POINTER;
203
204   reg_size += (current_frame_info.save_fp + current_frame_info.save_rp)
205                * UNITS_PER_WORD;
206
207   /* Save computed information.  */
208   current_frame_info.pretend_size = pretend_size;
209   current_frame_info.var_size     = var_size;
210   current_frame_info.args_size    = args_size;
211   current_frame_info.reg_size     = reg_size;
212   current_frame_info.frame_size   = args_size + var_size;
213   current_frame_info.total_size   = args_size + var_size + reg_size + pretend_size;
214   current_frame_info.gmask        = gmask;
215   current_frame_info.initialised  = reload_completed;
216
217   /* Calculate the required distance.  */
218   return_value = 0;
219   
220   if (to_reg == STACK_POINTER_REGNUM)
221     return_value += args_size + var_size;
222   
223   if (from_reg == ARG_POINTER_REGNUM)
224     return_value += reg_size;
225
226   return return_value;
227 }
228
229 /* Called after register allocation to add any instructions needed for the
230    prologue.  Using a prologue insn is favored compared to putting all of the
231    instructions in output_function_prologue(), since it allows the scheduler
232    to intermix instructions with the saves of the caller saved registers.  In
233    some cases, it might be necessary to emit a barrier instruction as the last
234    insn to prevent such scheduling.  */
235
236 void
237 fr30_expand_prologue (void)
238 {
239   int regno;
240   rtx insn;
241
242   if (! current_frame_info.initialised)
243     fr30_compute_frame_size (0, 0);
244
245   /* This cases shouldn't happen.  Catch it now.  */
246   if (current_frame_info.total_size == 0
247       && current_frame_info.gmask)
248     abort ();
249
250   /* Allocate space for register arguments if this is a variadic function.  */
251   if (current_frame_info.pretend_size)
252     {
253       int regs_to_save = current_frame_info.pretend_size / UNITS_PER_WORD;
254       
255       /* Push argument registers into the pretend arg area.  */
256       for (regno = FIRST_ARG_REGNUM + FR30_NUM_ARG_REGS; regno --, regs_to_save --;)
257         {
258           insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
259           RTX_FRAME_RELATED_P (insn) = 1;
260         }
261     }
262
263   if (current_frame_info.gmask)
264     {
265       /* Save any needed call-saved regs.  */
266       for (regno = STACK_POINTER_REGNUM; regno--;)
267         {
268           if ((current_frame_info.gmask & (1 << regno)) != 0)
269             {
270               insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, regno)));
271               RTX_FRAME_RELATED_P (insn) = 1;
272             }
273         }
274     }
275
276   /* Save return address if necessary.  */
277   if (current_frame_info.save_rp)
278     {
279       insn = emit_insn (gen_movsi_push (gen_rtx_REG (Pmode, 
280                                                      RETURN_POINTER_REGNUM)));
281       RTX_FRAME_RELATED_P (insn) = 1;
282     }
283
284   /* Save old frame pointer and create new one, if necessary.  */
285   if (current_frame_info.save_fp)
286     {
287       if (current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
288         {
289           int enter_size = current_frame_info.frame_size + UNITS_PER_WORD;
290           rtx pattern;
291           
292           insn = emit_insn (gen_enter_func (GEN_INT (enter_size)));
293           RTX_FRAME_RELATED_P (insn) = 1;
294           
295           pattern = PATTERN (insn);
296           
297           /* Also mark all 3 subexpressions as RTX_FRAME_RELATED_P. */
298           if (GET_CODE (pattern) == PARALLEL)
299             {
300               int x;
301               for (x = XVECLEN (pattern, 0); x--;)
302                 {
303                   rtx part = XVECEXP (pattern, 0, x);
304                   
305                   /* One of the insns in the ENTER pattern updates the
306                      frame pointer.  If we do not actually need the frame
307                      pointer in this function then this is a side effect
308                      rather than a desired effect, so we do not mark that
309                      insn as being related to the frame set up.  Doing this
310                      allows us to compile the crash66.C test file in the
311                      G++ testsuite.  */
312                   if (! frame_pointer_needed
313                       && GET_CODE (part) == SET
314                       && REGNO (SET_DEST (part)) == HARD_FRAME_POINTER_REGNUM)
315                     RTX_FRAME_RELATED_P (part) = 0;
316                   else
317                     RTX_FRAME_RELATED_P (part) = 1;
318                 }
319             }
320         }
321       else
322         {
323           insn = emit_insn (gen_movsi_push (frame_pointer_rtx));
324           RTX_FRAME_RELATED_P (insn) = 1;
325
326           if (frame_pointer_needed)
327             {
328               insn = emit_insn (gen_movsi (frame_pointer_rtx, stack_pointer_rtx));
329               RTX_FRAME_RELATED_P (insn) = 1;
330             }
331         }
332     }
333
334   /* Allocate the stack frame.  */
335   if (current_frame_info.frame_size == 0)
336     ; /* Nothing to do.  */
337   else if (current_frame_info.save_fp
338            && current_frame_info.frame_size < ((1 << 10) - UNITS_PER_WORD))
339     ; /* Nothing to do.  */
340   else if (current_frame_info.frame_size <= 512)
341     {
342       insn = emit_insn (gen_add_to_stack (GEN_INT (- current_frame_info.frame_size)));
343       RTX_FRAME_RELATED_P (insn) = 1;
344     }
345   else
346     {
347       rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
348       insn = emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
349       RTX_FRAME_RELATED_P (insn) = 1;
350       insn = emit_insn (gen_subsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
351       RTX_FRAME_RELATED_P (insn) = 1;
352     }
353
354   if (current_function_profile)
355     emit_insn (gen_blockage ());
356 }
357
358 /* Called after register allocation to add any instructions needed for the
359    epilogue.  Using an epilogue insn is favored compared to putting all of the
360    instructions in output_function_epilogue(), since it allows the scheduler
361    to intermix instructions with the restores of the caller saved registers.
362    In some cases, it might be necessary to emit a barrier instruction as the
363    first insn to prevent such scheduling.  */
364 void
365 fr30_expand_epilogue (void)
366 {
367   int regno;
368
369   /* Perform the inversion operations of the prologue.  */
370   if (! current_frame_info.initialised)
371     abort ();
372
373   /* Pop local variables and arguments off the stack.
374      If frame_pointer_needed is TRUE then the frame pointer register
375      has actually been used as a frame pointer, and we can recover
376      the stack pointer from it, otherwise we must unwind the stack
377      manually.  */
378   if (current_frame_info.frame_size > 0)
379     {
380       if (current_frame_info.save_fp && frame_pointer_needed)
381         {
382           emit_insn (gen_leave_func ());
383           current_frame_info.save_fp = 0;
384         }
385       else if (current_frame_info.frame_size <= 508)
386         emit_insn (gen_add_to_stack
387                    (GEN_INT (current_frame_info.frame_size)));
388       else
389         {
390           rtx tmp = gen_rtx_REG (Pmode, PROLOGUE_TMP_REGNUM);
391           emit_insn (gen_movsi (tmp, GEN_INT (current_frame_info.frame_size)));
392           emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx, tmp));
393         }
394     }
395   
396   if (current_frame_info.save_fp)
397     emit_insn (gen_movsi_pop (frame_pointer_rtx));
398   
399   /* Pop all the registers that were pushed.  */
400   if (current_frame_info.save_rp)
401     emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, RETURN_POINTER_REGNUM)));
402     
403   for (regno = 0; regno < STACK_POINTER_REGNUM; regno ++)
404     if (current_frame_info.gmask & (1 << regno))
405       emit_insn (gen_movsi_pop (gen_rtx_REG (Pmode, regno)));
406   
407   if (current_frame_info.pretend_size)
408     emit_insn (gen_add_to_stack (GEN_INT (current_frame_info.pretend_size)));
409
410   /* Reset state info for each function.  */
411   current_frame_info = zero_frame_info;
412
413   emit_jump_insn (gen_return_from_func ());
414 }
415
416 /* Do any needed setup for a variadic function.  We must create a register
417    parameter block, and then copy any anonymous arguments, plus the last
418    named argument, from registers into memory.  * copying actually done in
419    fr30_expand_prologue().
420
421    ARG_REGS_USED_SO_FAR has *not* been updated for the last named argument
422    which has type TYPE and mode MODE, and we rely on this fact.  */
423 void
424 fr30_setup_incoming_varargs (CUMULATIVE_ARGS *arg_regs_used_so_far,
425                              enum machine_mode mode,
426                              tree type ATTRIBUTE_UNUSED,
427                              int *pretend_size,
428                              int second_time ATTRIBUTE_UNUSED)
429 {
430   int size;
431
432   /* All BLKmode values are passed by reference.  */
433   if (mode == BLKmode)
434     abort ();
435
436   /* ??? This run-time test as well as the code inside the if
437      statement is probably unnecessary.  */
438   if (targetm.calls.strict_argument_naming (arg_regs_used_so_far))
439     /* If TARGET_STRICT_ARGUMENT_NAMING returns true, then the last named
440        arg must not be treated as an anonymous arg.  */
441     arg_regs_used_so_far += fr30_num_arg_regs (mode, type);
442
443   size = FR30_NUM_ARG_REGS - (* arg_regs_used_so_far);
444
445   if (size <= 0)
446     return;
447
448   * pretend_size = (size * UNITS_PER_WORD);
449 }
450
451 /*}}}*/
452 /*{{{  Printing operands */ 
453
454 /* Print a memory address as an operand to reference that memory location.  */
455
456 void
457 fr30_print_operand_address (FILE *stream, rtx address)
458 {
459   switch (GET_CODE (address))
460     {
461     case SYMBOL_REF:
462       output_addr_const (stream, address);
463       break;
464       
465     default:
466       fprintf (stderr, "code = %x\n", GET_CODE (address));
467       debug_rtx (address);
468       output_operand_lossage ("fr30_print_operand_address: unhandled address");
469       break;
470     }
471 }
472
473 /* Print an operand.  */
474
475 void
476 fr30_print_operand (FILE *file, rtx x, int code)
477 {
478   rtx x0;
479   
480   switch (code)
481     {
482     case '#':
483       /* Output a :D if this instruction is delayed.  */
484       if (dbr_sequence_length () != 0)
485         fputs (":D", file);
486       return;
487       
488     case 'p':
489       /* Compute the register name of the second register in a hi/lo
490          register pair.  */
491       if (GET_CODE (x) != REG)
492         output_operand_lossage ("fr30_print_operand: unrecognized %%p code");
493       else
494         fprintf (file, "r%d", REGNO (x) + 1);
495       return;
496       
497     case 'b':
498       /* Convert GCC's comparison operators into FR30 comparison codes.  */
499       switch (GET_CODE (x))
500         {
501         case EQ:  fprintf (file, "eq"); break;
502         case NE:  fprintf (file, "ne"); break;
503         case LT:  fprintf (file, "lt"); break;
504         case LE:  fprintf (file, "le"); break;
505         case GT:  fprintf (file, "gt"); break;
506         case GE:  fprintf (file, "ge"); break;
507         case LTU: fprintf (file, "c"); break;
508         case LEU: fprintf (file, "ls"); break;
509         case GTU: fprintf (file, "hi"); break;
510         case GEU: fprintf (file, "nc");  break;
511         default:
512           output_operand_lossage ("fr30_print_operand: unrecognized %%b code");
513           break;
514         }
515       return;
516       
517     case 'B':
518       /* Convert GCC's comparison operators into the complimentary FR30
519          comparison codes.  */
520       switch (GET_CODE (x))
521         {
522         case EQ:  fprintf (file, "ne"); break;
523         case NE:  fprintf (file, "eq"); break;
524         case LT:  fprintf (file, "ge"); break;
525         case LE:  fprintf (file, "gt"); break;
526         case GT:  fprintf (file, "le"); break;
527         case GE:  fprintf (file, "lt"); break;
528         case LTU: fprintf (file, "nc"); break;
529         case LEU: fprintf (file, "hi"); break;
530         case GTU: fprintf (file, "ls"); break;
531         case GEU: fprintf (file, "c"); break;
532         default:
533           output_operand_lossage ("fr30_print_operand: unrecognized %%B code");
534           break;
535         }
536       return;
537
538     case 'A':
539       /* Print a signed byte value as an unsigned value.  */
540       if (GET_CODE (x) != CONST_INT)
541         output_operand_lossage ("fr30_print_operand: invalid operand to %%A code");
542       else
543         {
544           HOST_WIDE_INT val;
545           
546           val = INTVAL (x);
547
548           val &= 0xff;
549
550           fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
551         }
552       return;
553       
554     case 'x':
555       if (GET_CODE (x) != CONST_INT
556           || INTVAL (x) < 16
557           || INTVAL (x) > 32)
558         output_operand_lossage ("fr30_print_operand: invalid %%x code");
559       else
560         fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) - 16);
561       return;
562
563     case 'F':
564       if (GET_CODE (x) != CONST_DOUBLE)
565         output_operand_lossage ("fr30_print_operand: invalid %%F code");
566       else
567         {
568           char str[30];
569
570           real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x),
571                            sizeof (str), 0, 1);
572           fputs (str, file);
573         }
574       return;
575       
576     case 0:
577       /* Handled below.  */
578       break;
579       
580     default:
581       fprintf (stderr, "unknown code = %x\n", code);
582       output_operand_lossage ("fr30_print_operand: unknown code");
583       return;
584     }
585
586   switch (GET_CODE (x))
587     {
588     case REG:
589       fputs (reg_names [REGNO (x)], file);
590       break;
591
592     case MEM:
593       x0 = XEXP (x,0);
594       
595       switch (GET_CODE (x0))
596         {
597         case REG:
598           if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
599             abort ();
600           fprintf (file, "@%s", reg_names [REGNO (x0)]);
601           break;
602
603         case PLUS:
604           if (GET_CODE (XEXP (x0, 0)) != REG
605               || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
606               || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
607               || GET_CODE (XEXP (x0, 1)) != CONST_INT)
608             {
609               fprintf (stderr, "bad INDEXed address:");
610               debug_rtx (x);
611               output_operand_lossage ("fr30_print_operand: unhandled MEM");
612             }
613           else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
614             {
615               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
616               if (val < -(1 << 9) || val > ((1 << 9) - 4))
617                 {
618                   fprintf (stderr, "frame INDEX out of range:");
619                   debug_rtx (x);
620                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
621                 }
622               fprintf (file, "@(r14, #" HOST_WIDE_INT_PRINT_DEC ")", val);
623             }
624           else
625             {
626               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
627               if (val < 0 || val > ((1 << 6) - 4))
628                 {
629                   fprintf (stderr, "stack INDEX out of range:");
630                   debug_rtx (x);
631                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
632                 }
633               fprintf (file, "@(r15, #" HOST_WIDE_INT_PRINT_DEC ")", val);
634             }
635           break;
636           
637         case SYMBOL_REF:
638           output_address (x0);
639           break;
640           
641         default:
642           fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
643           debug_rtx (x);
644           output_operand_lossage ("fr30_print_operand: unhandled MEM");
645           break;
646         }
647       break;
648       
649     case CONST_DOUBLE :
650       /* We handle SFmode constants here as output_addr_const doesn't.  */
651       if (GET_MODE (x) == SFmode)
652         {
653           REAL_VALUE_TYPE d;
654           long l;
655
656           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
657           REAL_VALUE_TO_TARGET_SINGLE (d, l);
658           fprintf (file, "0x%08lx", l);
659           break;
660         }
661
662       /* Fall through.  Let output_addr_const deal with it.  */
663     default:
664       output_addr_const (file, x);
665       break;
666     }
667
668   return;
669 }
670
671 /*}}}*/
672 /*{{{  Function arguments */ 
673
674 /* Return true if we should pass an argument on the stack rather than
675    in registers.  */
676
677 static bool
678 fr30_must_pass_in_stack (enum machine_mode mode, tree type)
679 {
680   if (mode == BLKmode)
681     return true;
682   if (type == NULL)
683     return false;
684   return AGGREGATE_TYPE_P (type);
685 }
686
687 /* Compute the number of word sized registers needed to hold a
688    function argument of mode INT_MODE and tree type TYPE.  */
689 int
690 fr30_num_arg_regs (enum machine_mode mode, tree type)
691 {
692   int size;
693
694   if (targetm.calls.must_pass_in_stack (mode, type))
695     return 0;
696
697   if (type && mode == BLKmode)
698     size = int_size_in_bytes (type);
699   else
700     size = GET_MODE_SIZE (mode);
701
702   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
703 }
704
705 /* Returns the number of bytes in which *part* of a parameter of machine
706    mode MODE and tree type TYPE (which may be NULL if the type is not known).
707    If the argument fits entirely in the argument registers, or entirely on
708    the stack, then 0 is returned.
709    CUM is the number of argument registers already used by earlier
710    parameters to the function.  */
711
712 static int
713 fr30_arg_partial_bytes (CUMULATIVE_ARGS *cum, enum machine_mode mode,
714                         tree type, bool named)
715 {
716   /* Unnamed arguments, i.e. those that are prototyped as ...
717      are always passed on the stack.
718      Also check here to see if all the argument registers are full.  */
719   if (named == 0 || *cum >= FR30_NUM_ARG_REGS)
720     return 0;
721
722   /* Work out how many argument registers would be needed if this
723      parameter were to be passed entirely in registers.  If there
724      are sufficient argument registers available (or if no registers
725      are needed because the parameter must be passed on the stack)
726      then return zero, as this parameter does not require partial
727      register, partial stack stack space.  */
728   if (*cum + fr30_num_arg_regs (mode, type) <= FR30_NUM_ARG_REGS)
729     return 0;
730   
731   return (FR30_NUM_ARG_REGS - *cum) * UNITS_PER_WORD;
732 }
733
734 /*}}}*/
735 /*{{{  Operand predicates */ 
736
737 #ifndef Mmode
738 #define Mmode enum machine_mode
739 #endif
740
741 /* Returns true if OPERAND is an integer value suitable for use in
742    an ADDSP instruction.  */
743 int
744 stack_add_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
745 {
746   return
747     (GET_CODE (operand) == CONST_INT
748      && INTVAL (operand) >= -512
749      && INTVAL (operand) <=  508
750      && ((INTVAL (operand) & 3) == 0));
751 }
752
753 /* Returns true if OPERAND is an integer value suitable for use in
754    an ADD por ADD2 instruction, or if it is a register.  */
755 int
756 add_immediate_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
757 {
758   return
759     (GET_CODE (operand) == REG
760      || (GET_CODE (operand) == CONST_INT
761          && INTVAL (operand) >= -16
762          && INTVAL (operand) <=  15));
763 }
764
765 /* Returns true if OPERAND is hard register in the range 8 - 15.  */
766 int
767 high_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
768 {
769   return
770     (GET_CODE (operand) == REG
771      && REGNO (operand) <= 15
772      && REGNO (operand) >= 8);
773 }
774
775 /* Returns true if OPERAND is hard register in the range 0 - 7.  */
776 int
777 low_register_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
778 {
779   return
780     (GET_CODE (operand) == REG
781      && REGNO (operand) <= 7);
782 }
783
784 /* Returns true if OPERAND is suitable for use in a CALL insn.  */
785 int
786 call_operand (rtx operand, Mmode mode ATTRIBUTE_UNUSED)
787 {
788   return (GET_CODE (operand) == MEM
789           && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
790               || GET_CODE (XEXP (operand, 0)) == REG));
791 }
792
793 /* Returns TRUE if OP is a valid operand of a DImode operation.  */
794 int
795 di_operand (rtx op, Mmode mode)
796 {
797   if (register_operand (op, mode))
798     return TRUE;
799
800   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
801     return FALSE;
802
803   if (GET_CODE (op) == SUBREG)
804     op = SUBREG_REG (op);
805
806   switch (GET_CODE (op))
807     {
808     case CONST_DOUBLE:
809     case CONST_INT:
810       return TRUE;
811
812     case MEM:
813       return memory_address_p (DImode, XEXP (op, 0));
814
815     default:
816       return FALSE;
817     }
818 }
819
820 /* Returns TRUE if OP is a DImode register or MEM.  */
821 int
822 nonimmediate_di_operand (rtx op, Mmode mode)
823 {
824   if (register_operand (op, mode))
825     return TRUE;
826
827   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
828     return FALSE;
829
830   if (GET_CODE (op) == SUBREG)
831     op = SUBREG_REG (op);
832
833   if (GET_CODE (op) == MEM)
834     return memory_address_p (DImode, XEXP (op, 0));
835
836   return FALSE;
837 }
838
839 /* Returns true iff all the registers in the operands array
840    are in descending or ascending order.  */
841 int
842 fr30_check_multiple_regs (rtx *operands, int num_operands, int descending)
843 {
844   if (descending)
845     {
846       unsigned int prev_regno = 0;
847       
848       while (num_operands --)
849         {
850           if (GET_CODE (operands [num_operands]) != REG)
851             return 0;
852           
853           if (REGNO (operands [num_operands]) < prev_regno)
854             return 0;
855           
856           prev_regno = REGNO (operands [num_operands]);
857         }
858     }
859   else
860     {
861       unsigned int prev_regno = CONDITION_CODE_REGNUM;
862       
863       while (num_operands --)
864         {
865           if (GET_CODE (operands [num_operands]) != REG)
866             return 0;
867           
868           if (REGNO (operands [num_operands]) > prev_regno)
869             return 0;
870           
871           prev_regno = REGNO (operands [num_operands]);
872         }
873     }
874
875   return 1;
876 }
877
878 int
879 fr30_const_double_is_zero (rtx operand)
880 {
881   REAL_VALUE_TYPE d;
882
883   if (operand == NULL || GET_CODE (operand) != CONST_DOUBLE)
884     return 0;
885
886   REAL_VALUE_FROM_CONST_DOUBLE (d, operand);
887
888   return REAL_VALUES_EQUAL (d, dconst0);
889 }
890
891 /*}}}*/
892 /*{{{  Instruction Output Routines  */
893
894 /* Output a double word move.
895    It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
896    On the FR30 we are constrained by the fact that it does not
897    support offsetable addresses, and so we have to load the
898    address of the secnd word into the second destination register
899    before we can use it.  */
900
901 rtx
902 fr30_move_double (rtx * operands)
903 {
904   rtx src  = operands[1];
905   rtx dest = operands[0];
906   enum rtx_code src_code = GET_CODE (src);
907   enum rtx_code dest_code = GET_CODE (dest);
908   enum machine_mode mode = GET_MODE (dest);
909   rtx val;
910
911   start_sequence ();
912
913   if (dest_code == REG)
914     {
915       if (src_code == REG)
916         {
917           int reverse = (REGNO (dest) == REGNO (src) + 1);
918           
919           /* We normally copy the low-numbered register first.  However, if
920              the first register of operand 0 is the same as the second register
921              of operand 1, we must copy in the opposite order.  */
922           emit_insn (gen_rtx_SET (VOIDmode,
923                                   operand_subword (dest, reverse, TRUE, mode),
924                                   operand_subword (src,  reverse, TRUE, mode)));
925           
926           emit_insn (gen_rtx_SET (VOIDmode,
927                               operand_subword (dest, !reverse, TRUE, mode),
928                               operand_subword (src,  !reverse, TRUE, mode)));
929         }
930       else if (src_code == MEM)
931         {
932           rtx addr = XEXP (src, 0);
933           int dregno = REGNO (dest);
934           rtx dest0;
935           rtx dest1;
936           rtx new_mem;
937           
938           /* If the high-address word is used in the address, we
939              must load it last.  Otherwise, load it first.  */
940           int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
941
942           if (GET_CODE (addr) != REG)
943             abort ();
944           
945           dest0 = operand_subword (dest, reverse, TRUE, mode);
946           dest1 = operand_subword (dest, !reverse, TRUE, mode);
947
948           if (reverse)
949             {
950               emit_insn (gen_rtx_SET (VOIDmode, dest1,
951                                       adjust_address (src, SImode, 0)));
952               emit_insn (gen_rtx_SET (SImode, dest0,
953                                       gen_rtx_REG (SImode, REGNO (addr))));
954               emit_insn (gen_rtx_SET (SImode, dest0,
955                                       plus_constant (dest0, UNITS_PER_WORD)));
956
957               new_mem = gen_rtx_MEM (SImode, dest0);
958               MEM_COPY_ATTRIBUTES (new_mem, src);
959               
960               emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
961             }
962           else
963             {
964               emit_insn (gen_rtx_SET (VOIDmode, dest0,
965                                       adjust_address (src, SImode, 0)));
966               emit_insn (gen_rtx_SET (SImode, dest1,
967                                       gen_rtx_REG (SImode, REGNO (addr))));
968               emit_insn (gen_rtx_SET (SImode, dest1,
969                                       plus_constant (dest1, UNITS_PER_WORD)));
970
971               new_mem = gen_rtx_MEM (SImode, dest1);
972               MEM_COPY_ATTRIBUTES (new_mem, src);
973               
974               emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
975             }
976         }
977       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
978         {
979           rtx words[2];
980           split_double (src, &words[0], &words[1]);
981           emit_insn (gen_rtx_SET (VOIDmode,
982                                   operand_subword (dest, 0, TRUE, mode),
983                                   words[0]));
984       
985           emit_insn (gen_rtx_SET (VOIDmode,
986                                   operand_subword (dest, 1, TRUE, mode),
987                                   words[1]));
988         }
989     }
990   else if (src_code == REG && dest_code == MEM)
991     {
992       rtx addr = XEXP (dest, 0);
993       rtx src0;
994       rtx src1;
995
996       if (GET_CODE (addr) != REG)
997         abort ();
998       
999       src0 = operand_subword (src, 0, TRUE, mode);
1000       src1 = operand_subword (src, 1, TRUE, mode);
1001       
1002       emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
1003                               src0));
1004
1005       if (REGNO (addr) == STACK_POINTER_REGNUM
1006           || REGNO (addr) == FRAME_POINTER_REGNUM)
1007         emit_insn (gen_rtx_SET (VOIDmode,
1008                                 adjust_address (dest, SImode, UNITS_PER_WORD),
1009                                 src1));
1010       else
1011         {
1012           rtx new_mem;
1013           
1014           /* We need a scratch register to hold the value of 'address + 4'.
1015              We ought to allow gcc to find one for us, but for now, just
1016              push one of the source registers.  */
1017           emit_insn (gen_movsi_push (src0));
1018           emit_insn (gen_movsi_internal (src0, addr));
1019           emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1020           
1021           new_mem = gen_rtx_MEM (SImode, src0);
1022           MEM_COPY_ATTRIBUTES (new_mem, dest);
1023           
1024           emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1025           emit_insn (gen_movsi_pop (src0));
1026         }
1027     }
1028   else
1029     /* This should have been prevented by the constraints on movdi_insn.  */
1030     abort ();
1031   
1032   val = get_insns ();
1033   end_sequence ();
1034
1035   return val;
1036 }
1037 /*}}}*/
1038 /* Local Variables: */
1039 /* folded-file: t   */
1040 /* End:             */