OSDN Git Service

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