OSDN Git Service

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