* fr30.c (fr30_print_operand): Fix bug in output of CONST_DOUBLE.
[platform/upstream/gcc.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           char str[30];
559
560           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
561           REAL_VALUE_TO_DECIMAL (d, str, 8);
562           fputs (str, file);
563         }
564       return;
565       
566     case 0:
567       /* Handled below.  */
568       break;
569       
570     default:
571       fprintf (stderr, "unknown code = %x\n", code);
572       output_operand_lossage ("fr30_print_operand: unknown code");
573       return;
574     }
575
576   switch (GET_CODE (x))
577     {
578     case REG:
579       fputs (reg_names [REGNO (x)], file);
580       break;
581
582     case MEM:
583       x0 = XEXP (x,0);
584       
585       switch (GET_CODE (x0))
586         {
587         case REG:
588           if ((unsigned) REGNO (x0) >= ARRAY_SIZE (reg_names))
589             abort ();
590           fprintf (file, "@%s", reg_names [REGNO (x0)]);
591           break;
592
593         case PLUS:
594           if (GET_CODE (XEXP (x0, 0)) != REG
595               || REGNO (XEXP (x0, 0)) < FRAME_POINTER_REGNUM
596               || REGNO (XEXP (x0, 0)) > STACK_POINTER_REGNUM
597               || GET_CODE (XEXP (x0, 1)) != CONST_INT)
598             {
599               fprintf (stderr, "bad INDEXed address:");
600               debug_rtx (x);
601               output_operand_lossage ("fr30_print_operand: unhandled MEM");
602             }
603           else if (REGNO (XEXP (x0, 0)) == FRAME_POINTER_REGNUM)
604             {
605               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
606               if (val < -(1 << 9) || val > ((1 << 9) - 4))
607                 {
608                   fprintf (stderr, "frame INDEX out of range:");
609                   debug_rtx (x);
610                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
611                 }
612               fprintf (file, "@(r14, #%d)", val);
613             }
614           else
615             {
616               HOST_WIDE_INT val = INTVAL (XEXP (x0, 1));
617               if (val < 0 || val > ((1 << 6) - 4))
618                 {
619                   fprintf (stderr, "stack INDEX out of range:");
620                   debug_rtx (x);
621                   output_operand_lossage ("fr30_print_operand: unhandled MEM");
622                 }
623               fprintf (file, "@(r15, #%d)", val);
624             }
625           break;
626           
627         case SYMBOL_REF:
628           output_address (x0);
629           break;
630           
631         default:
632           fprintf (stderr, "bad MEM code = %x\n", GET_CODE (x0));
633           debug_rtx (x);
634           output_operand_lossage ("fr30_print_operand: unhandled MEM");
635           break;
636         }
637       break;
638       
639     case CONST_DOUBLE :
640       /* We handle SFmode constants here as output_addr_const doesn't.  */
641       if (GET_MODE (x) == SFmode)
642         {
643           REAL_VALUE_TYPE d;
644           long l;
645
646           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
647           REAL_VALUE_TO_TARGET_SINGLE (d, l);
648           fprintf (file, "0x%08lx", l);
649           break;
650         }
651
652       /* Fall through.  Let output_addr_const deal with it.  */
653     default:
654       output_addr_const (file, x);
655       break;
656     }
657
658   return;
659 }
660
661 /*}}}*/
662 /*{{{  Function arguments */ 
663
664 /* Compute the number of word sized registers needed to hold a
665    function argument of mode INT_MODE and tree type TYPE.  */
666 int
667 fr30_num_arg_regs (int_mode, type)
668      int int_mode;
669      tree type;
670 {
671   enum machine_mode mode = (enum machine_mode) int_mode;
672   int size;
673
674   if (MUST_PASS_IN_STACK (mode, type))
675     return 0;
676
677   if (type && mode == BLKmode)
678     size = int_size_in_bytes (type);
679   else
680     size = GET_MODE_SIZE (mode);
681
682   return (size + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
683 }
684
685 /* Implements the FUNCTION_ARG_PARTIAL_NREGS macro.
686    Returns the number of argument registers required to hold *part* of
687    a parameter of machine mode MODE and tree type TYPE (which may be
688    NULL if the type is not known).  If the argument fits entirly in
689    the argument registers, or entirely on the stack, then 0 is returned.
690    CUM is the number of argument registers already used by earlier
691    parameters to the function.  */
692
693 int
694 fr30_function_arg_partial_nregs (cum, int_mode, type, named)
695      CUMULATIVE_ARGS cum;
696      int int_mode;
697      tree type;
698      int named;
699 {
700   /* Unnamed arguments, ie those that are prototyped as ...
701      are always passed on the stack.
702      Also check here to see if all the argument registers are full.  */
703   if (named == 0 || cum >= FR30_NUM_ARG_REGS)
704     return 0;
705
706   /* Work out how many argument registers would be needed if this
707      parameter were to be passed entirely in registers.  If there
708      are sufficient argument registers available (or if no registers
709      are needed because the parameter must be passed on the stack)
710      then return zero, as this parameter does not require partial
711      register, partial stack stack space.  */
712   if (cum + fr30_num_arg_regs (int_mode, type) <= FR30_NUM_ARG_REGS)
713     return 0;
714   
715   /* Otherwise return the number of registers that would be used.  */
716   return FR30_NUM_ARG_REGS - cum;
717 }
718
719 static rtx
720 fr30_pass_by_reference (valist, type)
721      tree valist;
722      tree type;
723 {
724   tree type_ptr;
725   tree type_ptr_ptr;
726   tree t;
727   
728   type_ptr     = build_pointer_type (type);
729   type_ptr_ptr = build_pointer_type (type_ptr);
730   
731   t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (UNITS_PER_WORD, 0));
732   TREE_SIDE_EFFECTS (t) = 1;
733   t = build1 (NOP_EXPR, type_ptr_ptr, t);
734   TREE_SIDE_EFFECTS (t) = 1;
735   t = build1 (INDIRECT_REF, type_ptr, t);
736   
737   return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
738 }
739
740 static rtx
741 fr30_pass_by_value (valist, type)
742      tree valist;
743      tree type;
744 {
745   HOST_WIDE_INT size = int_size_in_bytes (type);
746   HOST_WIDE_INT rsize;
747   rtx addr_rtx;
748   tree t;
749
750   if ((size % UNITS_PER_WORD) == 0)
751     {
752       t = build (POSTINCREMENT_EXPR, va_list_type_node, valist, build_int_2 (size, 0));
753       TREE_SIDE_EFFECTS (t) = 1;
754       
755       return expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
756     }
757
758   rsize = (size + UNITS_PER_WORD - 1) & - UNITS_PER_WORD;
759       
760   /* Care for bigendian correction on the aligned address.  */
761   t = build (PLUS_EXPR, ptr_type_node, valist, build_int_2 (rsize - size, 0));
762   addr_rtx = expand_expr (t, NULL_RTX, Pmode, EXPAND_NORMAL);
763   addr_rtx = copy_to_reg (addr_rtx);
764       
765   /* Increment AP.  */
766   t = build (PLUS_EXPR, va_list_type_node, valist, build_int_2 (rsize, 0));
767   t = build (MODIFY_EXPR, va_list_type_node, valist, t);
768   TREE_SIDE_EFFECTS (t) = 1;
769   expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
770   
771   return addr_rtx;
772 }
773
774 /* Implement `va_arg'.  */
775
776 rtx
777 fr30_va_arg (valist, type)
778      tree valist;
779      tree type;
780 {
781   HOST_WIDE_INT size;
782   
783   if (AGGREGATE_TYPE_P (type))
784     return fr30_pass_by_reference (valist, type);
785   
786   size = int_size_in_bytes (type);
787
788   if ((size % sizeof (int)) == 0
789       || size < 4)
790     return fr30_pass_by_value (valist, type);
791
792   return fr30_pass_by_reference (valist, type);
793 }
794
795 /*}}}*/
796 /*{{{  Operand predicates */ 
797
798 #ifndef Mmode
799 #define Mmode enum machine_mode
800 #endif
801
802 /* Returns true if OPERAND is an integer value suitable for use in
803    an ADDSP instruction.  */
804 int
805 stack_add_operand (operand, mode)
806      rtx operand;
807      Mmode mode ATTRIBUTE_UNUSED;
808 {
809   return
810     (GET_CODE (operand) == CONST_INT
811      && INTVAL (operand) >= -512
812      && INTVAL (operand) <=  508
813      && ((INTVAL (operand) & 3) == 0));
814 }
815
816 /* Returns true if OPERAND is an integer value suitable for use in
817    an ADD por ADD2 instruction, or if it is a register.  */
818 int
819 add_immediate_operand (operand, mode)
820      rtx operand;
821      Mmode mode ATTRIBUTE_UNUSED;
822 {
823   return
824     (GET_CODE (operand) == REG
825      || (GET_CODE (operand) == CONST_INT
826          && INTVAL (operand) >= -16
827          && INTVAL (operand) <=  15));
828 }
829
830 /* Returns true if OPERAND is hard register in the range 8 - 15.  */
831 int
832 high_register_operand (operand, mode)
833      rtx operand;
834      Mmode mode ATTRIBUTE_UNUSED;
835 {
836   return
837     (GET_CODE (operand) == REG
838      && REGNO (operand) <= 15
839      && REGNO (operand) >= 8);
840 }
841
842 /* Returns true if OPERAND is hard register in the range 0 - 7.  */
843 int
844 low_register_operand (operand, mode)
845      rtx operand;
846      Mmode mode ATTRIBUTE_UNUSED;
847 {
848   return
849     (GET_CODE (operand) == REG
850      && REGNO (operand) <= 7);
851 }
852
853 /* Returns true if OPERAND is suitable for use in a CALL insn.  */
854 int
855 call_operand (operand, mode)
856      rtx operand;
857      Mmode mode ATTRIBUTE_UNUSED;
858 {
859   return (GET_CODE (operand) == MEM
860           && (GET_CODE (XEXP (operand, 0)) == SYMBOL_REF
861               || GET_CODE (XEXP (operand, 0)) == REG));
862 }
863
864 /* Returns TRUE if OP is a valid operand of a DImode operation.  */
865 int
866 di_operand (op, mode)
867      rtx op;
868      Mmode mode;
869 {
870   if (register_operand (op, mode))
871     return TRUE;
872
873   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
874     return FALSE;
875
876   if (GET_CODE (op) == SUBREG)
877     op = SUBREG_REG (op);
878
879   switch (GET_CODE (op))
880     {
881     case CONST_DOUBLE:
882     case CONST_INT:
883       return TRUE;
884
885     case MEM:
886       return memory_address_p (DImode, XEXP (op, 0));
887
888     default:
889       return FALSE;
890     }
891 }
892
893 /* Returns TRUE if OP is a DImode register or MEM.  */
894 int
895 nonimmediate_di_operand (op, mode)
896      rtx op;
897      Mmode mode;
898 {
899   if (register_operand (op, mode))
900     return TRUE;
901
902   if (mode != VOIDmode && GET_MODE (op) != VOIDmode && GET_MODE (op) != DImode)
903     return FALSE;
904
905   if (GET_CODE (op) == SUBREG)
906     op = SUBREG_REG (op);
907
908   if (GET_CODE (op) == MEM)
909     return memory_address_p (DImode, XEXP (op, 0));
910
911   return FALSE;
912 }
913
914 /* Returns true iff all the registers in the operands array
915    are in descending or ascending order.  */
916 int
917 fr30_check_multiple_regs (operands, num_operands, descending)
918      rtx * operands;
919      int   num_operands;
920      int   descending;
921 {
922   if (descending)
923     {
924       unsigned int prev_regno = 0;
925       
926       while (num_operands --)
927         {
928           if (GET_CODE (operands [num_operands]) != REG)
929             return 0;
930           
931           if (REGNO (operands [num_operands]) < prev_regno)
932             return 0;
933           
934           prev_regno = REGNO (operands [num_operands]);
935         }
936     }
937   else
938     {
939       unsigned int prev_regno = CONDITION_CODE_REGNUM;
940       
941       while (num_operands --)
942         {
943           if (GET_CODE (operands [num_operands]) != REG)
944             return 0;
945           
946           if (REGNO (operands [num_operands]) > prev_regno)
947             return 0;
948           
949           prev_regno = REGNO (operands [num_operands]);
950         }
951     }
952
953   return 1;
954 }
955
956 /*}}}*/
957 /*{{{  Instruction Output Routines  */
958
959 /* Output a double word move.
960    It must be REG<-REG, REG<-MEM, MEM<-REG or REG<-CONST.
961    On the FR30 we are contrained by the fact that it does not
962    support offsetable addresses, and so we have to load the
963    address of the secnd word into the second destination register
964    before we can use it.  */
965
966 rtx
967 fr30_move_double (operands)
968      rtx * operands;
969 {
970   rtx src  = operands[1];
971   rtx dest = operands[0];
972   enum rtx_code src_code = GET_CODE (src);
973   enum rtx_code dest_code = GET_CODE (dest);
974   enum machine_mode mode = GET_MODE (dest);
975   rtx val;
976
977   start_sequence ();
978
979   if (dest_code == REG)
980     {
981       if (src_code == REG)
982         {
983           int reverse = (REGNO (dest) == REGNO (src) + 1);
984           
985           /* We normally copy the low-numbered register first.  However, if
986              the first register of operand 0 is the same as the second register
987              of operand 1, we must copy in the opposite order.  */
988           emit_insn (gen_rtx_SET (VOIDmode,
989                                   operand_subword (dest, reverse, TRUE, mode),
990                                   operand_subword (src,  reverse, TRUE, mode)));
991           
992           emit_insn (gen_rtx_SET (VOIDmode,
993                               operand_subword (dest, !reverse, TRUE, mode),
994                               operand_subword (src,  !reverse, TRUE, mode)));
995         }
996       else if (src_code == MEM)
997         {
998           rtx addr = XEXP (src, 0);
999           int dregno = REGNO (dest);
1000           rtx dest0;
1001           rtx dest1;
1002           rtx new_mem;
1003           
1004           /* If the high-address word is used in the address, we
1005              must load it last.  Otherwise, load it first.  */
1006           int reverse = (refers_to_regno_p (dregno, dregno + 1, addr, 0) != 0);
1007
1008           if (GET_CODE (addr) != REG)
1009             abort ();
1010           
1011           dest0 = operand_subword (dest, reverse, TRUE, mode);
1012           dest1 = operand_subword (dest, !reverse, TRUE, mode);
1013
1014           if (reverse)
1015             {
1016               emit_insn (gen_rtx_SET (VOIDmode, dest1,
1017                                       adjust_address (src, SImode, 0)));
1018               emit_insn (gen_rtx_SET (SImode, dest0,
1019                                       gen_rtx_REG (SImode, REGNO (addr))));
1020               emit_insn (gen_rtx_SET (SImode, dest0,
1021                                       plus_constant (dest0, UNITS_PER_WORD)));
1022
1023               new_mem = gen_rtx_MEM (SImode, dest0);
1024               MEM_COPY_ATTRIBUTES (new_mem, src);
1025               
1026               emit_insn (gen_rtx_SET (VOIDmode, dest0, new_mem));
1027             }
1028           else
1029             {
1030               emit_insn (gen_rtx_SET (VOIDmode, dest0,
1031                                       adjust_address (src, SImode, 0)));
1032               emit_insn (gen_rtx_SET (SImode, dest1,
1033                                       gen_rtx_REG (SImode, REGNO (addr))));
1034               emit_insn (gen_rtx_SET (SImode, dest1,
1035                                       plus_constant (dest1, UNITS_PER_WORD)));
1036
1037               new_mem = gen_rtx_MEM (SImode, dest1);
1038               MEM_COPY_ATTRIBUTES (new_mem, src);
1039               
1040               emit_insn (gen_rtx_SET (VOIDmode, dest1, new_mem));
1041             }
1042         }
1043       else if (src_code == CONST_INT || src_code == CONST_DOUBLE)
1044         {
1045           rtx words[2];
1046           split_double (src, &words[0], &words[1]);
1047           emit_insn (gen_rtx_SET (VOIDmode,
1048                                   operand_subword (dest, 0, TRUE, mode),
1049                                   words[0]));
1050       
1051           emit_insn (gen_rtx_SET (VOIDmode,
1052                                   operand_subword (dest, 1, TRUE, mode),
1053                                   words[1]));
1054         }
1055     }
1056   else if (src_code == REG && dest_code == MEM)
1057     {
1058       rtx addr = XEXP (dest, 0);
1059       rtx src0;
1060       rtx src1;
1061
1062       if (GET_CODE (addr) != REG)
1063         abort ();
1064       
1065       src0 = operand_subword (src, 0, TRUE, mode);
1066       src1 = operand_subword (src, 1, TRUE, mode);
1067       
1068       emit_insn (gen_rtx_SET (VOIDmode, adjust_address (dest, SImode, 0),
1069                               src0));
1070
1071       if (REGNO (addr) == STACK_POINTER_REGNUM
1072           || REGNO (addr) == FRAME_POINTER_REGNUM)
1073         emit_insn (gen_rtx_SET (VOIDmode,
1074                                 adjust_address (dest, SImode, UNITS_PER_WORD),
1075                                 src1));
1076       else
1077         {
1078           rtx new_mem;
1079           
1080           /* We need a scratch register to hold the value of 'address + 4'.
1081              We ought to allow gcc to find one for us, but for now, just
1082              push one of the source registers.  */
1083           emit_insn (gen_movsi_push (src0));
1084           emit_insn (gen_movsi_internal (src0, addr));
1085           emit_insn (gen_addsi_small_int (src0, src0, GEN_INT (UNITS_PER_WORD)));
1086           
1087           new_mem = gen_rtx_MEM (SImode, src0);
1088           MEM_COPY_ATTRIBUTES (new_mem, dest);
1089           
1090           emit_insn (gen_rtx_SET (VOIDmode, new_mem, src1));
1091           emit_insn (gen_movsi_pop (src0));
1092         }
1093     }
1094   else
1095     /* This should have been prevented by the constraints on movdi_insn.  */
1096     abort ();
1097   
1098   val = get_insns ();
1099   end_sequence ();
1100
1101   return val;
1102 }