OSDN Git Service

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