OSDN Git Service

* MAINTAINERS: Add myself as a maintainer for the RX port.
[pf3gnuchains/gcc-fork.git] / gcc / config / rx / rx.c
1 /* Subroutines used for code generation on Renesas RX processors.
2    Copyright (C) 2008, 2009 Free Software Foundation, Inc.
3    Contributed by Red Hat.
4
5    This file is part of GCC.
6
7    GCC 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 3, or (at your option)
10    any later version.
11
12    GCC 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 GCC; see the file COPYING3.  If not see
19    <http://www.gnu.org/licenses/>.  */
20
21 /* To Do:
22
23  * Re-enable memory-to-memory copies and fix up reload.  */
24
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "tree.h"
30 #include "rtl.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "function.h"
40 #include "expr.h"
41 #include "optabs.h"
42 #include "libfuncs.h"
43 #include "recog.h"
44 #include "toplev.h"
45 #include "reload.h"
46 #include "df.h"
47 #include "ggc.h"
48 #include "tm_p.h"
49 #include "debug.h"
50 #include "target.h"
51 #include "target-def.h"
52 #include "langhooks.h"
53 \f
54 /* Return true if OP is a reference to an object in a small data area.  */
55
56 static bool
57 rx_small_data_operand (rtx op)
58 {
59   if (rx_small_data_limit == 0)
60     return false;
61
62   if (GET_CODE (op) == SYMBOL_REF)
63     return SYMBOL_REF_SMALL_P (op);
64
65   return false;
66 }
67
68 static bool
69 rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
70 {
71   if (RTX_OK_FOR_BASE (x, strict))
72     /* Register Indirect.  */
73     return true;
74
75   if (GET_MODE_SIZE (mode) == 4
76       && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
77     /* Pre-decrement Register Indirect or
78        Post-increment Register Indirect.  */
79     return RTX_OK_FOR_BASE (XEXP (x, 0), strict);
80
81   if (GET_CODE (x) == PLUS)
82     {
83       rtx arg1 = XEXP (x, 0);
84       rtx arg2 = XEXP (x, 1);
85       rtx index = NULL_RTX;
86
87       if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict))
88         index = arg2;
89       else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict))
90         index = arg1;
91       else
92         return false;
93
94       switch (GET_CODE (index))
95         {
96         case CONST_INT:
97           {
98             /* Register Relative: REG + INT.
99                Only positive, mode-aligned, mode-sized
100                displacements are allowed.  */
101             HOST_WIDE_INT val = INTVAL (index);
102             int factor;
103
104             if (val < 0)
105               return false;
106             
107             switch (GET_MODE_SIZE (mode))
108               {
109               default: 
110               case 4: factor = 4; break;
111               case 2: factor = 2; break;
112               case 1: factor = 1; break;
113               }
114
115             if (val > (65535 * factor))
116               return false;
117             return (val % factor) == 0;
118           }
119
120         case REG:
121           /* Unscaled Indexed Register Indirect: REG + REG
122              Size has to be "QI", REG has to be valid.  */
123           return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict);
124
125         case MULT:
126           {
127             /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
128                Factor has to equal the mode size, REG has to be valid.  */
129             rtx factor;
130
131             factor = XEXP (index, 1);
132             index = XEXP (index, 0);
133
134             return REG_P (index)
135               && RTX_OK_FOR_BASE (index, strict)
136               && CONST_INT_P (factor)
137               && GET_MODE_SIZE (mode) == INTVAL (factor);
138           }
139
140         default:
141           return false;
142         }
143     }
144
145   /* Small data area accesses turn into register relative offsets.  */
146   return rx_small_data_operand (x);
147 }
148
149 /* Returns TRUE for simple memory addreses, ie ones
150    that do not involve register indirect addressing
151    or pre/post increment/decrement.  */
152
153 bool
154 rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
155 {
156   rtx base, index;
157
158   if (! rx_is_legitimate_address
159       (mode, mem, reload_in_progress || reload_completed))
160     return false;
161
162   switch (GET_CODE (mem))
163     {
164     case REG:
165       /* Simple memory addresses are OK.  */
166       return true;
167
168     case PRE_DEC:
169     case POST_INC:
170       return false;
171
172     case PLUS:
173       /* Only allow REG+INT addressing.  */
174       base = XEXP (mem, 0);
175       index = XEXP (mem, 1);
176
177       return RX_REG_P (base) && CONST_INT_P (index);
178
179     case SYMBOL_REF:
180       /* Can happen when small data is being supported.
181          Assume that it will be resolved into GP+INT.  */
182       return true;
183
184     default:
185       gcc_unreachable ();
186     }
187 }
188
189 bool
190 rx_is_mode_dependent_addr (rtx addr)
191 {
192   if (GET_CODE (addr) == CONST)
193     addr = XEXP (addr, 0);
194
195   switch (GET_CODE (addr))
196     {
197       /* --REG and REG++ only work in SImode.  */
198     case PRE_DEC:
199     case POST_INC:
200       return true;
201
202     case MINUS:
203     case PLUS:
204       if (! REG_P (XEXP (addr, 0)))
205         return true;
206
207       addr = XEXP (addr, 1);
208
209       switch (GET_CODE (addr))
210         {
211         case REG:
212           /* REG+REG only works in SImode.  */
213           return true;
214
215         case CONST_INT:
216           /* REG+INT is only mode independent if INT is a
217              multiple of 4, positive and will fit into 8-bits.  */
218           if (((INTVAL (addr) & 3) == 0)
219               && IN_RANGE (INTVAL (addr), 4, 252))
220             return false;
221           return true;
222
223         case SYMBOL_REF:
224         case LABEL_REF:
225           return true;
226
227         case MULT:
228           gcc_assert (REG_P (XEXP (addr, 0)));
229           gcc_assert (CONST_INT_P (XEXP (addr, 1)));
230           /* REG+REG*SCALE is always mode dependent.  */
231           return true;
232
233         default:
234           /* Not recognized, so treat as mode dependent.  */
235           return true;
236         }
237
238     case CONST_INT:
239     case SYMBOL_REF:
240     case LABEL_REF:
241     case REG:
242       /* These are all mode independent.  */
243       return false;
244
245     default:
246       /* Everything else is unrecognized,
247          so treat as mode dependent.  */
248       return true;
249     }
250 }
251 \f
252
253 /* A C compound statement to output to stdio stream FILE the
254    assembler syntax for an instruction operand that is a memory
255    reference whose address is ADDR.  */
256
257 void
258 rx_print_operand_address (FILE * file, rtx addr)
259 {
260   switch (GET_CODE (addr))
261     {
262     case REG:
263       fprintf (file, "[");
264       rx_print_operand (file, addr, 0);
265       fprintf (file, "]");
266       break;
267
268     case PRE_DEC:
269       fprintf (file, "[-");
270       rx_print_operand (file, XEXP (addr, 0), 0);
271       fprintf (file, "]");
272       break;
273
274     case POST_INC:
275       fprintf (file, "[");
276       rx_print_operand (file, XEXP (addr, 0), 0);
277       fprintf (file, "+]");
278       break;
279
280     case PLUS:
281       {
282         rtx arg1 = XEXP (addr, 0);
283         rtx arg2 = XEXP (addr, 1);
284         rtx base, index;
285
286         if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true))
287           base = arg1, index = arg2;
288         else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true))
289           base = arg2, index = arg1;
290         else
291           {
292             rx_print_operand (file, arg1, 0);
293             fprintf (file, " + ");
294             rx_print_operand (file, arg2, 0);
295             break;
296           }
297
298         if (REG_P (index) || GET_CODE (index) == MULT)
299           {
300             fprintf (file, "[");
301             rx_print_operand (file, index, 'A');
302             fprintf (file, ",");
303           }
304         else /* GET_CODE (index) == CONST_INT  */
305           {
306             rx_print_operand (file, index, 'A');
307             fprintf (file, "[");
308           }
309         rx_print_operand (file, base, 0);
310         fprintf (file, "]");
311         break;
312       }
313
314     case LABEL_REF:
315     case SYMBOL_REF:
316     case CONST:
317       fprintf (file, "#");
318     default:
319       output_addr_const (file, addr);
320       break;
321     }
322 }
323
324 static void
325 rx_print_integer (FILE * file, HOST_WIDE_INT val)
326 {
327   if (IN_RANGE (val, -64, 64))
328     fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
329   else
330     fprintf (file,
331              TARGET_AS100_SYNTAX
332              ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX,
333              val);
334 }
335
336 static bool
337 rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
338 {
339   const char *  op = integer_asm_op (size, is_aligned);
340
341   if (! CONST_INT_P (x))
342     return default_assemble_integer (x, size, is_aligned);
343
344   if (op == NULL)
345     return false;
346   fputs (op, asm_out_file);
347
348   rx_print_integer (asm_out_file, INTVAL (x));
349   fputc ('\n', asm_out_file);
350   return true;
351 }
352
353
354 int rx_float_compare_mode;
355
356 /* Handles the insertion of a single operand into the assembler output.
357    The %<letter> directives supported are:
358
359      %A  Print an operand without a leading # character.
360      %B  Print an integer comparison name.
361      %C  Print a control register name.
362      %F  Print a condition code flag name.
363      %H  Print high part of a DImode register, integer or address.
364      %L  Print low part of a DImode register, integer or address.
365      %Q  If the operand is a MEM, then correctly generate
366          register indirect or register relative addressing.  */
367
368 void
369 rx_print_operand (FILE * file, rtx op, int letter)
370 {
371   switch (letter)
372     {
373     case 'A':
374       /* Print an operand without a leading #.  */
375       if (MEM_P (op))
376         op = XEXP (op, 0);
377
378       switch (GET_CODE (op))
379         {
380         case LABEL_REF:
381         case SYMBOL_REF:
382           output_addr_const (file, op);
383           break;
384         case CONST_INT:
385           fprintf (file, "%ld", (long) INTVAL (op));
386           break;
387         default:
388           rx_print_operand (file, op, 0);
389           break;
390         }
391       break;
392
393     case 'B':
394       switch (GET_CODE (op))
395         {
396         case LT:  fprintf (file, "lt"); break;
397         case GE:  fprintf (file, "ge"); break;
398         case GT:  fprintf (file, "gt"); break;
399         case LE:  fprintf (file, "le"); break;
400         case GEU: fprintf (file, "geu"); break;
401         case LTU: fprintf (file, "ltu"); break;
402         case GTU: fprintf (file, "gtu"); break;
403         case LEU: fprintf (file, "leu"); break;
404         case EQ:  fprintf (file, "eq"); break;
405         case NE:  fprintf (file, "ne"); break;
406         default:  debug_rtx (op); gcc_unreachable ();
407         }
408       break;
409
410     case 'C':
411       gcc_assert (CONST_INT_P (op));
412       switch (INTVAL (op))
413         {
414         case 0:   fprintf (file, "psw"); break;
415         case 2:   fprintf (file, "usp"); break;
416         case 3:   fprintf (file, "fpsw"); break;
417         case 4:   fprintf (file, "cpen"); break;
418         case 8:   fprintf (file, "bpsw"); break;
419         case 9:   fprintf (file, "bpc"); break;
420         case 0xa: fprintf (file, "isp"); break;
421         case 0xb: fprintf (file, "fintv"); break;
422         case 0xc: fprintf (file, "intb"); break;
423         default:
424           gcc_unreachable ();
425         }
426       break;
427
428     case 'F':
429       gcc_assert (CONST_INT_P (op));
430       switch (INTVAL (op))
431         {
432         case 0: case 'c': case 'C': fprintf (file, "C"); break;
433         case 1: case 'z': case 'Z': fprintf (file, "Z"); break;
434         case 2: case 's': case 'S': fprintf (file, "S"); break;
435         case 3: case 'o': case 'O': fprintf (file, "O"); break;
436         case 8: case 'i': case 'I': fprintf (file, "I"); break;
437         case 9: case 'u': case 'U': fprintf (file, "U"); break;
438         default:
439           gcc_unreachable ();
440         }
441       break;
442
443     case 'H':
444       if (REG_P (op))
445         fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
446       else if (CONST_INT_P (op))
447         {
448           fprintf (file, "#");
449           rx_print_integer (file, INTVAL (op) >> 32);
450         }
451       else
452         {
453           gcc_assert (MEM_P (op));
454
455           if (! WORDS_BIG_ENDIAN)
456             op = adjust_address (op, SImode, 4);
457           output_address (XEXP (op, 0));
458         }
459       break;
460
461     case 'L':
462       if (REG_P (op))
463         fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
464       else if (CONST_INT_P (op))
465         {
466           fprintf (file, "#");
467           rx_print_integer (file, INTVAL (op) & 0xffffffff);
468         }
469       else
470         {
471           gcc_assert (MEM_P (op));
472
473           if (WORDS_BIG_ENDIAN)
474             op = adjust_address (op, SImode, 4);
475           output_address (XEXP (op, 0));
476         }
477       break;
478
479     case 'Q':
480       if (MEM_P (op))
481         {
482           HOST_WIDE_INT offset;
483
484           op = XEXP (op, 0);
485
486           if (REG_P (op))
487             offset = 0;
488           else if (GET_CODE (op) == PLUS)
489             {
490               rtx displacement;
491
492               if (REG_P (XEXP (op, 0)))
493                 {
494                   displacement = XEXP (op, 1);
495                   op = XEXP (op, 0);
496                 }
497               else
498                 {
499                   displacement = XEXP (op, 0);
500                   op = XEXP (op, 1);
501                   gcc_assert (REG_P (op));
502                 }
503
504               gcc_assert (CONST_INT_P (displacement));
505               offset = INTVAL (displacement);
506               gcc_assert (offset >= 0);
507
508               fprintf (file, "%ld", offset);
509             }
510           else
511             gcc_unreachable ();
512
513           fprintf (file, "[");
514           rx_print_operand (file, op, 0);
515           fprintf (file, "].");
516
517           switch (GET_MODE_SIZE (GET_MODE (op)))
518             {
519             case 1:
520               gcc_assert (offset < 65535 * 1);
521               fprintf (file, "B");
522               break;
523             case 2:
524               gcc_assert (offset % 2 == 0);
525               gcc_assert (offset < 65535 * 2);
526               fprintf (file, "W");
527               break;
528             default:
529               gcc_assert (offset % 4 == 0);
530               gcc_assert (offset < 65535 * 4);
531               fprintf (file, "L");
532               break;
533             }
534           break;
535         }
536
537       /* Fall through.  */
538
539     default:
540       switch (GET_CODE (op))
541         {
542         case MULT:
543           /* Should be the scaled part of an
544              indexed register indirect address.  */
545           {
546             rtx base = XEXP (op, 0);
547             rtx index = XEXP (op, 1);
548
549             /* Check for a swaped index register and scaling factor.
550                Not sure if this can happen, but be prepared to handle it.  */
551             if (CONST_INT_P (base) && REG_P (index))
552               {
553                 rtx tmp = base;
554                 base = index;
555                 index = tmp;
556               }
557
558             gcc_assert (REG_P (base));
559             gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
560             gcc_assert (CONST_INT_P (index));
561             /* Do not try to verify the value of the scalar as it is based
562                on the mode of the MEM not the mode of the MULT.  (Which
563                will always be SImode).  */
564             fprintf (file, "%s", reg_names [REGNO (base)]);
565             break;
566           }
567
568         case MEM:
569           output_address (XEXP (op, 0));
570           break;
571
572         case PLUS:
573           output_address (op);
574           break;
575
576         case REG:
577           gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
578           fprintf (file, "%s", reg_names [REGNO (op)]);
579           break;
580
581         case SUBREG:
582           gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER);
583           fprintf (file, "%s", reg_names [subreg_regno (op)]);
584           break;
585
586           /* This will only be single precision....  */
587         case CONST_DOUBLE:
588           {
589             unsigned long val;
590             REAL_VALUE_TYPE rv;
591
592             REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
593             REAL_VALUE_TO_TARGET_SINGLE (rv, val);
594             fprintf (file, TARGET_AS100_SYNTAX ? "#0%lxH" : "#0x%lx", val);
595             break;
596           }
597
598         case CONST_INT:
599           fprintf (file, "#");
600           rx_print_integer (file, INTVAL (op));
601           break;
602
603         case SYMBOL_REF:
604         case CONST:
605         case LABEL_REF:
606         case CODE_LABEL:
607         case UNSPEC:
608           rx_print_operand_address (file, op);
609           break;
610
611         default:
612           gcc_unreachable ();
613         }
614       break;
615     }
616 }
617
618 /* Returns an assembler template for a move instruction.  */
619
620 char *
621 rx_gen_move_template (rtx * operands, bool is_movu)
622 {
623   static char  template [64];
624   const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
625   const char * src_template;
626   const char * dst_template;
627   rtx          dest = operands[0];
628   rtx          src  = operands[1];
629
630   /* Decide which extension, if any, should be given to the move instruction.  */
631   switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
632     {
633     case QImode:
634       /* The .B extension is not valid when
635          loading an immediate into a register.  */
636       if (! REG_P (dest) || ! CONST_INT_P (src))
637         extension = ".B";
638       break;
639     case HImode:
640       if (! REG_P (dest) || ! CONST_INT_P (src))
641         /* The .W extension is not valid when
642            loading an immediate into a register.  */
643         extension = ".W";
644       break;
645     case SFmode:
646     case SImode:
647       extension = ".L";
648       break;
649     case VOIDmode:
650       /* This mode is used by constants.  */
651       break;
652     default:
653       debug_rtx (src);
654       gcc_unreachable ();
655     }
656
657   if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
658     src_template = "%%gp(%A1)[r13]";
659   else
660     src_template = "%1";
661
662   if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
663     dst_template = "%%gp(%A0)[r13]";
664   else
665     dst_template = "%0";
666
667   sprintf (template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
668            extension, src_template, dst_template);
669   return template;
670 }
671
672 /* Returns an assembler template for a conditional branch instruction.  */
673
674 const char *
675 rx_gen_cond_branch_template (rtx condition, bool reversed)
676 {
677   enum rtx_code code = GET_CODE (condition);
678
679
680   if ((cc_status.flags & CC_NO_OVERFLOW) && ! rx_float_compare_mode)
681     gcc_assert (code != GT && code != GE && code != LE && code != LT);
682
683   if ((cc_status.flags & CC_NO_CARRY) || rx_float_compare_mode)
684     gcc_assert (code != GEU && code != GTU && code != LEU && code != LTU);
685
686   if (reversed)
687     {
688       if (rx_float_compare_mode)
689         code = reverse_condition_maybe_unordered (code);
690       else
691         code = reverse_condition (code);
692     }
693
694   /* We do not worry about encoding the branch length here as GAS knows
695      how to choose the smallest version, and how to expand a branch that
696      is to a destination that is out of range.  */
697
698   switch (code)
699     {
700     case UNEQ:      return "bo\t1f\n\tbeq\t%0\n1:";
701     case LTGT:      return "bo\t1f\n\tbne\t%0\n1:";
702     case UNLT:      return "bo\t1f\n\tbn\t%0\n1:";
703     case UNGE:      return "bo\t1f\n\tbpz\t%0\n1:";
704     case UNLE:      return "bo\t1f\n\tbgt\t1f\n\tbra\t%0\n1:";
705     case UNGT:      return "bo\t1f\n\tble\t1f\n\tbra\t%0\n1:";
706     case UNORDERED: return "bo\t%0";
707     case ORDERED:   return "bno\t%0";
708
709     case LT:        return rx_float_compare_mode ? "bn\t%0" : "blt\t%0";
710     case GE:        return rx_float_compare_mode ? "bpz\t%0" : "bge\t%0";
711     case GT:        return "bgt\t%0";
712     case LE:        return "ble\t%0";
713     case GEU:       return "bgeu\t%0";
714     case LTU:       return "bltu\t%0";
715     case GTU:       return "bgtu\t%0";
716     case LEU:       return "bleu\t%0";
717     case EQ:        return "beq\t%0";
718     case NE:        return "bne\t%0";
719     default:
720       gcc_unreachable ();
721     }
722 }
723 \f
724 /* Return VALUE rounded up to the next ALIGNMENT boundary.  */
725
726 static inline unsigned int
727 rx_round_up (unsigned int value, unsigned int alignment)
728 {
729   alignment -= 1;
730   return (value + alignment) & (~ alignment);
731 }
732
733 /* Return the number of bytes in the argument registers
734    occupied by an argument of type TYPE and mode MODE.  */
735
736 unsigned int
737 rx_function_arg_size (Mmode mode, const_tree type)
738 {
739   unsigned int num_bytes;
740
741   num_bytes = (mode == BLKmode)
742     ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
743   return rx_round_up (num_bytes, UNITS_PER_WORD);
744 }
745
746 #define NUM_ARG_REGS            4
747 #define MAX_NUM_ARG_BYTES       (NUM_ARG_REGS * UNITS_PER_WORD)
748
749 /* Return an RTL expression describing the register holding a function
750    parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
751    be passed on the stack.  CUM describes the previous parameters to the
752    function and NAMED is false if the parameter is part of a variable
753    parameter list, or the last named parameter before the start of a
754    variable parameter list.  */
755
756 rtx
757 rx_function_arg (Fargs * cum, Mmode mode, const_tree type, bool named)
758 {
759   unsigned int next_reg;
760   unsigned int bytes_so_far = *cum;
761   unsigned int size;
762   unsigned int rounded_size;
763
764   /* An exploded version of rx_function_arg_size.  */
765   size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
766
767   rounded_size = rx_round_up (size, UNITS_PER_WORD);
768
769   /* Don't pass this arg via registers if there
770      are insufficient registers to hold all of it.  */
771   if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES)
772     return NULL_RTX;
773
774   /* Unnamed arguments and the last named argument in a
775      variadic function are always passed on the stack.  */
776   if (!named)
777     return NULL_RTX;
778
779   /* Structures must occupy an exact number of registers,
780      otherwise they are passed on the stack.  */
781   if ((type == NULL || AGGREGATE_TYPE_P (type))
782       && (size % UNITS_PER_WORD) != 0)
783     return NULL_RTX;
784
785   next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
786
787   return gen_rtx_REG (mode, next_reg);
788 }
789
790 /* Return an RTL describing where a function return value of type RET_TYPE
791    is held.  */
792
793 static rtx
794 rx_function_value (const_tree ret_type,
795                    const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
796                    bool       outgoing ATTRIBUTE_UNUSED)
797 {
798   return gen_rtx_REG (TYPE_MODE (ret_type), FUNC_RETURN_REGNUM);
799 }
800
801 static bool
802 rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
803 {
804   HOST_WIDE_INT size;
805
806   if (TYPE_MODE (type) != BLKmode
807       && ! AGGREGATE_TYPE_P (type))
808     return false;
809
810   size = int_size_in_bytes (type);
811   /* Large structs and those whose size is not an
812      exact multiple of 4 are returned in memory.  */
813   return size < 1
814     || size > 16
815     || (size % UNITS_PER_WORD) != 0;
816 }
817
818 static rtx
819 rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
820                      int incoming ATTRIBUTE_UNUSED)
821 {
822   return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM);
823 }
824
825 static bool
826 rx_return_in_msb (const_tree valtype)
827 {
828   return TARGET_BIG_ENDIAN_DATA
829     && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE);
830 }
831
832 /* Returns true if the provided function has the specified attribute.  */
833
834 static inline bool
835 has_func_attr (const_tree decl, const char * func_attr)
836 {
837   if (decl == NULL_TREE)
838     decl = current_function_decl;
839
840   return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
841 }
842
843 /* Returns true if the provided function has
844    the "[fast_]interrupt" attribute.  */
845
846 static inline bool
847 is_fast_interrupt_func (const_tree decl)
848 {
849   return has_func_attr (decl, "interrupt")
850     || has_func_attr (decl, "fast_interrupt") ;
851 }
852
853 /* Returns true if the provided function has the "exception" attribute.  */
854
855 static inline bool
856 is_exception_func (const_tree decl)
857 {
858   return has_func_attr (decl, "exception");
859 }
860
861 /* Returns true if the provided function has the "naked" attribute.  */
862
863 static inline bool
864 is_naked_func (const_tree decl)
865 {
866   return has_func_attr (decl, "naked");
867 }
868 \f
869 static bool use_fixed_regs = false;
870
871 void
872 rx_conditional_register_usage (void)
873 {
874   static bool using_fixed_regs = false;
875
876   if (rx_small_data_limit > 0)
877     fixed_regs[GP_BASE_REGNUM] = call_used_regs [GP_BASE_REGNUM] = 1;
878
879   if (use_fixed_regs != using_fixed_regs)
880     {
881       static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
882       static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
883
884       if (use_fixed_regs)
885         {
886           unsigned int switched = 0;
887           unsigned int r;
888
889           /* This is for fast interrupt handlers.  Any register in
890              the range r10 to r13 (inclusive) that is currently
891              marked as fixed is now a viable, call-saved register.
892              All other registers are fixed.  */
893           memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
894           memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
895           
896           for (r = 1; r < 10; r++)
897             fixed_regs[r] = call_used_regs[r] = 1;
898           
899           for (r = 10; r <= 13; r++)
900             if (fixed_regs[r])
901               {
902                 fixed_regs[r] = 0;
903                 call_used_regs[r] = 1;
904                 ++ switched;
905               }
906             else
907               {
908                 fixed_regs[r] = 1;
909                 call_used_regs[r] = 1;
910               }
911
912           fixed_regs[14] = call_used_regs[14] = 1;
913           fixed_regs[15] = call_used_regs[15] = 1;
914
915           if (switched == 0)
916             {
917               static bool warned = false;
918
919               if (! warned)
920                 {
921                   warning (0, "no fixed registers available "
922                            "for use by fast interrupt handler");
923                   warned = true;
924                 }
925             }
926         }
927       else
928         {
929           /* Restore the normal register masks.  */
930           memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
931           memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
932         }
933
934       using_fixed_regs = use_fixed_regs;
935     }
936 }
937
938 /* Perform any actions necessary before starting to compile FNDECL.
939    For the RX we use this to make sure that we have the correct
940    set of register masks selected.  If FNDECL is NULL then we are
941    compiling top level things.  */
942
943 static void
944 rx_set_current_function (tree fndecl)
945 {
946   /* Remember the last target of rx_set_current_function.  */
947   static tree rx_previous_fndecl;
948   bool prev_was_interrupt;
949   bool current_is_interrupt;
950
951   /* Only change the context if the function changes.  This hook is called
952      several times in the course of compiling a function, and we don't want
953      to slow things down too much or call target_reinit when it isn't safe.  */
954   if (fndecl == rx_previous_fndecl)
955     return;
956
957   prev_was_interrupt
958     = rx_previous_fndecl
959     ? is_fast_interrupt_func (rx_previous_fndecl) : false;
960   current_is_interrupt
961     = fndecl ? is_fast_interrupt_func (fndecl) : false;
962       
963   if (prev_was_interrupt != current_is_interrupt)
964     {
965       use_fixed_regs = current_is_interrupt;
966       target_reinit ();
967     }
968       
969   rx_previous_fndecl = fndecl;
970 }
971 \f
972 /* Typical stack layout should looks like this after the function's prologue:
973
974                             |    |
975                               --                       ^
976                             |    | \                   |
977                             |    |   arguments saved   | Increasing
978                             |    |   on the stack      |  addresses
979     PARENT   arg pointer -> |    | /
980   -------------------------- ---- -------------------
981     CHILD                   |ret |   return address
982                               --
983                             |    | \
984                             |    |   call saved
985                             |    |   registers
986                             |    | /
987                               --
988                             |    | \
989                             |    |   local
990                             |    |   variables
991         frame pointer ->    |    | /
992                               --
993                             |    | \
994                             |    |   outgoing          | Decreasing
995                             |    |   arguments         |  addresses
996    current stack pointer -> |    | /                   |
997   -------------------------- ---- ------------------   V
998                             |    |                 */
999
1000 static unsigned int
1001 bit_count (unsigned int x)
1002 {
1003   const unsigned int m1 = 0x55555555;
1004   const unsigned int m2 = 0x33333333;
1005   const unsigned int m4 = 0x0f0f0f0f;
1006
1007   x -= (x >> 1) & m1;
1008   x = (x & m2) + ((x >> 2) & m2);
1009   x = (x + (x >> 4)) & m4;
1010   x += x >>  8;
1011
1012   return (x + (x >> 16)) & 0x3f;
1013 }
1014
1015 /* Returns either the lowest numbered and highest numbered registers that
1016    occupy the call-saved area of the stack frame, if the registers are
1017    stored as a contiguous block, or else a bitmask of the individual
1018    registers if they are stored piecemeal.
1019
1020    Also computes the size of the frame and the size of the outgoing
1021    arguments block (in bytes).  */
1022
1023 static void
1024 rx_get_stack_layout (unsigned int * lowest,
1025                      unsigned int * highest,
1026                      unsigned int * register_mask,
1027                      unsigned int * frame_size,
1028                      unsigned int * stack_size)
1029 {
1030   unsigned int reg;
1031   unsigned int low;
1032   unsigned int high;
1033   unsigned int fixed_reg = 0;
1034   unsigned int save_mask;
1035   unsigned int pushed_mask;
1036   unsigned int unneeded_pushes;
1037
1038   if (is_naked_func (NULL_TREE)
1039       || is_fast_interrupt_func (NULL_TREE))
1040     {
1041       /* Naked functions do not create their own stack frame.
1042          Instead the programmer must do that for us.
1043
1044          Fast interrupt handlers use fixed registers that have
1045          been epsecially released to the function, so they do
1046          not need or want a stack frame.  */
1047       * lowest = 0;
1048       * highest = 0;
1049       * register_mask = 0;
1050       * frame_size = 0;
1051       * stack_size = 0;
1052       return;
1053     }
1054
1055   for (save_mask = high = low = 0, reg = 1; reg < FIRST_PSEUDO_REGISTER; reg++)
1056     {
1057       if (df_regs_ever_live_p (reg)
1058           && (! call_used_regs[reg]
1059               /* Even call clobbered registered must
1060                  be pushed inside exception handlers.  */
1061               || is_exception_func (NULL_TREE)))
1062         {
1063           if (low == 0)
1064             low = reg;
1065           high = reg;
1066
1067           save_mask |= 1 << reg;
1068         }
1069
1070       /* Remember if we see a fixed register
1071          after having found the low register.  */
1072       if (low != 0 && fixed_reg == 0 && fixed_regs [reg])
1073         fixed_reg = reg;
1074     }
1075
1076   /* Decide if it would be faster fill in the call-saved area of the stack
1077      frame using multiple PUSH instructions instead of a single PUSHM
1078      instruction.
1079
1080      SAVE_MASK is a bitmask of the registers that must be stored in the
1081      call-save area.  PUSHED_MASK is a bitmask of the registers that would
1082      be pushed into the area if we used a PUSHM instruction.  UNNEEDED_PUSHES
1083      is a bitmask of those registers in pushed_mask that are not in
1084      save_mask.
1085
1086      We use a simple heuristic that says that it is better to use
1087      multiple PUSH instructions if the number of unnecessary pushes is
1088      greater than the number of necessary pushes.
1089
1090      We also use multiple PUSH instructions if there are any fixed registers
1091      between LOW and HIGH.  The only way that this can happen is if the user
1092      has specified --fixed-<reg-name> on the command line and in such
1093      circumstances we do not want to touch the fixed registers at all.
1094
1095      FIXME: Is it worth improving this heuristic ?  */
1096   pushed_mask = (-1 << low) & ~(-1 << (high + 1));
1097   unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
1098
1099   if ((fixed_reg && fixed_reg <= high)
1100       || (optimize_function_for_speed_p (cfun)
1101           && bit_count (save_mask) < bit_count (unneeded_pushes)))
1102     {
1103       /* Use multiple pushes.  */
1104       * lowest = 0;
1105       * highest = 0;
1106       * register_mask = save_mask;
1107     }
1108   else
1109     {
1110       /* Use one push multiple instruction.  */
1111       * lowest = low;
1112       * highest = high;
1113       * register_mask = 0;
1114     }
1115
1116   * frame_size = rx_round_up
1117     (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT);
1118
1119   if (crtl->args.size > 0)
1120     * frame_size += rx_round_up
1121       (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT);
1122
1123   * stack_size = rx_round_up
1124     (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT);
1125 }
1126
1127 /* Generate a PUSHM instruction that matches the given operands.  */
1128
1129 void
1130 rx_emit_stack_pushm (rtx * operands)
1131 {
1132   HOST_WIDE_INT last_reg;
1133   rtx first_push;
1134
1135   gcc_assert (CONST_INT_P (operands[0]));
1136   last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1;
1137
1138   gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1139   first_push = XVECEXP (operands[1], 0, 1);
1140   gcc_assert (SET_P (first_push));
1141   first_push = SET_SRC (first_push);
1142   gcc_assert (REG_P (first_push));
1143
1144   asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
1145                reg_names [REGNO (first_push)],
1146                reg_names [REGNO (first_push) + last_reg]);
1147   
1148 }
1149
1150 /* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate.  */
1151
1152 static rtx
1153 gen_rx_store_vector (unsigned int low, unsigned int high)
1154 {
1155   unsigned int i;
1156   unsigned int count = (high - low) + 2;
1157   rtx vector;
1158
1159   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1160
1161   XVECEXP (vector, 0, 0) =
1162     gen_rtx_SET (SImode, stack_pointer_rtx,
1163                  gen_rtx_MINUS (SImode, stack_pointer_rtx,
1164                                 GEN_INT ((count - 1) * UNITS_PER_WORD)));
1165
1166   for (i = 0; i < count - 1; i++)
1167     XVECEXP (vector, 0, i + 1) =
1168       gen_rtx_SET (SImode,
1169                    gen_rtx_MEM (SImode,
1170                                 i == 0 ? stack_pointer_rtx
1171                                 : gen_rtx_MINUS (SImode, stack_pointer_rtx,
1172                                                  GEN_INT (i * UNITS_PER_WORD))),
1173                    gen_rtx_REG (SImode, low + i));
1174
1175   return vector;
1176 }
1177
1178 void
1179 rx_expand_prologue (void)
1180 {
1181   unsigned int stack_size;
1182   unsigned int frame_size;
1183   unsigned int mask;
1184   unsigned int low;
1185   unsigned int high;
1186   rtx insn;
1187
1188   /* Naked functions use their own, programmer provided prologues.  */
1189   if (is_naked_func (NULL_TREE)
1190       /* Fast interrupt functions never use the stack.  */
1191       || is_fast_interrupt_func (NULL_TREE))
1192     return;
1193
1194   rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1195
1196   /* If we use any of the callee-saved registers, save them now.  */
1197   if (mask)
1198     {
1199       unsigned int reg;
1200
1201       /* Push registers in reverse order.  */
1202       for (reg = FIRST_PSEUDO_REGISTER; reg --;)
1203         if (mask & (1 << reg))
1204           {
1205             insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
1206             RTX_FRAME_RELATED_P (insn) = 1;
1207           }
1208     }
1209   else if (low)
1210     {
1211       if (high == low)
1212         insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
1213       else
1214         insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1)
1215                                                     * UNITS_PER_WORD),
1216                                            gen_rx_store_vector (low, high)));
1217       RTX_FRAME_RELATED_P (insn) = 1;
1218     }
1219
1220   /* If needed, set up the frame pointer.  */
1221   if (frame_pointer_needed)
1222     {
1223       if (frame_size)
1224         insn = emit_insn (gen_addsi3 (frame_pointer_rtx, stack_pointer_rtx,
1225                                       GEN_INT (- (HOST_WIDE_INT) frame_size)));
1226       else
1227         insn = emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
1228
1229       RTX_FRAME_RELATED_P (insn) = 1;
1230     }
1231
1232   insn = NULL_RTX;
1233
1234   /* Allocate space for the outgoing args.
1235      If the stack frame has not already been set up then handle this as well.  */
1236   if (stack_size)
1237     {
1238       if (frame_size)
1239         {
1240           if (frame_pointer_needed)
1241             insn = emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_rtx,
1242                                           GEN_INT (- (HOST_WIDE_INT)
1243                                                    stack_size)));
1244           else
1245             insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1246                                           GEN_INT (- (HOST_WIDE_INT)
1247                                                    (frame_size + stack_size))));
1248         }
1249       else
1250         insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1251                                       GEN_INT (- (HOST_WIDE_INT) stack_size)));
1252     }
1253   else if (frame_size)
1254     {
1255       if (! frame_pointer_needed)
1256         insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1257                                       GEN_INT (- (HOST_WIDE_INT) frame_size)));
1258       else
1259         insn = emit_move_insn (stack_pointer_rtx, frame_pointer_rtx);
1260     }
1261
1262   if (insn != NULL_RTX)
1263     RTX_FRAME_RELATED_P (insn) = 1;
1264 }
1265
1266 static void
1267 rx_output_function_prologue (FILE * file,
1268                              HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
1269 {
1270   if (is_fast_interrupt_func (NULL_TREE))
1271     asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
1272
1273   if (is_exception_func (NULL_TREE))
1274     asm_fprintf (file, "\t; Note: Exception Handler\n");
1275
1276   if (is_naked_func (NULL_TREE))
1277     asm_fprintf (file, "\t; Note: Naked Function\n");
1278
1279   if (cfun->static_chain_decl != NULL)
1280     asm_fprintf (file, "\t; Note: Nested function declared "
1281                  "inside another function.\n");
1282
1283   if (crtl->calls_eh_return)
1284     asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n");
1285 }
1286
1287 /* Generate a POPM or RTSD instruction that matches the given operands.  */
1288
1289 void
1290 rx_emit_stack_popm (rtx * operands, bool is_popm)
1291 {
1292   HOST_WIDE_INT stack_adjust;
1293   HOST_WIDE_INT last_reg;
1294   rtx first_push;
1295
1296   gcc_assert (CONST_INT_P (operands[0]));
1297   stack_adjust = INTVAL (operands[0]);
1298   
1299   gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1300   last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3);
1301
1302   first_push = XVECEXP (operands[1], 0, 1);
1303   gcc_assert (SET_P (first_push));
1304   first_push = SET_DEST (first_push);
1305   gcc_assert (REG_P (first_push));
1306
1307   if (is_popm)
1308     asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n",
1309                  reg_names [REGNO (first_push)],
1310                  reg_names [REGNO (first_push) + last_reg]);
1311   else
1312     asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n",
1313                  (int) stack_adjust,
1314                  reg_names [REGNO (first_push)],
1315                  reg_names [REGNO (first_push) + last_reg]);
1316 }
1317
1318 /* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate.  */
1319
1320 static rtx
1321 gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high)
1322 {
1323   unsigned int i;
1324   unsigned int bias = 3;
1325   unsigned int count = (high - low) + bias;
1326   rtx vector;
1327
1328   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1329
1330   XVECEXP (vector, 0, 0) =
1331     gen_rtx_SET (SImode, stack_pointer_rtx,
1332                  plus_constant (stack_pointer_rtx, adjust));
1333
1334   for (i = 0; i < count - 2; i++)
1335     XVECEXP (vector, 0, i + 1) =
1336       gen_rtx_SET (SImode,
1337                    gen_rtx_REG (SImode, low + i),
1338                    gen_rtx_MEM (SImode,
1339                                 i == 0 ? stack_pointer_rtx
1340                                 : plus_constant (stack_pointer_rtx,
1341                                                  i * UNITS_PER_WORD)));
1342
1343   XVECEXP (vector, 0, count - 1) = gen_rtx_RETURN (VOIDmode);
1344
1345   return vector;
1346 }
1347   
1348 /* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate.  */
1349
1350 static rtx
1351 gen_rx_popm_vector (unsigned int low, unsigned int high)
1352 {
1353   unsigned int i;  
1354   unsigned int count = (high - low) + 2;
1355   rtx vector;
1356
1357   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1358
1359   XVECEXP (vector, 0, 0) =
1360     gen_rtx_SET (SImode, stack_pointer_rtx,
1361                  plus_constant (stack_pointer_rtx,
1362                                 (count - 1) * UNITS_PER_WORD));
1363
1364   for (i = 0; i < count - 1; i++)
1365     XVECEXP (vector, 0, i + 1) =
1366       gen_rtx_SET (SImode,
1367                    gen_rtx_REG (SImode, low + i),
1368                    gen_rtx_MEM (SImode,
1369                                 i == 0 ? stack_pointer_rtx
1370                                 : plus_constant (stack_pointer_rtx,
1371                                                  i * UNITS_PER_WORD)));
1372
1373   return vector;
1374 }
1375   
1376 void
1377 rx_expand_epilogue (bool is_sibcall)
1378 {
1379   unsigned int low;
1380   unsigned int high;
1381   unsigned int frame_size;
1382   unsigned int stack_size;
1383   unsigned int register_mask;
1384   unsigned int regs_size;
1385   unsigned HOST_WIDE_INT total_size;
1386
1387   if (is_naked_func (NULL_TREE))
1388     {
1389       /* Naked functions use their own, programmer provided epilogues.
1390          But, in order to keep gcc happy we have to generate some kind of
1391          epilogue RTL.  */
1392       emit_jump_insn (gen_naked_return ());
1393       return;
1394     }
1395
1396   rx_get_stack_layout (& low, & high, & register_mask,
1397                        & frame_size, & stack_size);
1398
1399   total_size = frame_size + stack_size;
1400   regs_size = ((high - low) + 1) * UNITS_PER_WORD;
1401
1402   /* See if we are unable to use the special stack frame deconstruct and
1403      return instructions.  In most cases we can use them, but the exceptions
1404      are:
1405
1406      - Sibling calling functions deconstruct the frame but do not return to
1407        their caller.  Instead they branch to their sibling and allow their
1408        return instruction to return to this function's parent.
1409
1410      - Fast interrupt and exception handling functions have to use special
1411        return instructions.
1412
1413      - Functions where we have pushed a fragmented set of registers into the
1414        call-save area must have the same set of registers popped.  */
1415   if (is_sibcall
1416       || is_fast_interrupt_func (NULL_TREE)
1417       || is_exception_func (NULL_TREE)
1418       || register_mask)
1419     {
1420       /* Cannot use the special instructions - deconstruct by hand.  */
1421       if (total_size)
1422         emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1423                                GEN_INT (total_size)));
1424
1425       if (register_mask)
1426         {
1427           unsigned int reg;
1428
1429           for (reg = 0; reg < FIRST_PSEUDO_REGISTER; reg ++)
1430             if (register_mask & (1 << reg))
1431               emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
1432         }
1433       else if (low)
1434         {
1435           if (high == low)
1436             emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
1437           else
1438             emit_insn (gen_stack_popm (GEN_INT (regs_size),
1439                                        gen_rx_popm_vector (low, high)));
1440         }
1441
1442       if (is_fast_interrupt_func (NULL_TREE))
1443         emit_jump_insn (gen_fast_interrupt_return ());
1444       else if (is_exception_func (NULL_TREE))
1445         emit_jump_insn (gen_exception_return ());
1446       else if (! is_sibcall)
1447         emit_jump_insn (gen_simple_return ());
1448
1449       return;
1450     }
1451
1452   /* If we allocated space on the stack, free it now.  */
1453   if (total_size)
1454     {
1455       unsigned HOST_WIDE_INT rtsd_size;
1456
1457       /* See if we can use the RTSD instruction.  */
1458       rtsd_size = total_size + regs_size;
1459       if (rtsd_size < 1024 && (rtsd_size % 4) == 0)
1460         {
1461           if (low)
1462             emit_jump_insn (gen_pop_and_return
1463                             (GEN_INT (rtsd_size),
1464                              gen_rx_rtsd_vector (rtsd_size, low, high)));
1465           else
1466             emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size)));
1467
1468           return;
1469         }
1470
1471       emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
1472                              GEN_INT (total_size)));
1473     }
1474
1475   if (low)
1476     emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size),
1477                                         gen_rx_rtsd_vector (regs_size,
1478                                                             low, high)));
1479   else
1480     emit_jump_insn (gen_simple_return ());
1481 }
1482
1483
1484 /* Compute the offset (in words) between FROM (arg pointer
1485    or frame pointer) and TO (frame pointer or stack pointer).
1486    See ASCII art comment at the start of rx_expand_prologue
1487    for more information.  */
1488
1489 int
1490 rx_initial_elimination_offset (int from, int to)
1491 {
1492   unsigned int low;
1493   unsigned int high;
1494   unsigned int frame_size;
1495   unsigned int stack_size;
1496   unsigned int mask;
1497
1498   rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1499
1500   if (from == ARG_POINTER_REGNUM)
1501     {
1502       /* Extend the computed size of the stack frame to
1503          include the registers pushed in the prologue.  */
1504       if (low)
1505         frame_size += ((high - low) + 1) * UNITS_PER_WORD;
1506       else
1507         frame_size += bit_count (mask) * UNITS_PER_WORD;
1508
1509       /* Remember to include the return address.  */
1510       frame_size += 1 * UNITS_PER_WORD;
1511
1512       if (to == FRAME_POINTER_REGNUM)
1513         return frame_size;
1514
1515       gcc_assert (to == STACK_POINTER_REGNUM);
1516       return frame_size + stack_size;
1517     }
1518
1519   gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM);
1520   return stack_size;
1521 }
1522
1523 /* Update the status of the condition
1524    codes (cc0) based on the given INSN.  */
1525
1526 void
1527 rx_notice_update_cc (rtx body, rtx insn)
1528 {
1529   switch (get_attr_cc (insn))
1530     {
1531     case CC_NONE:
1532       /* Insn does not affect cc0 at all.  */
1533       break;
1534     case CC_CLOBBER:
1535       /* Insn doesn't leave cc0 in a usable state.  */
1536       CC_STATUS_INIT;
1537       break;
1538     case CC_SET_ZSOC:
1539       /* The insn sets all the condition code bits.  */
1540       CC_STATUS_INIT;
1541       cc_status.value1 = SET_SRC (body);
1542       break;
1543     case CC_SET_ZSO:
1544       /* Insn sets the Z,S and O flags, but not the C flag.  */
1545       CC_STATUS_INIT;
1546       cc_status.flags |= CC_NO_CARRY;
1547       /* Do not set the value1 field in this case.  The final_scan_insn()
1548          function naively believes that if cc_status.value1 is set then
1549          it can eliminate *any* comparison against that value, even if
1550          the type of comparison cannot be satisfied by the range of flag
1551          bits being set here.  See gcc.c-torture/execute/20041210-1.c
1552          for an example of this in action.  */
1553       break;
1554     case CC_SET_ZS:
1555       /* Insn sets the Z and S flags, but not the O or C flags.  */
1556       CC_STATUS_INIT;
1557       cc_status.flags |= (CC_NO_CARRY | CC_NO_OVERFLOW);
1558       /* See comment above regarding cc_status.value1.  */
1559       break;
1560     default:
1561       gcc_unreachable ();
1562     }
1563 }
1564
1565 /* Decide if a variable should go into one of the small data sections.  */
1566
1567 static bool
1568 rx_in_small_data (const_tree decl)
1569 {
1570   int size;
1571   const_tree section;
1572
1573   if (rx_small_data_limit == 0)
1574     return false;
1575
1576   if (TREE_CODE (decl) != VAR_DECL)
1577     return false;
1578
1579   /* We do not put read-only variables into a small data area because
1580      they would be placed with the other read-only sections, far away
1581      from the read-write data sections, and we only have one small
1582      data area pointer.
1583      Similarly commons are placed in the .bss section which might be
1584      far away (and out of alignment with respect to) the .data section.  */
1585   if (TREE_READONLY (decl) || DECL_COMMON (decl))
1586     return false;
1587
1588   section = DECL_SECTION_NAME (decl);
1589   if (section)
1590     {
1591       const char * const name = TREE_STRING_POINTER (section);
1592
1593       return (strcmp (name, "D_2") == 0) || (strcmp (name, "B_2") == 0);
1594     }
1595
1596   size = int_size_in_bytes (TREE_TYPE (decl));
1597
1598   return (size > 0) && (size <= rx_small_data_limit);
1599 }
1600
1601 /* Return a section for X.
1602    The only special thing we do here is to honor small data.  */
1603
1604 static section *
1605 rx_select_rtx_section (enum machine_mode mode,
1606                        rtx x,
1607                        unsigned HOST_WIDE_INT align)
1608 {
1609   if (rx_small_data_limit > 0
1610       && GET_MODE_SIZE (mode) <= rx_small_data_limit
1611       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
1612     return sdata_section;
1613
1614   return default_elf_select_rtx_section (mode, x, align);
1615 }
1616
1617 static section *
1618 rx_select_section (tree decl,
1619                    int reloc,
1620                    unsigned HOST_WIDE_INT align)
1621 {
1622   if (rx_small_data_limit > 0)
1623     {
1624       switch (categorize_decl_for_section (decl, reloc))
1625         {
1626         case SECCAT_SDATA:      return sdata_section;
1627         case SECCAT_SBSS:       return sbss_section;
1628         case SECCAT_SRODATA:
1629           /* Fall through.  We do not put small, read only
1630              data into the C_2 section because we are not
1631              using the C_2 section.  We do not use the C_2
1632              section because it is located with the other
1633              read-only data sections, far away from the read-write
1634              data sections and we only have one small data
1635              pointer (r13).  */
1636         default:
1637           break;
1638         }
1639     }
1640
1641   /* If we are supporting the Renesas assembler
1642      we cannot use mergeable sections.  */
1643   if (TARGET_AS100_SYNTAX)
1644     switch (categorize_decl_for_section (decl, reloc))
1645       {
1646       case SECCAT_RODATA_MERGE_CONST:
1647       case SECCAT_RODATA_MERGE_STR_INIT:
1648       case SECCAT_RODATA_MERGE_STR:
1649         return readonly_data_section;
1650
1651       default:
1652         break;
1653       }
1654
1655   return default_elf_select_section (decl, reloc, align);
1656 }
1657 \f
1658 enum rx_builtin
1659 {
1660   RX_BUILTIN_BRK,
1661   RX_BUILTIN_CLRPSW,
1662   RX_BUILTIN_INT,
1663   RX_BUILTIN_MACHI,
1664   RX_BUILTIN_MACLO,
1665   RX_BUILTIN_MULHI,
1666   RX_BUILTIN_MULLO,
1667   RX_BUILTIN_MVFACHI,
1668   RX_BUILTIN_MVFACMI,
1669   RX_BUILTIN_MVFC,
1670   RX_BUILTIN_MVTACHI,
1671   RX_BUILTIN_MVTACLO,
1672   RX_BUILTIN_MVTC,
1673   RX_BUILTIN_RACW,
1674   RX_BUILTIN_REVW,
1675   RX_BUILTIN_RMPA,
1676   RX_BUILTIN_ROUND,
1677   RX_BUILTIN_SAT,
1678   RX_BUILTIN_SETPSW,
1679   RX_BUILTIN_WAIT,
1680   RX_BUILTIN_max
1681 };
1682
1683 static void
1684 rx_init_builtins (void)
1685 {
1686 #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE)           \
1687   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1688                         build_function_type_list (RET_TYPE##_type_node, \
1689                                                   ARG_TYPE##_type_node, \
1690                                                   NULL_TREE),           \
1691                         RX_BUILTIN_##UC_NAME,                           \
1692                         BUILT_IN_MD, NULL, NULL_TREE)
1693
1694 #define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
1695   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1696                         build_function_type_list (RET_TYPE##_type_node, \
1697                                                   ARG_TYPE1##_type_node,\
1698                                                   ARG_TYPE2##_type_node,\
1699                                                   NULL_TREE),           \
1700                         RX_BUILTIN_##UC_NAME,                           \
1701                         BUILT_IN_MD, NULL, NULL_TREE)
1702
1703 #define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
1704   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1705                         build_function_type_list (RET_TYPE##_type_node, \
1706                                                   ARG_TYPE1##_type_node,\
1707                                                   ARG_TYPE2##_type_node,\
1708                                                   ARG_TYPE3##_type_node,\
1709                                                   NULL_TREE),           \
1710                         RX_BUILTIN_##UC_NAME,                           \
1711                         BUILT_IN_MD, NULL, NULL_TREE)
1712
1713   ADD_RX_BUILTIN1 (BRK,     "brk",     void,  void);
1714   ADD_RX_BUILTIN1 (CLRPSW,  "clrpsw",  void,  integer);
1715   ADD_RX_BUILTIN1 (SETPSW,  "setpsw",  void,  integer);
1716   ADD_RX_BUILTIN1 (INT,     "int",     void,  integer);
1717   ADD_RX_BUILTIN2 (MACHI,   "machi",   void,  intSI, intSI);
1718   ADD_RX_BUILTIN2 (MACLO,   "maclo",   void,  intSI, intSI);
1719   ADD_RX_BUILTIN2 (MULHI,   "mulhi",   void,  intSI, intSI);
1720   ADD_RX_BUILTIN2 (MULLO,   "mullo",   void,  intSI, intSI);
1721   ADD_RX_BUILTIN1 (MVFACHI, "mvfachi", intSI, void);
1722   ADD_RX_BUILTIN1 (MVFACMI, "mvfacmi", intSI, void);
1723   ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void,  intSI);
1724   ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void,  intSI);
1725   ADD_RX_BUILTIN1 (RMPA,    "rmpa",    void,  void);
1726   ADD_RX_BUILTIN1 (MVFC,    "mvfc",    intSI, integer);
1727   ADD_RX_BUILTIN2 (MVTC,    "mvtc",    void,  integer, integer);
1728   ADD_RX_BUILTIN1 (RACW,    "racw",    void,  integer);
1729   ADD_RX_BUILTIN1 (ROUND,   "round",   intSI, float);
1730   ADD_RX_BUILTIN1 (REVW,    "revw",    intSI, intSI);
1731   ADD_RX_BUILTIN1 (SAT,     "sat",     intSI, intSI);
1732   ADD_RX_BUILTIN1 (WAIT,    "wait",    void,  void);
1733 }
1734
1735 static rtx
1736 rx_expand_builtin_stz (rtx arg, rtx target, rtx (* gen_func)(rtx, rtx))
1737 {
1738   if (! CONST_INT_P (arg))
1739     return NULL_RTX;
1740
1741   if (target == NULL_RTX || ! REG_P (target))
1742     target = gen_reg_rtx (SImode);
1743
1744   emit_insn (gen_func (target, arg));
1745
1746   return target;
1747 }
1748
1749 static rtx
1750 rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
1751 {
1752   if (reg && ! REG_P (arg))
1753     arg = force_reg (SImode, arg);
1754
1755   emit_insn (gen_func (arg));
1756
1757   return NULL_RTX;
1758 }
1759
1760 static rtx
1761 rx_expand_builtin_mvtc (tree exp)
1762 {
1763   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1764   rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
1765
1766   if (! CONST_INT_P (arg1))
1767     return NULL_RTX;
1768
1769   if (! REG_P (arg2))
1770     arg2 = force_reg (SImode, arg2);
1771
1772   emit_insn (gen_mvtc (arg1, arg2));
1773
1774   return NULL_RTX;
1775 }
1776
1777 static rtx
1778 rx_expand_builtin_mvfc (tree t_arg, rtx target)
1779 {
1780   rtx arg = expand_normal (t_arg);
1781
1782   if (! CONST_INT_P (arg))
1783     return NULL_RTX;
1784
1785   if (! REG_P (target))
1786     target = force_reg (SImode, target);
1787
1788   emit_insn (gen_mvfc (target, arg));
1789
1790   return target;
1791 }
1792
1793 static rtx
1794 rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
1795 {
1796   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1797   rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
1798
1799   if (! REG_P (arg1))
1800     arg1 = force_reg (SImode, arg1);
1801
1802   if (! REG_P (arg2))
1803     arg2 = force_reg (SImode, arg2);
1804
1805   emit_insn (gen_func (arg1, arg2));
1806
1807   return NULL_RTX;
1808 }
1809
1810 static rtx
1811 rx_expand_int_builtin_1_arg (rtx arg,
1812                              rtx target,
1813                              rtx (* gen_func)(rtx, rtx),
1814                              bool mem_ok)
1815 {
1816   if (! REG_P (arg))
1817     if (!mem_ok || ! MEM_P (arg))
1818       arg = force_reg (SImode, arg);
1819
1820   if (target == NULL_RTX || ! REG_P (target))
1821     target = gen_reg_rtx (SImode);
1822
1823   emit_insn (gen_func (target, arg));
1824
1825   return target;
1826 }
1827
1828 static rtx
1829 rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx))
1830 {
1831   if (target == NULL_RTX || ! REG_P (target))
1832     target = gen_reg_rtx (SImode);
1833
1834   emit_insn (gen_func (target));
1835
1836   return target;
1837 }
1838
1839 static rtx
1840 rx_expand_builtin_round (rtx arg, rtx target)
1841 {
1842   if ((! REG_P (arg) && ! MEM_P (arg))
1843       || GET_MODE (arg) != SFmode)
1844     arg = force_reg (SFmode, arg);
1845
1846   if (target == NULL_RTX || ! REG_P (target))
1847     target = gen_reg_rtx (SImode);
1848
1849   emit_insn (gen_lrintsf2 (target, arg));
1850
1851   return target;
1852 }
1853
1854 static rtx
1855 rx_expand_builtin (tree exp,
1856                    rtx target,
1857                    rtx subtarget ATTRIBUTE_UNUSED,
1858                    enum machine_mode mode ATTRIBUTE_UNUSED,
1859                    int ignore ATTRIBUTE_UNUSED)
1860 {
1861   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
1862   tree arg    = CALL_EXPR_ARGS (exp) ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
1863   rtx  op     = arg ? expand_normal (arg) : NULL_RTX;
1864   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
1865
1866   switch (fcode)
1867     {
1868     case RX_BUILTIN_BRK:     emit_insn (gen_brk ()); return NULL_RTX;
1869     case RX_BUILTIN_CLRPSW:  return rx_expand_void_builtin_1_arg
1870         (op, gen_clrpsw, false);
1871     case RX_BUILTIN_SETPSW:  return rx_expand_void_builtin_1_arg
1872         (op, gen_setpsw, false);
1873     case RX_BUILTIN_INT:     return rx_expand_void_builtin_1_arg
1874         (op, gen_int, false);
1875     case RX_BUILTIN_MACHI:   return rx_expand_builtin_mac (exp, gen_machi);
1876     case RX_BUILTIN_MACLO:   return rx_expand_builtin_mac (exp, gen_maclo);
1877     case RX_BUILTIN_MULHI:   return rx_expand_builtin_mac (exp, gen_mulhi);
1878     case RX_BUILTIN_MULLO:   return rx_expand_builtin_mac (exp, gen_mullo);
1879     case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg
1880         (target, gen_mvfachi);
1881     case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg
1882         (target, gen_mvfacmi);
1883     case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg
1884         (op, gen_mvtachi, true);
1885     case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg
1886         (op, gen_mvtaclo, true);
1887     case RX_BUILTIN_RMPA:    emit_insn (gen_rmpa ()); return NULL_RTX;
1888     case RX_BUILTIN_MVFC:    return rx_expand_builtin_mvfc (arg, target);
1889     case RX_BUILTIN_MVTC:    return rx_expand_builtin_mvtc (exp);
1890     case RX_BUILTIN_RACW:    return rx_expand_void_builtin_1_arg
1891         (op, gen_racw, false);
1892     case RX_BUILTIN_ROUND:   return rx_expand_builtin_round (op, target);
1893     case RX_BUILTIN_REVW:    return rx_expand_int_builtin_1_arg
1894         (op, target, gen_revw, false);
1895     case RX_BUILTIN_SAT:     return rx_expand_int_builtin_1_arg
1896         (op, target, gen_sat, false);
1897     case RX_BUILTIN_WAIT:    emit_insn (gen_wait ()); return NULL_RTX;
1898
1899     default:
1900       internal_error ("bad builtin code");
1901       break;
1902     }
1903
1904   return NULL_RTX;
1905 }
1906 \f
1907 /* Place an element into a constructor or destructor section.
1908    Like default_ctor_section_asm_out_constructor in varasm.c
1909    except that it uses .init_array (or .fini_array) and it
1910    handles constructor priorities.  */
1911
1912 static void
1913 rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
1914 {
1915   section * s;
1916
1917   if (priority != DEFAULT_INIT_PRIORITY)
1918     {
1919       char buf[18];
1920
1921       sprintf (buf, "%s.%.5u",
1922                is_ctor ? ".init_array" : ".fini_array",
1923                priority);
1924       s = get_section (buf, SECTION_WRITE, NULL_TREE);
1925     }
1926   else if (is_ctor)
1927     s = ctors_section;
1928   else
1929     s = dtors_section;
1930
1931   switch_to_section (s);
1932   assemble_align (POINTER_SIZE);
1933   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
1934 }
1935
1936 static void
1937 rx_elf_asm_constructor (rtx symbol, int priority)
1938 {
1939   rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true);
1940 }
1941
1942 static void
1943 rx_elf_asm_destructor (rtx symbol, int priority)
1944 {
1945   rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
1946 }
1947 \f
1948 /* Check "interrupt", "exception" and "naked" attributes.  */
1949
1950 static tree
1951 rx_handle_func_attribute (tree * node,
1952                           tree   name,
1953                           tree   args,
1954                           int    flags ATTRIBUTE_UNUSED,
1955                           bool * no_add_attrs)
1956 {
1957   gcc_assert (DECL_P (* node));
1958   gcc_assert (args == NULL_TREE);
1959
1960   if (TREE_CODE (* node) != FUNCTION_DECL)
1961     {
1962       warning (OPT_Wattributes, "%qE attribute only applies to functions",
1963                name);
1964       * no_add_attrs = true;
1965     }
1966
1967   /* FIXME: We ought to check for conflicting attributes.  */
1968
1969   /* FIXME: We ought to check that the interrupt and exception
1970      handler attributes have been applied to void functions.  */
1971   return NULL_TREE;
1972 }
1973
1974 /* Table of RX specific attributes.  */
1975 const struct attribute_spec rx_attribute_table[] =
1976 {
1977   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler.  */
1978   { "interrupt",      0, 0, true, false, false, rx_handle_func_attribute },
1979   { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
1980   { "exception",      0, 0, true, false, false, rx_handle_func_attribute },
1981   { "naked",          0, 0, true, false, false, rx_handle_func_attribute },
1982   { NULL,             0, 0, false, false, false, NULL }
1983 };
1984
1985 static bool
1986 rx_allocate_stack_slots_for_args (void)
1987 {
1988   /* Naked functions should not allocate stack slots for arguments.  */
1989   return ! is_naked_func (NULL_TREE);
1990 }
1991
1992 static bool
1993 rx_func_attr_inlinable (const_tree decl)
1994 {
1995   return ! is_fast_interrupt_func (decl)
1996     &&   ! is_exception_func (decl)
1997     &&   ! is_naked_func (decl);  
1998 }
1999
2000 static void
2001 rx_file_start (void)
2002 {
2003   if (! TARGET_AS100_SYNTAX)
2004     default_file_start ();
2005 }
2006
2007 static bool
2008 rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
2009 {
2010   return TRUE;
2011 }
2012
2013 /* Try to generate code for the "isnv" pattern which inserts bits
2014    into a word.
2015      operands[0] => Location to be altered.
2016      operands[1] => Number of bits to change.
2017      operands[2] => Starting bit.
2018      operands[3] => Value to insert.
2019    Returns TRUE if successful, FALSE otherwise.  */
2020
2021 bool
2022 rx_expand_insv (rtx * operands)
2023 {
2024   if (INTVAL (operands[1]) != 1
2025       || ! CONST_INT_P (operands[3]))
2026     return false;
2027
2028   if (MEM_P (operands[0])
2029       && INTVAL (operands[2]) > 7)
2030     return false;
2031
2032   switch (INTVAL (operands[3]))
2033     {
2034     case 0:
2035       if (MEM_P (operands[0]))
2036         emit_insn (gen_bitclr_in_memory (operands[0], operands[0],
2037                                          operands[2]));
2038       else
2039         emit_insn (gen_bitclr (operands[0], operands[0], operands[2]));
2040       break;
2041     case 1:
2042     case -1:
2043       if (MEM_P (operands[0]))
2044         emit_insn (gen_bitset_in_memory (operands[0], operands[0],
2045                                          operands[2]));
2046       else
2047         emit_insn (gen_bitset (operands[0], operands[0], operands[2]));
2048       break;
2049    default:
2050       return false;
2051     }
2052   return true;
2053 }
2054 \f
2055 /* Returns true if X a legitimate constant for an immediate
2056    operand on the RX.  X is already known to satisfy CONSTANT_P.  */
2057
2058 bool
2059 rx_is_legitimate_constant (rtx x)
2060 {
2061   HOST_WIDE_INT val;
2062
2063   switch (GET_CODE (x))
2064     {
2065     case CONST:
2066       x = XEXP (x, 0);
2067
2068       if (GET_CODE (x) == PLUS)
2069         {
2070           if (! CONST_INT_P (XEXP (x, 1)))
2071             return false;
2072
2073           /* GCC would not pass us CONST_INT + CONST_INT so we
2074              know that we have {SYMBOL|LABEL} + CONST_INT.  */
2075           x = XEXP (x, 0);
2076           gcc_assert (! CONST_INT_P (x));
2077         }
2078
2079       switch (GET_CODE (x))
2080         {
2081         case LABEL_REF:
2082         case SYMBOL_REF:
2083           return true;
2084
2085           /* One day we may have to handle UNSPEC constants here.  */
2086         default:
2087           /* FIXME: Can this ever happen ?  */
2088           abort ();
2089           return false;
2090         }
2091       break;
2092       
2093     case LABEL_REF:
2094     case SYMBOL_REF:
2095       return true;
2096     case CONST_DOUBLE:
2097       return rx_max_constant_size == 0;
2098     case CONST_VECTOR:
2099       return false;
2100     default:
2101       gcc_assert (CONST_INT_P (x));
2102       break;
2103     }
2104
2105   if (rx_max_constant_size == 0)
2106     /* If there is no constraint on the size of constants
2107        used as operands, then any value is legitimate.  */
2108     return true;
2109
2110   val = INTVAL (x);
2111
2112   /* rx_max_constant_size specifies the maximum number
2113      of bytes that can be used to hold a signed value.  */
2114   return IN_RANGE (val, (-1 << (rx_max_constant_size * 8)),
2115                         ( 1 << (rx_max_constant_size * 8)));
2116 }
2117
2118 /* Extra processing for target specific command line options.  */
2119
2120 static bool
2121 rx_handle_option (size_t code, const char *  arg ATTRIBUTE_UNUSED, int value)
2122 {
2123   switch (code)
2124     {
2125     case OPT_mint_register_:
2126       switch (value)
2127         {
2128         case 4:
2129           fixed_regs[10] = call_used_regs [10] = 1;
2130           /* Fall through.  */
2131         case 3:
2132           fixed_regs[11] = call_used_regs [11] = 1;
2133           /* Fall through.  */
2134         case 2:
2135           fixed_regs[12] = call_used_regs [12] = 1;
2136           /* Fall through.  */
2137         case 1:
2138           fixed_regs[13] = call_used_regs [13] = 1;
2139           /* Fall through.  */
2140         case 0:
2141           return true;
2142         default:
2143           return false;
2144         }
2145       break;
2146
2147     case OPT_mmax_constant_size_:
2148       /* Make sure that the the -mmax-constant_size option is in range.  */
2149       return IN_RANGE (value, 0, 4);
2150
2151     default:
2152       return true;
2153     }
2154 }
2155
2156 static int
2157 rx_address_cost (rtx addr, bool speed)
2158 {
2159   rtx a, b;
2160
2161   if (GET_CODE (addr) != PLUS)
2162     return COSTS_N_INSNS (1);
2163
2164   a = XEXP (addr, 0);
2165   b = XEXP (addr, 1);
2166
2167   if (REG_P (a) && REG_P (b))
2168     /* Try to discourage REG+REG addressing as it keeps two registers live.  */
2169     return COSTS_N_INSNS (4);
2170
2171   if (speed)
2172     /* [REG+OFF] is just as fast as [REG].  */
2173     return COSTS_N_INSNS (1);
2174
2175   if (CONST_INT_P (b)
2176       && ((INTVAL (b) > 128) || INTVAL (b) < -127))
2177     /* Try to discourage REG + <large OFF> when optimizing for size.  */
2178     return COSTS_N_INSNS (2);
2179     
2180   return COSTS_N_INSNS (1);
2181 }
2182
2183 static bool
2184 rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2185 {
2186   /* We can always eliminate to the frame pointer.
2187      We can eliminate to the stack pointer unless a frame
2188      pointer is needed.  */
2189
2190   return to == FRAME_POINTER_REGNUM
2191     || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed);
2192 }
2193 \f
2194
2195 static void
2196 rx_trampoline_template (FILE * file)
2197 {
2198   /* Output assembler code for a block containing the constant
2199      part of a trampoline, leaving space for the variable parts.
2200
2201      On the RX, (where r8 is the static chain regnum) the trampoline
2202      looks like:
2203
2204            mov          #<static chain value>, r8
2205            mov          #<function's address>, r9
2206            jmp          r9
2207
2208      In big-endian-data-mode however instructions are read into the CPU
2209      4 bytes at a time.  These bytes are then swapped around before being
2210      passed to the decoder.  So...we must partition our trampoline into
2211      4 byte packets and swap these packets around so that the instruction
2212      reader will reverse the process.  But, in order to avoid splitting
2213      the 32-bit constants across these packet boundaries, (making inserting
2214      them into the constructed trampoline very difficult) we have to pad the
2215      instruction sequence with NOP insns.  ie:
2216
2217            nop
2218            nop
2219            mov.l        #<...>, r8
2220            nop
2221            nop
2222            mov.l        #<...>, r9
2223            jmp          r9
2224            nop
2225            nop             */
2226
2227   if (! TARGET_BIG_ENDIAN_DATA)
2228     {
2229       asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM);
2230       asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM);
2231       asm_fprintf (file, "\tjmp\tr%d\n",                TRAMPOLINE_TEMP_REGNUM);
2232     }
2233   else
2234     {
2235       char r8 = '0' + STATIC_CHAIN_REGNUM;
2236       char r9 = '0' + TRAMPOLINE_TEMP_REGNUM;
2237
2238       if (TARGET_AS100_SYNTAX)
2239         {
2240           asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r8);
2241           asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
2242           asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r9);
2243           asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
2244           asm_fprintf (file, "\t.BYTE 003H,  003H, 00%cH, 07fH\n", r9);
2245         }
2246       else
2247         {
2248           asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r8);
2249           asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
2250           asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r9);
2251           asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
2252           asm_fprintf (file, "\t.byte 0x03,  0x03, 0x0%c, 0x7f\n", r9);
2253         }
2254     }
2255 }
2256
2257 static void
2258 rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
2259 {
2260   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2261
2262   emit_block_move (tramp, assemble_trampoline_template (),
2263                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2264
2265   if (TARGET_BIG_ENDIAN_DATA)
2266     {
2267       emit_move_insn (adjust_address (tramp, SImode, 4), chain);
2268       emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
2269     }
2270   else
2271     {
2272       emit_move_insn (adjust_address (tramp, SImode, 2), chain);
2273       emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr);
2274     }
2275 }
2276 \f
2277 #undef  TARGET_FUNCTION_VALUE
2278 #define TARGET_FUNCTION_VALUE           rx_function_value
2279
2280 #undef  TARGET_RETURN_IN_MSB
2281 #define TARGET_RETURN_IN_MSB            rx_return_in_msb
2282
2283 #undef  TARGET_IN_SMALL_DATA_P
2284 #define TARGET_IN_SMALL_DATA_P          rx_in_small_data
2285
2286 #undef  TARGET_RETURN_IN_MEMORY
2287 #define TARGET_RETURN_IN_MEMORY         rx_return_in_memory
2288
2289 #undef  TARGET_HAVE_SRODATA_SECTION
2290 #define TARGET_HAVE_SRODATA_SECTION     true
2291
2292 #undef  TARGET_ASM_SELECT_RTX_SECTION
2293 #define TARGET_ASM_SELECT_RTX_SECTION   rx_select_rtx_section
2294
2295 #undef  TARGET_ASM_SELECT_SECTION
2296 #define TARGET_ASM_SELECT_SECTION       rx_select_section
2297
2298 #undef  TARGET_INIT_BUILTINS
2299 #define TARGET_INIT_BUILTINS            rx_init_builtins
2300
2301 #undef  TARGET_EXPAND_BUILTIN
2302 #define TARGET_EXPAND_BUILTIN           rx_expand_builtin
2303
2304 #undef  TARGET_ASM_CONSTRUCTOR
2305 #define TARGET_ASM_CONSTRUCTOR          rx_elf_asm_constructor
2306
2307 #undef  TARGET_ASM_DESTRUCTOR
2308 #define TARGET_ASM_DESTRUCTOR           rx_elf_asm_destructor
2309
2310 #undef  TARGET_STRUCT_VALUE_RTX
2311 #define TARGET_STRUCT_VALUE_RTX         rx_struct_value_rtx
2312
2313 #undef  TARGET_ATTRIBUTE_TABLE
2314 #define TARGET_ATTRIBUTE_TABLE          rx_attribute_table
2315
2316 #undef  TARGET_ASM_FILE_START
2317 #define TARGET_ASM_FILE_START                   rx_file_start
2318
2319 #undef  TARGET_MS_BITFIELD_LAYOUT_P
2320 #define TARGET_MS_BITFIELD_LAYOUT_P             rx_is_ms_bitfield_layout
2321
2322 #undef  TARGET_LEGITIMATE_ADDRESS_P
2323 #define TARGET_LEGITIMATE_ADDRESS_P             rx_is_legitimate_address
2324
2325 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
2326 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS    rx_allocate_stack_slots_for_args
2327
2328 #undef  TARGET_ASM_FUNCTION_PROLOGUE
2329 #define TARGET_ASM_FUNCTION_PROLOGUE            rx_output_function_prologue
2330
2331 #undef  TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
2332 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P   rx_func_attr_inlinable
2333
2334 #undef  TARGET_SET_CURRENT_FUNCTION
2335 #define TARGET_SET_CURRENT_FUNCTION             rx_set_current_function
2336
2337 #undef  TARGET_HANDLE_OPTION
2338 #define TARGET_HANDLE_OPTION                    rx_handle_option
2339
2340 #undef  TARGET_ASM_INTEGER
2341 #define TARGET_ASM_INTEGER                      rx_assemble_integer
2342
2343 #undef  TARGET_USE_BLOCKS_FOR_CONSTANT_P
2344 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P        hook_bool_mode_const_rtx_true
2345
2346 #undef  TARGET_MAX_ANCHOR_OFFSET
2347 #define TARGET_MAX_ANCHOR_OFFSET                32
2348
2349 #undef  TARGET_ADDRESS_COST
2350 #define TARGET_ADDRESS_COST                     rx_address_cost
2351
2352 #undef  TARGET_CAN_ELIMINATE
2353 #define TARGET_CAN_ELIMINATE                    rx_can_eliminate
2354
2355 #undef  TARGET_ASM_TRAMPOLINE_TEMPLATE
2356 #define TARGET_ASM_TRAMPOLINE_TEMPLATE          rx_trampoline_template
2357
2358 #undef  TARGET_TRAMPOLINE_INIT
2359 #define TARGET_TRAMPOLINE_INIT                  rx_trampoline_init
2360
2361 struct gcc_target targetm = TARGET_INITIALIZER;
2362
2363 /* #include "gt-rx.h" */