OSDN Git Service

* config/rx/rx.md (UNSPEC_CONST): New.
[pf3gnuchains/gcc-fork.git] / gcc / config / rx / rx.c
1 /* Subroutines used for code generation on Renesas RX processors.
2    Copyright (C) 2008, 2009, 2010, 2011 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 "insn-config.h"
34 #include "conditions.h"
35 #include "output.h"
36 #include "insn-attr.h"
37 #include "flags.h"
38 #include "function.h"
39 #include "expr.h"
40 #include "optabs.h"
41 #include "libfuncs.h"
42 #include "recog.h"
43 #include "diagnostic-core.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 static void rx_print_operand (FILE *, rtx, int);
55
56 #define CC_FLAG_S       (1 << 0)
57 #define CC_FLAG_Z       (1 << 1)
58 #define CC_FLAG_O       (1 << 2)
59 #define CC_FLAG_C       (1 << 3)
60 #define CC_FLAG_FP      (1 << 4)        /* fake, to differentiate CC_Fmode */
61
62 static unsigned int flags_from_mode (enum machine_mode mode);
63 static unsigned int flags_from_code (enum rtx_code code);
64
65 enum rx_cpu_types  rx_cpu_type = RX600;
66 \f
67 /* Return true if OP is a reference to an object in a small data area.  */
68
69 static bool
70 rx_small_data_operand (rtx op)
71 {
72   if (rx_small_data_limit == 0)
73     return false;
74
75   if (GET_CODE (op) == SYMBOL_REF)
76     return SYMBOL_REF_SMALL_P (op);
77
78   return false;
79 }
80
81 static bool
82 rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
83 {
84   if (RTX_OK_FOR_BASE (x, strict))
85     /* Register Indirect.  */
86     return true;
87
88   if (GET_MODE_SIZE (mode) == 4
89       && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
90     /* Pre-decrement Register Indirect or
91        Post-increment Register Indirect.  */
92     return RTX_OK_FOR_BASE (XEXP (x, 0), strict);
93
94   if (GET_CODE (x) == PLUS)
95     {
96       rtx arg1 = XEXP (x, 0);
97       rtx arg2 = XEXP (x, 1);
98       rtx index = NULL_RTX;
99
100       if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict))
101         index = arg2;
102       else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict))
103         index = arg1;
104       else
105         return false;
106
107       switch (GET_CODE (index))
108         {
109         case CONST_INT:
110           {
111             /* Register Relative: REG + INT.
112                Only positive, mode-aligned, mode-sized
113                displacements are allowed.  */
114             HOST_WIDE_INT val = INTVAL (index);
115             int factor;
116
117             if (val < 0)
118               return false;
119             
120             switch (GET_MODE_SIZE (mode))
121               {
122               default: 
123               case 4: factor = 4; break;
124               case 2: factor = 2; break;
125               case 1: factor = 1; break;
126               }
127
128             if (val > (65535 * factor))
129               return false;
130             return (val % factor) == 0;
131           }
132
133         case REG:
134           /* Unscaled Indexed Register Indirect: REG + REG
135              Size has to be "QI", REG has to be valid.  */
136           return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict);
137
138         case MULT:
139           {
140             /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
141                Factor has to equal the mode size, REG has to be valid.  */
142             rtx factor;
143
144             factor = XEXP (index, 1);
145             index = XEXP (index, 0);
146
147             return REG_P (index)
148               && RTX_OK_FOR_BASE (index, strict)
149               && CONST_INT_P (factor)
150               && GET_MODE_SIZE (mode) == INTVAL (factor);
151           }
152
153         default:
154           return false;
155         }
156     }
157
158   /* Small data area accesses turn into register relative offsets.  */
159   return rx_small_data_operand (x);
160 }
161
162 /* Returns TRUE for simple memory addreses, ie ones
163    that do not involve register indirect addressing
164    or pre/post increment/decrement.  */
165
166 bool
167 rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
168 {
169   rtx base, index;
170
171   if (! rx_is_legitimate_address
172       (mode, mem, reload_in_progress || reload_completed))
173     return false;
174
175   switch (GET_CODE (mem))
176     {
177     case REG:
178       /* Simple memory addresses are OK.  */
179       return true;
180
181     case PRE_DEC:
182     case POST_INC:
183       return false;
184
185     case PLUS:
186       /* Only allow REG+INT addressing.  */
187       base = XEXP (mem, 0);
188       index = XEXP (mem, 1);
189
190       return RX_REG_P (base) && CONST_INT_P (index);
191
192     case SYMBOL_REF:
193       /* Can happen when small data is being supported.
194          Assume that it will be resolved into GP+INT.  */
195       return true;
196
197     default:
198       gcc_unreachable ();
199     }
200 }
201
202 bool
203 rx_is_mode_dependent_addr (rtx addr)
204 {
205   if (GET_CODE (addr) == CONST)
206     addr = XEXP (addr, 0);
207
208   switch (GET_CODE (addr))
209     {
210       /* --REG and REG++ only work in SImode.  */
211     case PRE_DEC:
212     case POST_INC:
213       return true;
214
215     case MINUS:
216     case PLUS:
217       if (! REG_P (XEXP (addr, 0)))
218         return true;
219
220       addr = XEXP (addr, 1);
221
222       switch (GET_CODE (addr))
223         {
224         case REG:
225           /* REG+REG only works in SImode.  */
226           return true;
227
228         case CONST_INT:
229           /* REG+INT is only mode independent if INT is a
230              multiple of 4, positive and will fit into 8-bits.  */
231           if (((INTVAL (addr) & 3) == 0)
232               && IN_RANGE (INTVAL (addr), 4, 252))
233             return false;
234           return true;
235
236         case SYMBOL_REF:
237         case LABEL_REF:
238           return true;
239
240         case MULT:
241           gcc_assert (REG_P (XEXP (addr, 0)));
242           gcc_assert (CONST_INT_P (XEXP (addr, 1)));
243           /* REG+REG*SCALE is always mode dependent.  */
244           return true;
245
246         default:
247           /* Not recognized, so treat as mode dependent.  */
248           return true;
249         }
250
251     case CONST_INT:
252     case SYMBOL_REF:
253     case LABEL_REF:
254     case REG:
255       /* These are all mode independent.  */
256       return false;
257
258     default:
259       /* Everything else is unrecognized,
260          so treat as mode dependent.  */
261       return true;
262     }
263 }
264 \f
265 /* A C compound statement to output to stdio stream FILE the
266    assembler syntax for an instruction operand that is a memory
267    reference whose address is ADDR.  */
268
269 static void
270 rx_print_operand_address (FILE * file, rtx addr)
271 {
272   switch (GET_CODE (addr))
273     {
274     case REG:
275       fprintf (file, "[");
276       rx_print_operand (file, addr, 0);
277       fprintf (file, "]");
278       break;
279
280     case PRE_DEC:
281       fprintf (file, "[-");
282       rx_print_operand (file, XEXP (addr, 0), 0);
283       fprintf (file, "]");
284       break;
285
286     case POST_INC:
287       fprintf (file, "[");
288       rx_print_operand (file, XEXP (addr, 0), 0);
289       fprintf (file, "+]");
290       break;
291
292     case PLUS:
293       {
294         rtx arg1 = XEXP (addr, 0);
295         rtx arg2 = XEXP (addr, 1);
296         rtx base, index;
297
298         if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true))
299           base = arg1, index = arg2;
300         else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true))
301           base = arg2, index = arg1;
302         else
303           {
304             rx_print_operand (file, arg1, 0);
305             fprintf (file, " + ");
306             rx_print_operand (file, arg2, 0);
307             break;
308           }
309
310         if (REG_P (index) || GET_CODE (index) == MULT)
311           {
312             fprintf (file, "[");
313             rx_print_operand (file, index, 'A');
314             fprintf (file, ",");
315           }
316         else /* GET_CODE (index) == CONST_INT  */
317           {
318             rx_print_operand (file, index, 'A');
319             fprintf (file, "[");
320           }
321         rx_print_operand (file, base, 0);
322         fprintf (file, "]");
323         break;
324       }
325
326     case CONST:
327       if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
328         {
329           addr = XEXP (addr, 0);
330           gcc_assert (XINT (addr, 1) == UNSPEC_CONST);
331       
332           addr = XVECEXP (addr, 0, 0);
333           gcc_assert (CONST_INT_P (addr));
334         }
335       /* Fall through.  */
336     case LABEL_REF:
337     case SYMBOL_REF:
338       fprintf (file, "#");
339
340     default:
341       output_addr_const (file, addr);
342       break;
343     }
344 }
345
346 static void
347 rx_print_integer (FILE * file, HOST_WIDE_INT val)
348 {
349   if (IN_RANGE (val, -64, 64))
350     fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
351   else
352     fprintf (file,
353              TARGET_AS100_SYNTAX
354              ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX,
355              val);
356 }
357
358 static bool
359 rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
360 {
361   const char *  op = integer_asm_op (size, is_aligned);
362
363   if (! CONST_INT_P (x))
364     return default_assemble_integer (x, size, is_aligned);
365
366   if (op == NULL)
367     return false;
368   fputs (op, asm_out_file);
369
370   rx_print_integer (asm_out_file, INTVAL (x));
371   fputc ('\n', asm_out_file);
372   return true;
373 }
374
375
376 /* Handles the insertion of a single operand into the assembler output.
377    The %<letter> directives supported are:
378
379      %A  Print an operand without a leading # character.
380      %B  Print an integer comparison name.
381      %C  Print a control register name.
382      %F  Print a condition code flag name.
383      %H  Print high part of a DImode register, integer or address.
384      %L  Print low part of a DImode register, integer or address.
385      %N  Print the negation of the immediate value.
386      %Q  If the operand is a MEM, then correctly generate
387          register indirect or register relative addressing.  */
388
389 static void
390 rx_print_operand (FILE * file, rtx op, int letter)
391 {
392   switch (letter)
393     {
394     case 'A':
395       /* Print an operand without a leading #.  */
396       if (MEM_P (op))
397         op = XEXP (op, 0);
398
399       switch (GET_CODE (op))
400         {
401         case LABEL_REF:
402         case SYMBOL_REF:
403           output_addr_const (file, op);
404           break;
405         case CONST_INT:
406           fprintf (file, "%ld", (long) INTVAL (op));
407           break;
408         default:
409           rx_print_operand (file, op, 0);
410           break;
411         }
412       break;
413
414     case 'B':
415       {
416         enum rtx_code code = GET_CODE (op);
417         enum machine_mode mode = GET_MODE (XEXP (op, 0));
418         const char *ret;
419
420         if (mode == CC_Fmode)
421           {
422             /* C flag is undefined, and O flag carries unordered.  None of the
423                branch combinations that include O use it helpfully.  */
424             switch (code)
425               {
426               case ORDERED:
427                 ret = "no";
428                 break;
429               case UNORDERED:
430                 ret = "o";
431                 break;
432               case LT:
433                 ret = "n";
434                 break;
435               case GE:
436                 ret = "pz";
437                 break;
438               case EQ:
439                 ret = "eq";
440                 break;
441               case NE:
442                 ret = "ne";
443                 break;
444               default:
445                 gcc_unreachable ();
446               }
447           }
448         else
449           {
450             switch (code)
451               {
452               case LT:
453                 ret = "n";
454                 break;
455               case GE:
456                 ret = "pz";
457                 break;
458               case GT:
459                 ret = "gt";
460                 break;
461               case LE:
462                 ret = "le";
463                 break;
464               case GEU:
465                 ret = "geu";
466                 break;
467               case LTU:
468                 ret = "ltu";
469                 break;
470               case GTU:
471                 ret = "gtu";
472                 break;
473               case LEU:
474                 ret = "leu";
475                 break;
476               case EQ:
477                 ret = "eq";
478                 break;
479               case NE:
480                 ret = "ne";
481                 break;
482               default:
483                 gcc_unreachable ();
484               }
485             gcc_checking_assert ((flags_from_code (code)
486                                   & ~flags_from_mode (mode)) == 0);
487           }
488         fputs (ret, file);
489         break;
490       }
491
492     case 'C':
493       gcc_assert (CONST_INT_P (op));
494       switch (INTVAL (op))
495         {
496         case 0:   fprintf (file, "psw"); break;
497         case 2:   fprintf (file, "usp"); break;
498         case 3:   fprintf (file, "fpsw"); break;
499         case 4:   fprintf (file, "cpen"); break;
500         case 8:   fprintf (file, "bpsw"); break;
501         case 9:   fprintf (file, "bpc"); break;
502         case 0xa: fprintf (file, "isp"); break;
503         case 0xb: fprintf (file, "fintv"); break;
504         case 0xc: fprintf (file, "intb"); break;
505         default:
506           warning (0, "unreocgnized control register number: %d - using 'psw'",
507                    (int) INTVAL (op));
508           fprintf (file, "psw");
509           break;
510         }
511       break;
512
513     case 'F':
514       gcc_assert (CONST_INT_P (op));
515       switch (INTVAL (op))
516         {
517         case 0: case 'c': case 'C': fprintf (file, "C"); break;
518         case 1: case 'z': case 'Z': fprintf (file, "Z"); break;
519         case 2: case 's': case 'S': fprintf (file, "S"); break;
520         case 3: case 'o': case 'O': fprintf (file, "O"); break;
521         case 8: case 'i': case 'I': fprintf (file, "I"); break;
522         case 9: case 'u': case 'U': fprintf (file, "U"); break;
523         default:
524           gcc_unreachable ();
525         }
526       break;
527
528     case 'H':
529       switch (GET_CODE (op))
530         {
531         case REG:
532           fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
533           break;
534         case CONST_INT:
535           {
536             HOST_WIDE_INT v = INTVAL (op);
537
538             fprintf (file, "#");
539             /* Trickery to avoid problems with shifting 32 bits at a time.  */
540             v = v >> 16;
541             v = v >> 16;          
542             rx_print_integer (file, v);
543             break;
544           }
545         case CONST_DOUBLE:
546           fprintf (file, "#");
547           rx_print_integer (file, CONST_DOUBLE_HIGH (op));
548           break;
549         case MEM:
550           if (! WORDS_BIG_ENDIAN)
551             op = adjust_address (op, SImode, 4);
552           output_address (XEXP (op, 0));
553           break;
554         default:
555           gcc_unreachable ();
556         }
557       break;
558
559     case 'L':
560       switch (GET_CODE (op))
561         {
562         case REG:
563           fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
564           break;
565         case CONST_INT:
566           fprintf (file, "#");
567           rx_print_integer (file, INTVAL (op) & 0xffffffff);
568           break;
569         case CONST_DOUBLE:
570           fprintf (file, "#");
571           rx_print_integer (file, CONST_DOUBLE_LOW (op));
572           break;
573         case MEM:
574           if (WORDS_BIG_ENDIAN)
575             op = adjust_address (op, SImode, 4);
576           output_address (XEXP (op, 0));
577           break;
578         default:
579           gcc_unreachable ();
580         }
581       break;
582
583     case 'N':
584       gcc_assert (CONST_INT_P (op));
585       fprintf (file, "#");
586       rx_print_integer (file, - INTVAL (op));
587       break;
588
589     case 'Q':
590       if (MEM_P (op))
591         {
592           HOST_WIDE_INT offset;
593
594           op = XEXP (op, 0);
595
596           if (REG_P (op))
597             offset = 0;
598           else if (GET_CODE (op) == PLUS)
599             {
600               rtx displacement;
601
602               if (REG_P (XEXP (op, 0)))
603                 {
604                   displacement = XEXP (op, 1);
605                   op = XEXP (op, 0);
606                 }
607               else
608                 {
609                   displacement = XEXP (op, 0);
610                   op = XEXP (op, 1);
611                   gcc_assert (REG_P (op));
612                 }
613
614               gcc_assert (CONST_INT_P (displacement));
615               offset = INTVAL (displacement);
616               gcc_assert (offset >= 0);
617
618               fprintf (file, "%ld", offset);
619             }
620           else
621             gcc_unreachable ();
622
623           fprintf (file, "[");
624           rx_print_operand (file, op, 0);
625           fprintf (file, "].");
626
627           switch (GET_MODE_SIZE (GET_MODE (op)))
628             {
629             case 1:
630               gcc_assert (offset < 65535 * 1);
631               fprintf (file, "B");
632               break;
633             case 2:
634               gcc_assert (offset % 2 == 0);
635               gcc_assert (offset < 65535 * 2);
636               fprintf (file, "W");
637               break;
638             default:
639               gcc_assert (offset % 4 == 0);
640               gcc_assert (offset < 65535 * 4);
641               fprintf (file, "L");
642               break;
643             }
644           break;
645         }
646
647       /* Fall through.  */
648
649     default:
650       switch (GET_CODE (op))
651         {
652         case MULT:
653           /* Should be the scaled part of an
654              indexed register indirect address.  */
655           {
656             rtx base = XEXP (op, 0);
657             rtx index = XEXP (op, 1);
658
659             /* Check for a swaped index register and scaling factor.
660                Not sure if this can happen, but be prepared to handle it.  */
661             if (CONST_INT_P (base) && REG_P (index))
662               {
663                 rtx tmp = base;
664                 base = index;
665                 index = tmp;
666               }
667
668             gcc_assert (REG_P (base));
669             gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
670             gcc_assert (CONST_INT_P (index));
671             /* Do not try to verify the value of the scalar as it is based
672                on the mode of the MEM not the mode of the MULT.  (Which
673                will always be SImode).  */
674             fprintf (file, "%s", reg_names [REGNO (base)]);
675             break;
676           }
677
678         case MEM:
679           output_address (XEXP (op, 0));
680           break;
681
682         case PLUS:
683           output_address (op);
684           break;
685
686         case REG:
687           gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
688           fprintf (file, "%s", reg_names [REGNO (op)]);
689           break;
690
691         case SUBREG:
692           gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER);
693           fprintf (file, "%s", reg_names [subreg_regno (op)]);
694           break;
695
696           /* This will only be single precision....  */
697         case CONST_DOUBLE:
698           {
699             unsigned long val;
700             REAL_VALUE_TYPE rv;
701
702             REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
703             REAL_VALUE_TO_TARGET_SINGLE (rv, val);
704             fprintf (file, TARGET_AS100_SYNTAX ? "#0%lxH" : "#0x%lx", val);
705             break;
706           }
707
708         case CONST_INT:
709           fprintf (file, "#");
710           rx_print_integer (file, INTVAL (op));
711           break;
712
713         case SYMBOL_REF:
714         case CONST:
715         case LABEL_REF:
716         case CODE_LABEL:
717         case UNSPEC:
718           rx_print_operand_address (file, op);
719           break;
720
721         default:
722           gcc_unreachable ();
723         }
724       break;
725     }
726 }
727
728 /* Returns an assembler template for a move instruction.  */
729
730 char *
731 rx_gen_move_template (rtx * operands, bool is_movu)
732 {
733   static char  out_template [64];
734   const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
735   const char * src_template;
736   const char * dst_template;
737   rtx          dest = operands[0];
738   rtx          src  = operands[1];
739
740   /* Decide which extension, if any, should be given to the move instruction.  */
741   switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
742     {
743     case QImode:
744       /* The .B extension is not valid when
745          loading an immediate into a register.  */
746       if (! REG_P (dest) || ! CONST_INT_P (src))
747         extension = ".B";
748       break;
749     case HImode:
750       if (! REG_P (dest) || ! CONST_INT_P (src))
751         /* The .W extension is not valid when
752            loading an immediate into a register.  */
753         extension = ".W";
754       break;
755     case SFmode:
756     case SImode:
757       extension = ".L";
758       break;
759     case VOIDmode:
760       /* This mode is used by constants.  */
761       break;
762     default:
763       debug_rtx (src);
764       gcc_unreachable ();
765     }
766
767   if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
768     src_template = "%%gp(%A1)[r13]";
769   else
770     src_template = "%1";
771
772   if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
773     dst_template = "%%gp(%A0)[r13]";
774   else
775     dst_template = "%0";
776
777   sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
778            extension, src_template, dst_template);
779   return out_template;
780 }
781 \f
782 /* Return VALUE rounded up to the next ALIGNMENT boundary.  */
783
784 static inline unsigned int
785 rx_round_up (unsigned int value, unsigned int alignment)
786 {
787   alignment -= 1;
788   return (value + alignment) & (~ alignment);
789 }
790
791 /* Return the number of bytes in the argument registers
792    occupied by an argument of type TYPE and mode MODE.  */
793
794 static unsigned int
795 rx_function_arg_size (Mmode mode, const_tree type)
796 {
797   unsigned int num_bytes;
798
799   num_bytes = (mode == BLKmode)
800     ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
801   return rx_round_up (num_bytes, UNITS_PER_WORD);
802 }
803
804 #define NUM_ARG_REGS            4
805 #define MAX_NUM_ARG_BYTES       (NUM_ARG_REGS * UNITS_PER_WORD)
806
807 /* Return an RTL expression describing the register holding a function
808    parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
809    be passed on the stack.  CUM describes the previous parameters to the
810    function and NAMED is false if the parameter is part of a variable
811    parameter list, or the last named parameter before the start of a
812    variable parameter list.  */
813
814 static rtx
815 rx_function_arg (Fargs * cum, Mmode mode, const_tree type, bool named)
816 {
817   unsigned int next_reg;
818   unsigned int bytes_so_far = *cum;
819   unsigned int size;
820   unsigned int rounded_size;
821
822   /* An exploded version of rx_function_arg_size.  */
823   size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
824   /* If the size is not known it cannot be passed in registers.  */
825   if (size < 1)
826     return NULL_RTX;
827
828   rounded_size = rx_round_up (size, UNITS_PER_WORD);
829
830   /* Don't pass this arg via registers if there
831      are insufficient registers to hold all of it.  */
832   if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES)
833     return NULL_RTX;
834
835   /* Unnamed arguments and the last named argument in a
836      variadic function are always passed on the stack.  */
837   if (!named)
838     return NULL_RTX;
839
840   /* Structures must occupy an exact number of registers,
841      otherwise they are passed on the stack.  */
842   if ((type == NULL || AGGREGATE_TYPE_P (type))
843       && (size % UNITS_PER_WORD) != 0)
844     return NULL_RTX;
845
846   next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
847
848   return gen_rtx_REG (mode, next_reg);
849 }
850
851 static void
852 rx_function_arg_advance (Fargs * cum, Mmode mode, const_tree type,
853                          bool named ATTRIBUTE_UNUSED)
854 {
855   *cum += rx_function_arg_size (mode, type);
856 }
857
858 static unsigned int
859 rx_function_arg_boundary (Mmode mode ATTRIBUTE_UNUSED,
860                           const_tree type ATTRIBUTE_UNUSED)
861 {
862   return 32;
863 }
864
865 /* Return an RTL describing where a function return value of type RET_TYPE
866    is held.  */
867
868 static rtx
869 rx_function_value (const_tree ret_type,
870                    const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
871                    bool       outgoing ATTRIBUTE_UNUSED)
872 {
873   enum machine_mode mode = TYPE_MODE (ret_type);
874
875   /* RX ABI specifies that small integer types are
876      promoted to int when returned by a function.  */
877   if (GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) < 4)
878     return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
879     
880   return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
881 }
882
883 /* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
884    regard to function returns as does TARGET_FUNCTION_VALUE.  */
885
886 static enum machine_mode
887 rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
888                           enum machine_mode mode,
889                           int * punsignedp ATTRIBUTE_UNUSED,
890                           const_tree funtype ATTRIBUTE_UNUSED,
891                           int for_return)
892 {
893   if (for_return != 1
894       || GET_MODE_SIZE (mode) >= 4
895       || GET_MODE_SIZE (mode) < 1)
896     return mode;
897
898   return SImode;
899 }
900
901 static bool
902 rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
903 {
904   HOST_WIDE_INT size;
905
906   if (TYPE_MODE (type) != BLKmode
907       && ! AGGREGATE_TYPE_P (type))
908     return false;
909
910   size = int_size_in_bytes (type);
911   /* Large structs and those whose size is not an
912      exact multiple of 4 are returned in memory.  */
913   return size < 1
914     || size > 16
915     || (size % UNITS_PER_WORD) != 0;
916 }
917
918 static rtx
919 rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
920                      int incoming ATTRIBUTE_UNUSED)
921 {
922   return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM);
923 }
924
925 static bool
926 rx_return_in_msb (const_tree valtype)
927 {
928   return TARGET_BIG_ENDIAN_DATA
929     && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE);
930 }
931
932 /* Returns true if the provided function has the specified attribute.  */
933
934 static inline bool
935 has_func_attr (const_tree decl, const char * func_attr)
936 {
937   if (decl == NULL_TREE)
938     decl = current_function_decl;
939
940   return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
941 }
942
943 /* Returns true if the provided function has the "fast_interrupt" attribute.  */
944
945 static inline bool
946 is_fast_interrupt_func (const_tree decl)
947 {
948   return has_func_attr (decl, "fast_interrupt");
949 }
950
951 /* Returns true if the provided function has the "interrupt" attribute.  */
952
953 static inline bool
954 is_interrupt_func (const_tree decl)
955 {
956   return has_func_attr (decl, "interrupt");
957 }
958
959 /* Returns true if the provided function has the "naked" attribute.  */
960
961 static inline bool
962 is_naked_func (const_tree decl)
963 {
964   return has_func_attr (decl, "naked");
965 }
966 \f
967 static bool use_fixed_regs = false;
968
969 static void
970 rx_conditional_register_usage (void)
971 {
972   static bool using_fixed_regs = false;
973
974   if (rx_small_data_limit > 0)
975     fixed_regs[GP_BASE_REGNUM] = call_used_regs [GP_BASE_REGNUM] = 1;
976
977   if (use_fixed_regs != using_fixed_regs)
978     {
979       static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
980       static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
981
982       if (use_fixed_regs)
983         {
984           unsigned int r;
985
986           memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
987           memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
988
989           /* This is for fast interrupt handlers.  Any register in
990              the range r10 to r13 (inclusive) that is currently
991              marked as fixed is now a viable, call-used register.  */     
992           for (r = 10; r <= 13; r++)
993             if (fixed_regs[r])
994               {
995                 fixed_regs[r] = 0;
996                 call_used_regs[r] = 1;
997               }
998
999           /* Mark r7 as fixed.  This is just a hack to avoid
1000              altering the reg_alloc_order array so that the newly
1001              freed r10-r13 registers are the preferred registers.  */
1002           fixed_regs[7] = call_used_regs[7] = 1;
1003         }
1004       else
1005         {
1006           /* Restore the normal register masks.  */
1007           memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
1008           memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
1009         }
1010
1011       using_fixed_regs = use_fixed_regs;
1012     }
1013 }
1014
1015 /* Perform any actions necessary before starting to compile FNDECL.
1016    For the RX we use this to make sure that we have the correct
1017    set of register masks selected.  If FNDECL is NULL then we are
1018    compiling top level things.  */
1019
1020 static void
1021 rx_set_current_function (tree fndecl)
1022 {
1023   /* Remember the last target of rx_set_current_function.  */
1024   static tree rx_previous_fndecl;
1025   bool prev_was_fast_interrupt;
1026   bool current_is_fast_interrupt;
1027
1028   /* Only change the context if the function changes.  This hook is called
1029      several times in the course of compiling a function, and we don't want
1030      to slow things down too much or call target_reinit when it isn't safe.  */
1031   if (fndecl == rx_previous_fndecl)
1032     return;
1033
1034   prev_was_fast_interrupt
1035     = rx_previous_fndecl
1036     ? is_fast_interrupt_func (rx_previous_fndecl) : false;
1037
1038   current_is_fast_interrupt
1039     = fndecl ? is_fast_interrupt_func (fndecl) : false;
1040       
1041   if (prev_was_fast_interrupt != current_is_fast_interrupt)
1042     {
1043       use_fixed_regs = current_is_fast_interrupt;
1044       target_reinit ();
1045     }
1046
1047   rx_previous_fndecl = fndecl;
1048 }
1049 \f
1050 /* Typical stack layout should looks like this after the function's prologue:
1051
1052                             |    |
1053                               --                       ^
1054                             |    | \                   |
1055                             |    |   arguments saved   | Increasing
1056                             |    |   on the stack      |  addresses
1057     PARENT   arg pointer -> |    | /
1058   -------------------------- ---- -------------------
1059     CHILD                   |ret |   return address
1060                               --
1061                             |    | \
1062                             |    |   call saved
1063                             |    |   registers
1064                             |    | /
1065                               --
1066                             |    | \
1067                             |    |   local
1068                             |    |   variables
1069         frame pointer ->    |    | /
1070                               --
1071                             |    | \
1072                             |    |   outgoing          | Decreasing
1073                             |    |   arguments         |  addresses
1074    current stack pointer -> |    | /                   |
1075   -------------------------- ---- ------------------   V
1076                             |    |                 */
1077
1078 static unsigned int
1079 bit_count (unsigned int x)
1080 {
1081   const unsigned int m1 = 0x55555555;
1082   const unsigned int m2 = 0x33333333;
1083   const unsigned int m4 = 0x0f0f0f0f;
1084
1085   x -= (x >> 1) & m1;
1086   x = (x & m2) + ((x >> 2) & m2);
1087   x = (x + (x >> 4)) & m4;
1088   x += x >>  8;
1089
1090   return (x + (x >> 16)) & 0x3f;
1091 }
1092
1093 #define MUST_SAVE_ACC_REGISTER                  \
1094   (TARGET_SAVE_ACC_REGISTER                     \
1095    && (is_interrupt_func (NULL_TREE)            \
1096        || is_fast_interrupt_func (NULL_TREE)))
1097
1098 /* Returns either the lowest numbered and highest numbered registers that
1099    occupy the call-saved area of the stack frame, if the registers are
1100    stored as a contiguous block, or else a bitmask of the individual
1101    registers if they are stored piecemeal.
1102
1103    Also computes the size of the frame and the size of the outgoing
1104    arguments block (in bytes).  */
1105
1106 static void
1107 rx_get_stack_layout (unsigned int * lowest,
1108                      unsigned int * highest,
1109                      unsigned int * register_mask,
1110                      unsigned int * frame_size,
1111                      unsigned int * stack_size)
1112 {
1113   unsigned int reg;
1114   unsigned int low;
1115   unsigned int high;
1116   unsigned int fixed_reg = 0;
1117   unsigned int save_mask;
1118   unsigned int pushed_mask;
1119   unsigned int unneeded_pushes;
1120
1121   if (is_naked_func (NULL_TREE))
1122     {
1123       /* Naked functions do not create their own stack frame.
1124          Instead the programmer must do that for us.  */
1125       * lowest = 0;
1126       * highest = 0;
1127       * register_mask = 0;
1128       * frame_size = 0;
1129       * stack_size = 0;
1130       return;
1131     }
1132
1133   for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++)
1134     {
1135       if ((df_regs_ever_live_p (reg)
1136            /* Always save all call clobbered registers inside interrupt
1137               handlers, even if they are not live - they may be used in
1138               routines called from this one.  */
1139            || (call_used_regs[reg] && is_interrupt_func (NULL_TREE)))
1140           && (! call_used_regs[reg]
1141               /* Even call clobbered registered must
1142                  be pushed inside interrupt handlers.  */
1143               || is_interrupt_func (NULL_TREE)
1144               /* Likewise for fast interrupt handlers, except registers r10 -
1145                  r13.  These are normally call-saved, but may have been set
1146                  to call-used by rx_conditional_register_usage.  If so then
1147                  they can be used in the fast interrupt handler without
1148                  saving them on the stack.  */
1149               || (is_fast_interrupt_func (NULL_TREE)
1150                   && ! IN_RANGE (reg, 10, 13))))
1151         {
1152           if (low == 0)
1153             low = reg;
1154           high = reg;
1155
1156           save_mask |= 1 << reg;
1157         }
1158
1159       /* Remember if we see a fixed register
1160          after having found the low register.  */
1161       if (low != 0 && fixed_reg == 0 && fixed_regs [reg])
1162         fixed_reg = reg;
1163     }
1164
1165   /* If we have to save the accumulator register, make sure
1166      that at least two registers are pushed into the frame.  */
1167   if (MUST_SAVE_ACC_REGISTER
1168       && bit_count (save_mask) < 2)
1169     {
1170       save_mask |= (1 << 13) | (1 << 14);
1171       if (low == 0)
1172         low = 13;
1173       if (high == 0 || low == high)
1174         high = low + 1;
1175     }
1176
1177   /* Decide if it would be faster fill in the call-saved area of the stack
1178      frame using multiple PUSH instructions instead of a single PUSHM
1179      instruction.
1180
1181      SAVE_MASK is a bitmask of the registers that must be stored in the
1182      call-save area.  PUSHED_MASK is a bitmask of the registers that would
1183      be pushed into the area if we used a PUSHM instruction.  UNNEEDED_PUSHES
1184      is a bitmask of those registers in pushed_mask that are not in
1185      save_mask.
1186
1187      We use a simple heuristic that says that it is better to use
1188      multiple PUSH instructions if the number of unnecessary pushes is
1189      greater than the number of necessary pushes.
1190
1191      We also use multiple PUSH instructions if there are any fixed registers
1192      between LOW and HIGH.  The only way that this can happen is if the user
1193      has specified --fixed-<reg-name> on the command line and in such
1194      circumstances we do not want to touch the fixed registers at all.
1195
1196      FIXME: Is it worth improving this heuristic ?  */
1197   pushed_mask = (-1 << low) & ~(-1 << (high + 1));
1198   unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
1199
1200   if ((fixed_reg && fixed_reg <= high)
1201       || (optimize_function_for_speed_p (cfun)
1202           && bit_count (save_mask) < bit_count (unneeded_pushes)))
1203     {
1204       /* Use multiple pushes.  */
1205       * lowest = 0;
1206       * highest = 0;
1207       * register_mask = save_mask;
1208     }
1209   else
1210     {
1211       /* Use one push multiple instruction.  */
1212       * lowest = low;
1213       * highest = high;
1214       * register_mask = 0;
1215     }
1216
1217   * frame_size = rx_round_up
1218     (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT);
1219
1220   if (crtl->args.size > 0)
1221     * frame_size += rx_round_up
1222       (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT);
1223
1224   * stack_size = rx_round_up
1225     (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT);
1226 }
1227
1228 /* Generate a PUSHM instruction that matches the given operands.  */
1229
1230 void
1231 rx_emit_stack_pushm (rtx * operands)
1232 {
1233   HOST_WIDE_INT last_reg;
1234   rtx first_push;
1235
1236   gcc_assert (CONST_INT_P (operands[0]));
1237   last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1;
1238
1239   gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1240   first_push = XVECEXP (operands[1], 0, 1);
1241   gcc_assert (SET_P (first_push));
1242   first_push = SET_SRC (first_push);
1243   gcc_assert (REG_P (first_push));
1244
1245   asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
1246                reg_names [REGNO (first_push) - last_reg],
1247                reg_names [REGNO (first_push)]);
1248 }
1249
1250 /* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate.  */
1251
1252 static rtx
1253 gen_rx_store_vector (unsigned int low, unsigned int high)
1254 {
1255   unsigned int i;
1256   unsigned int count = (high - low) + 2;
1257   rtx vector;
1258
1259   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1260
1261   XVECEXP (vector, 0, 0) =
1262     gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1263                  gen_rtx_MINUS (SImode, stack_pointer_rtx,
1264                                 GEN_INT ((count - 1) * UNITS_PER_WORD)));
1265
1266   for (i = 0; i < count - 1; i++)
1267     XVECEXP (vector, 0, i + 1) =
1268       gen_rtx_SET (VOIDmode,
1269                    gen_rtx_MEM (SImode,
1270                                 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1271                                                GEN_INT ((i + 1) * UNITS_PER_WORD))),
1272                    gen_rtx_REG (SImode, high - i));
1273   return vector;
1274 }
1275
1276 /* Mark INSN as being frame related.  If it is a PARALLEL
1277    then mark each element as being frame related as well.  */
1278
1279 static void
1280 mark_frame_related (rtx insn)
1281 {
1282   RTX_FRAME_RELATED_P (insn) = 1;
1283   insn = PATTERN (insn);
1284
1285   if (GET_CODE (insn) == PARALLEL)
1286     {
1287       unsigned int i;
1288
1289       for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
1290         RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
1291     }
1292 }
1293
1294 static bool
1295 ok_for_max_constant (HOST_WIDE_INT val)
1296 {
1297   if (rx_max_constant_size == 0  || rx_max_constant_size == 4)
1298     /* If there is no constraint on the size of constants
1299        used as operands, then any value is legitimate.  */
1300     return true;
1301
1302   /* rx_max_constant_size specifies the maximum number
1303      of bytes that can be used to hold a signed value.  */
1304   return IN_RANGE (val, (-1 << (rx_max_constant_size * 8)),
1305                         ( 1 << (rx_max_constant_size * 8)));
1306 }
1307
1308 /* Generate an ADD of SRC plus VAL into DEST.
1309    Handles the case where VAL is too big for max_constant_value.
1310    Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true.  */
1311
1312 static void
1313 gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
1314 {
1315   rtx insn;
1316
1317   if (val == NULL_RTX || INTVAL (val) == 0)
1318     {
1319       gcc_assert (dest != src);
1320
1321       insn = emit_move_insn (dest, src);
1322     }
1323   else if (ok_for_max_constant (INTVAL (val)))
1324     insn = emit_insn (gen_addsi3 (dest, src, val));
1325   else
1326     {
1327       insn = emit_insn (gen_addsi3_unspec (dest, src, val));
1328
1329       if (is_frame_related)
1330         /* We have to provide our own frame related note here
1331            as the dwarf2out code cannot be expected to grok
1332            our unspec.  */
1333         add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1334                       gen_rtx_SET (SImode, dest,
1335                                    gen_rtx_PLUS (SImode, src, val)));
1336       return;
1337     }
1338
1339   if (is_frame_related)
1340     RTX_FRAME_RELATED_P (insn) = 1;
1341   return;
1342 }
1343
1344 void
1345 rx_expand_prologue (void)
1346 {
1347   unsigned int stack_size;
1348   unsigned int frame_size;
1349   unsigned int mask;
1350   unsigned int low;
1351   unsigned int high;
1352   unsigned int reg;
1353   rtx insn;
1354
1355   /* Naked functions use their own, programmer provided prologues.  */
1356   if (is_naked_func (NULL_TREE))
1357     return;
1358
1359   rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1360
1361   /* If we use any of the callee-saved registers, save them now.  */
1362   if (mask)
1363     {
1364       /* Push registers in reverse order.  */
1365       for (reg = CC_REGNUM; reg --;)
1366         if (mask & (1 << reg))
1367           {
1368             insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
1369             mark_frame_related (insn);
1370           }
1371     }
1372   else if (low)
1373     {
1374       if (high == low)
1375         insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
1376       else
1377         insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1)
1378                                                     * UNITS_PER_WORD),
1379                                            gen_rx_store_vector (low, high)));
1380       mark_frame_related (insn);
1381     }
1382
1383   if (MUST_SAVE_ACC_REGISTER)
1384     {
1385       unsigned int acc_high, acc_low;
1386
1387       /* Interrupt handlers have to preserve the accumulator
1388          register if so requested by the user.  Use the first
1389          two pushed registers as intermediaries.  */
1390       if (mask)
1391         {
1392           acc_low = acc_high = 0;
1393
1394           for (reg = 1; reg < CC_REGNUM; reg ++)
1395             if (mask & (1 << reg))
1396               {
1397                 if (acc_low == 0)
1398                   acc_low = reg;
1399                 else
1400                   {
1401                     acc_high = reg;
1402                     break;
1403                   }
1404               }
1405             
1406           /* We have assumed that there are at least two registers pushed... */
1407           gcc_assert (acc_high != 0);
1408
1409           /* Note - the bottom 16 bits of the accumulator are inaccessible.
1410              We just assume that they are zero.  */
1411           emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1412           emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1413           emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low)));
1414           emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high)));
1415         }
1416       else
1417         {
1418           acc_low = low;
1419           acc_high = low + 1;
1420
1421           /* We have assumed that there are at least two registers pushed... */
1422           gcc_assert (acc_high <= high);
1423
1424           emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1425           emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1426           emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD),
1427                                       gen_rx_store_vector (acc_low, acc_high)));
1428         }
1429     }
1430
1431   /* If needed, set up the frame pointer.  */
1432   if (frame_pointer_needed)
1433     gen_safe_add (frame_pointer_rtx, stack_pointer_rtx,
1434                   GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1435
1436   /* Allocate space for the outgoing args.
1437      If the stack frame has not already been set up then handle this as well.  */
1438   if (stack_size)
1439     {
1440       if (frame_size)
1441         {
1442           if (frame_pointer_needed)
1443             gen_safe_add (stack_pointer_rtx, frame_pointer_rtx,
1444                           GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1445           else
1446             gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1447                           GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)),
1448                           true);
1449         }
1450       else
1451         gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1452                       GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1453     }
1454   else if (frame_size)
1455     {
1456       if (! frame_pointer_needed)
1457         gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1458                       GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1459       else
1460         gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
1461                       true);
1462     }
1463 }
1464
1465 static void
1466 rx_output_function_prologue (FILE * file,
1467                              HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
1468 {
1469   if (is_fast_interrupt_func (NULL_TREE))
1470     asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
1471
1472   if (is_interrupt_func (NULL_TREE))
1473     asm_fprintf (file, "\t; Note: Interrupt Handler\n");
1474
1475   if (is_naked_func (NULL_TREE))
1476     asm_fprintf (file, "\t; Note: Naked Function\n");
1477
1478   if (cfun->static_chain_decl != NULL)
1479     asm_fprintf (file, "\t; Note: Nested function declared "
1480                  "inside another function.\n");
1481
1482   if (crtl->calls_eh_return)
1483     asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n");
1484 }
1485
1486 /* Generate a POPM or RTSD instruction that matches the given operands.  */
1487
1488 void
1489 rx_emit_stack_popm (rtx * operands, bool is_popm)
1490 {
1491   HOST_WIDE_INT stack_adjust;
1492   HOST_WIDE_INT last_reg;
1493   rtx first_push;
1494
1495   gcc_assert (CONST_INT_P (operands[0]));
1496   stack_adjust = INTVAL (operands[0]);
1497   
1498   gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1499   last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3);
1500
1501   first_push = XVECEXP (operands[1], 0, 1);
1502   gcc_assert (SET_P (first_push));
1503   first_push = SET_DEST (first_push);
1504   gcc_assert (REG_P (first_push));
1505
1506   if (is_popm)
1507     asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n",
1508                  reg_names [REGNO (first_push)],
1509                  reg_names [REGNO (first_push) + last_reg]);
1510   else
1511     asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n",
1512                  (int) stack_adjust,
1513                  reg_names [REGNO (first_push)],
1514                  reg_names [REGNO (first_push) + last_reg]);
1515 }
1516
1517 /* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate.  */
1518
1519 static rtx
1520 gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high)
1521 {
1522   unsigned int i;
1523   unsigned int bias = 3;
1524   unsigned int count = (high - low) + bias;
1525   rtx vector;
1526
1527   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1528
1529   XVECEXP (vector, 0, 0) =
1530     gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1531                  plus_constant (stack_pointer_rtx, adjust));
1532
1533   for (i = 0; i < count - 2; i++)
1534     XVECEXP (vector, 0, i + 1) =
1535       gen_rtx_SET (VOIDmode,
1536                    gen_rtx_REG (SImode, low + i),
1537                    gen_rtx_MEM (SImode,
1538                                 i == 0 ? stack_pointer_rtx
1539                                 : plus_constant (stack_pointer_rtx,
1540                                                  i * UNITS_PER_WORD)));
1541
1542   XVECEXP (vector, 0, count - 1) = gen_rtx_RETURN (VOIDmode);
1543
1544   return vector;
1545 }
1546   
1547 /* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate.  */
1548
1549 static rtx
1550 gen_rx_popm_vector (unsigned int low, unsigned int high)
1551 {
1552   unsigned int i;  
1553   unsigned int count = (high - low) + 2;
1554   rtx vector;
1555
1556   vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1557
1558   XVECEXP (vector, 0, 0) =
1559     gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1560                  plus_constant (stack_pointer_rtx,
1561                                 (count - 1) * UNITS_PER_WORD));
1562
1563   for (i = 0; i < count - 1; i++)
1564     XVECEXP (vector, 0, i + 1) =
1565       gen_rtx_SET (VOIDmode,
1566                    gen_rtx_REG (SImode, low + i),
1567                    gen_rtx_MEM (SImode,
1568                                 i == 0 ? stack_pointer_rtx
1569                                 : plus_constant (stack_pointer_rtx,
1570                                                  i * UNITS_PER_WORD)));
1571
1572   return vector;
1573 }
1574   
1575 void
1576 rx_expand_epilogue (bool is_sibcall)
1577 {
1578   unsigned int low;
1579   unsigned int high;
1580   unsigned int frame_size;
1581   unsigned int stack_size;
1582   unsigned int register_mask;
1583   unsigned int regs_size;
1584   unsigned int reg;
1585   unsigned HOST_WIDE_INT total_size;
1586
1587   /* FIXME: We do not support indirect sibcalls at the moment becaause we
1588      cannot guarantee that the register holding the function address is a
1589      call-used register.  If it is a call-saved register then the stack
1590      pop instructions generated in the epilogue will corrupt the address
1591      before it is used.
1592
1593      Creating a new call-used-only register class works but then the
1594      reload pass gets stuck because it cannot always find a call-used
1595      register for spilling sibcalls.
1596
1597      The other possible solution is for this pass to scan forward for the
1598      sibcall instruction (if it has been generated) and work out if it
1599      is an indirect sibcall using a call-saved register.  If it is then
1600      the address can copied into a call-used register in this epilogue
1601      code and the sibcall instruction modified to use that register.  */
1602
1603   if (is_naked_func (NULL_TREE))
1604     {
1605       gcc_assert (! is_sibcall);
1606
1607       /* Naked functions use their own, programmer provided epilogues.
1608          But, in order to keep gcc happy we have to generate some kind of
1609          epilogue RTL.  */
1610       emit_jump_insn (gen_naked_return ());
1611       return;
1612     }
1613
1614   rx_get_stack_layout (& low, & high, & register_mask,
1615                        & frame_size, & stack_size);
1616
1617   total_size = frame_size + stack_size;
1618   regs_size = ((high - low) + 1) * UNITS_PER_WORD;
1619
1620   /* See if we are unable to use the special stack frame deconstruct and
1621      return instructions.  In most cases we can use them, but the exceptions
1622      are:
1623
1624      - Sibling calling functions deconstruct the frame but do not return to
1625        their caller.  Instead they branch to their sibling and allow their
1626        return instruction to return to this function's parent.
1627
1628      - Fast and normal interrupt handling functions have to use special
1629        return instructions.
1630
1631      - Functions where we have pushed a fragmented set of registers into the
1632        call-save area must have the same set of registers popped.  */
1633   if (is_sibcall
1634       || is_fast_interrupt_func (NULL_TREE)
1635       || is_interrupt_func (NULL_TREE)
1636       || register_mask)
1637     {
1638       /* Cannot use the special instructions - deconstruct by hand.  */
1639       if (total_size)
1640         gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1641                       GEN_INT (total_size), false);
1642
1643       if (MUST_SAVE_ACC_REGISTER)
1644         {
1645           unsigned int acc_low, acc_high;
1646
1647           /* Reverse the saving of the accumulator register onto the stack.
1648              Note we must adjust the saved "low" accumulator value as it
1649              is really the middle 32-bits of the accumulator.  */
1650           if (register_mask)
1651             {
1652               acc_low = acc_high = 0;
1653
1654               for (reg = 1; reg < CC_REGNUM; reg ++)
1655                 if (register_mask & (1 << reg))
1656                   {
1657                     if (acc_low == 0)
1658                       acc_low = reg;
1659                     else
1660                       {
1661                         acc_high = reg;
1662                         break;
1663                       }
1664                   }
1665               emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high)));
1666               emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low)));
1667             }
1668           else
1669             {
1670               acc_low = low;
1671               acc_high = low + 1;
1672               emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD),
1673                                          gen_rx_popm_vector (acc_low, acc_high)));
1674             }
1675
1676           emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low),
1677                                   gen_rtx_REG (SImode, acc_low),
1678                                   GEN_INT (16)));
1679           emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low)));
1680           emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high)));
1681         }
1682
1683       if (register_mask)
1684         {
1685           for (reg = 0; reg < CC_REGNUM; reg ++)
1686             if (register_mask & (1 << reg))
1687               emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
1688         }
1689       else if (low)
1690         {
1691           if (high == low)
1692             emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
1693           else
1694             emit_insn (gen_stack_popm (GEN_INT (regs_size),
1695                                        gen_rx_popm_vector (low, high)));
1696         }
1697
1698       if (is_fast_interrupt_func (NULL_TREE))
1699         {
1700           gcc_assert (! is_sibcall);
1701           emit_jump_insn (gen_fast_interrupt_return ());
1702         }
1703       else if (is_interrupt_func (NULL_TREE))
1704         {
1705           gcc_assert (! is_sibcall);
1706           emit_jump_insn (gen_exception_return ());
1707         }
1708       else if (! is_sibcall)
1709         emit_jump_insn (gen_simple_return ());
1710
1711       return;
1712     }
1713
1714   /* If we allocated space on the stack, free it now.  */
1715   if (total_size)
1716     {
1717       unsigned HOST_WIDE_INT rtsd_size;
1718
1719       /* See if we can use the RTSD instruction.  */
1720       rtsd_size = total_size + regs_size;
1721       if (rtsd_size < 1024 && (rtsd_size % 4) == 0)
1722         {
1723           if (low)
1724             emit_jump_insn (gen_pop_and_return
1725                             (GEN_INT (rtsd_size),
1726                              gen_rx_rtsd_vector (rtsd_size, low, high)));
1727           else
1728             emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size)));
1729
1730           return;
1731         }
1732
1733       gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1734                     GEN_INT (total_size), false);
1735     }
1736
1737   if (low)
1738     emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size),
1739                                         gen_rx_rtsd_vector (regs_size,
1740                                                             low, high)));
1741   else
1742     emit_jump_insn (gen_simple_return ());
1743 }
1744
1745
1746 /* Compute the offset (in words) between FROM (arg pointer
1747    or frame pointer) and TO (frame pointer or stack pointer).
1748    See ASCII art comment at the start of rx_expand_prologue
1749    for more information.  */
1750
1751 int
1752 rx_initial_elimination_offset (int from, int to)
1753 {
1754   unsigned int low;
1755   unsigned int high;
1756   unsigned int frame_size;
1757   unsigned int stack_size;
1758   unsigned int mask;
1759
1760   rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1761
1762   if (from == ARG_POINTER_REGNUM)
1763     {
1764       /* Extend the computed size of the stack frame to
1765          include the registers pushed in the prologue.  */
1766       if (low)
1767         frame_size += ((high - low) + 1) * UNITS_PER_WORD;
1768       else
1769         frame_size += bit_count (mask) * UNITS_PER_WORD;
1770
1771       /* Remember to include the return address.  */
1772       frame_size += 1 * UNITS_PER_WORD;
1773
1774       if (to == FRAME_POINTER_REGNUM)
1775         return frame_size;
1776
1777       gcc_assert (to == STACK_POINTER_REGNUM);
1778       return frame_size + stack_size;
1779     }
1780
1781   gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM);
1782   return stack_size;
1783 }
1784
1785 /* Decide if a variable should go into one of the small data sections.  */
1786
1787 static bool
1788 rx_in_small_data (const_tree decl)
1789 {
1790   int size;
1791   const_tree section;
1792
1793   if (rx_small_data_limit == 0)
1794     return false;
1795
1796   if (TREE_CODE (decl) != VAR_DECL)
1797     return false;
1798
1799   /* We do not put read-only variables into a small data area because
1800      they would be placed with the other read-only sections, far away
1801      from the read-write data sections, and we only have one small
1802      data area pointer.
1803      Similarly commons are placed in the .bss section which might be
1804      far away (and out of alignment with respect to) the .data section.  */
1805   if (TREE_READONLY (decl) || DECL_COMMON (decl))
1806     return false;
1807
1808   section = DECL_SECTION_NAME (decl);
1809   if (section)
1810     {
1811       const char * const name = TREE_STRING_POINTER (section);
1812
1813       return (strcmp (name, "D_2") == 0) || (strcmp (name, "B_2") == 0);
1814     }
1815
1816   size = int_size_in_bytes (TREE_TYPE (decl));
1817
1818   return (size > 0) && (size <= rx_small_data_limit);
1819 }
1820
1821 /* Return a section for X.
1822    The only special thing we do here is to honor small data.  */
1823
1824 static section *
1825 rx_select_rtx_section (enum machine_mode mode,
1826                        rtx x,
1827                        unsigned HOST_WIDE_INT align)
1828 {
1829   if (rx_small_data_limit > 0
1830       && GET_MODE_SIZE (mode) <= rx_small_data_limit
1831       && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
1832     return sdata_section;
1833
1834   return default_elf_select_rtx_section (mode, x, align);
1835 }
1836
1837 static section *
1838 rx_select_section (tree decl,
1839                    int reloc,
1840                    unsigned HOST_WIDE_INT align)
1841 {
1842   if (rx_small_data_limit > 0)
1843     {
1844       switch (categorize_decl_for_section (decl, reloc))
1845         {
1846         case SECCAT_SDATA:      return sdata_section;
1847         case SECCAT_SBSS:       return sbss_section;
1848         case SECCAT_SRODATA:
1849           /* Fall through.  We do not put small, read only
1850              data into the C_2 section because we are not
1851              using the C_2 section.  We do not use the C_2
1852              section because it is located with the other
1853              read-only data sections, far away from the read-write
1854              data sections and we only have one small data
1855              pointer (r13).  */
1856         default:
1857           break;
1858         }
1859     }
1860
1861   /* If we are supporting the Renesas assembler
1862      we cannot use mergeable sections.  */
1863   if (TARGET_AS100_SYNTAX)
1864     switch (categorize_decl_for_section (decl, reloc))
1865       {
1866       case SECCAT_RODATA_MERGE_CONST:
1867       case SECCAT_RODATA_MERGE_STR_INIT:
1868       case SECCAT_RODATA_MERGE_STR:
1869         return readonly_data_section;
1870
1871       default:
1872         break;
1873       }
1874
1875   return default_elf_select_section (decl, reloc, align);
1876 }
1877 \f
1878 enum rx_builtin
1879 {
1880   RX_BUILTIN_BRK,
1881   RX_BUILTIN_CLRPSW,
1882   RX_BUILTIN_INT,
1883   RX_BUILTIN_MACHI,
1884   RX_BUILTIN_MACLO,
1885   RX_BUILTIN_MULHI,
1886   RX_BUILTIN_MULLO,
1887   RX_BUILTIN_MVFACHI,
1888   RX_BUILTIN_MVFACMI,
1889   RX_BUILTIN_MVFC,
1890   RX_BUILTIN_MVTACHI,
1891   RX_BUILTIN_MVTACLO,
1892   RX_BUILTIN_MVTC,
1893   RX_BUILTIN_MVTIPL,
1894   RX_BUILTIN_RACW,
1895   RX_BUILTIN_REVW,
1896   RX_BUILTIN_RMPA,
1897   RX_BUILTIN_ROUND,
1898   RX_BUILTIN_SETPSW,
1899   RX_BUILTIN_WAIT,
1900   RX_BUILTIN_max
1901 };
1902
1903 static void
1904 rx_init_builtins (void)
1905 {
1906 #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE)           \
1907   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1908                         build_function_type_list (RET_TYPE##_type_node, \
1909                                                   ARG_TYPE##_type_node, \
1910                                                   NULL_TREE),           \
1911                         RX_BUILTIN_##UC_NAME,                           \
1912                         BUILT_IN_MD, NULL, NULL_TREE)
1913
1914 #define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
1915   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1916                         build_function_type_list (RET_TYPE##_type_node, \
1917                                                   ARG_TYPE1##_type_node,\
1918                                                   ARG_TYPE2##_type_node,\
1919                                                   NULL_TREE),           \
1920                         RX_BUILTIN_##UC_NAME,                           \
1921                         BUILT_IN_MD, NULL, NULL_TREE)
1922
1923 #define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
1924   add_builtin_function ("__builtin_rx_" LC_NAME,                        \
1925                         build_function_type_list (RET_TYPE##_type_node, \
1926                                                   ARG_TYPE1##_type_node,\
1927                                                   ARG_TYPE2##_type_node,\
1928                                                   ARG_TYPE3##_type_node,\
1929                                                   NULL_TREE),           \
1930                         RX_BUILTIN_##UC_NAME,                           \
1931                         BUILT_IN_MD, NULL, NULL_TREE)
1932
1933   ADD_RX_BUILTIN1 (BRK,     "brk",     void,  void);
1934   ADD_RX_BUILTIN1 (CLRPSW,  "clrpsw",  void,  integer);
1935   ADD_RX_BUILTIN1 (SETPSW,  "setpsw",  void,  integer);
1936   ADD_RX_BUILTIN1 (INT,     "int",     void,  integer);
1937   ADD_RX_BUILTIN2 (MACHI,   "machi",   void,  intSI, intSI);
1938   ADD_RX_BUILTIN2 (MACLO,   "maclo",   void,  intSI, intSI);
1939   ADD_RX_BUILTIN2 (MULHI,   "mulhi",   void,  intSI, intSI);
1940   ADD_RX_BUILTIN2 (MULLO,   "mullo",   void,  intSI, intSI);
1941   ADD_RX_BUILTIN1 (MVFACHI, "mvfachi", intSI, void);
1942   ADD_RX_BUILTIN1 (MVFACMI, "mvfacmi", intSI, void);
1943   ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void,  intSI);
1944   ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void,  intSI);
1945   ADD_RX_BUILTIN1 (RMPA,    "rmpa",    void,  void);
1946   ADD_RX_BUILTIN1 (MVFC,    "mvfc",    intSI, integer);
1947   ADD_RX_BUILTIN2 (MVTC,    "mvtc",    void,  integer, integer);
1948   ADD_RX_BUILTIN1 (MVTIPL,  "mvtipl",  void,  integer);
1949   ADD_RX_BUILTIN1 (RACW,    "racw",    void,  integer);
1950   ADD_RX_BUILTIN1 (ROUND,   "round",   intSI, float);
1951   ADD_RX_BUILTIN1 (REVW,    "revw",    intSI, intSI);
1952   ADD_RX_BUILTIN1 (WAIT,    "wait",    void,  void);
1953 }
1954
1955 static rtx
1956 rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
1957 {
1958   if (reg && ! REG_P (arg))
1959     arg = force_reg (SImode, arg);
1960
1961   emit_insn (gen_func (arg));
1962
1963   return NULL_RTX;
1964 }
1965
1966 static rtx
1967 rx_expand_builtin_mvtc (tree exp)
1968 {
1969   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1970   rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
1971
1972   if (! CONST_INT_P (arg1))
1973     return NULL_RTX;
1974
1975   if (! REG_P (arg2))
1976     arg2 = force_reg (SImode, arg2);
1977
1978   emit_insn (gen_mvtc (arg1, arg2));
1979
1980   return NULL_RTX;
1981 }
1982
1983 static rtx
1984 rx_expand_builtin_mvfc (tree t_arg, rtx target)
1985 {
1986   rtx arg = expand_normal (t_arg);
1987
1988   if (! CONST_INT_P (arg))
1989     return NULL_RTX;
1990
1991   if (target == NULL_RTX)
1992     return NULL_RTX;
1993
1994   if (! REG_P (target))
1995     target = force_reg (SImode, target);
1996
1997   emit_insn (gen_mvfc (target, arg));
1998
1999   return target;
2000 }
2001
2002 static rtx
2003 rx_expand_builtin_mvtipl (rtx arg)
2004 {
2005   /* The RX610 does not support the MVTIPL instruction.  */
2006   if (rx_cpu_type == RX610)
2007     return NULL_RTX;
2008
2009   if (! CONST_INT_P (arg) || ! IN_RANGE (INTVAL (arg), 0, (1 << 4) - 1))
2010     return NULL_RTX;
2011
2012   emit_insn (gen_mvtipl (arg));
2013
2014   return NULL_RTX;
2015 }
2016
2017 static rtx
2018 rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
2019 {
2020   rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2021   rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2022
2023   if (! REG_P (arg1))
2024     arg1 = force_reg (SImode, arg1);
2025
2026   if (! REG_P (arg2))
2027     arg2 = force_reg (SImode, arg2);
2028
2029   emit_insn (gen_func (arg1, arg2));
2030
2031   return NULL_RTX;
2032 }
2033
2034 static rtx
2035 rx_expand_int_builtin_1_arg (rtx arg,
2036                              rtx target,
2037                              rtx (* gen_func)(rtx, rtx),
2038                              bool mem_ok)
2039 {
2040   if (! REG_P (arg))
2041     if (!mem_ok || ! MEM_P (arg))
2042       arg = force_reg (SImode, arg);
2043
2044   if (target == NULL_RTX || ! REG_P (target))
2045     target = gen_reg_rtx (SImode);
2046
2047   emit_insn (gen_func (target, arg));
2048
2049   return target;
2050 }
2051
2052 static rtx
2053 rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx))
2054 {
2055   if (target == NULL_RTX || ! REG_P (target))
2056     target = gen_reg_rtx (SImode);
2057
2058   emit_insn (gen_func (target));
2059
2060   return target;
2061 }
2062
2063 static rtx
2064 rx_expand_builtin_round (rtx arg, rtx target)
2065 {
2066   if ((! REG_P (arg) && ! MEM_P (arg))
2067       || GET_MODE (arg) != SFmode)
2068     arg = force_reg (SFmode, arg);
2069
2070   if (target == NULL_RTX || ! REG_P (target))
2071     target = gen_reg_rtx (SImode);
2072
2073   emit_insn (gen_lrintsf2 (target, arg));
2074
2075   return target;
2076 }
2077
2078 static int
2079 valid_psw_flag (rtx op, const char *which)
2080 {
2081   static int mvtc_inform_done = 0;
2082
2083   if (GET_CODE (op) == CONST_INT)
2084     switch (INTVAL (op))
2085       {
2086       case 0: case 'c': case 'C':
2087       case 1: case 'z': case 'Z':
2088       case 2: case 's': case 'S':
2089       case 3: case 'o': case 'O':
2090       case 8: case 'i': case 'I':
2091       case 9: case 'u': case 'U':
2092         return 1;
2093       }
2094
2095   error ("__builtin_rx_%s takes 'C', 'Z', 'S', 'O', 'I', or 'U'", which);
2096   if (!mvtc_inform_done)
2097     error ("use __builtin_rx_mvtc (0, ... ) to write arbitrary values to PSW");
2098   mvtc_inform_done = 1;
2099
2100   return 0;
2101 }
2102
2103 static rtx
2104 rx_expand_builtin (tree exp,
2105                    rtx target,
2106                    rtx subtarget ATTRIBUTE_UNUSED,
2107                    enum machine_mode mode ATTRIBUTE_UNUSED,
2108                    int ignore ATTRIBUTE_UNUSED)
2109 {
2110   tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2111   tree arg    = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
2112   rtx  op     = arg ? expand_normal (arg) : NULL_RTX;
2113   unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2114
2115   switch (fcode)
2116     {
2117     case RX_BUILTIN_BRK:     emit_insn (gen_brk ()); return NULL_RTX;
2118     case RX_BUILTIN_CLRPSW:
2119       if (!valid_psw_flag (op, "clrpsw"))
2120         return NULL_RTX;
2121       return rx_expand_void_builtin_1_arg (op, gen_clrpsw, false);
2122     case RX_BUILTIN_SETPSW:
2123       if (!valid_psw_flag (op, "setpsw"))
2124         return NULL_RTX;
2125       return rx_expand_void_builtin_1_arg (op, gen_setpsw, false);
2126     case RX_BUILTIN_INT:     return rx_expand_void_builtin_1_arg
2127         (op, gen_int, false);
2128     case RX_BUILTIN_MACHI:   return rx_expand_builtin_mac (exp, gen_machi);
2129     case RX_BUILTIN_MACLO:   return rx_expand_builtin_mac (exp, gen_maclo);
2130     case RX_BUILTIN_MULHI:   return rx_expand_builtin_mac (exp, gen_mulhi);
2131     case RX_BUILTIN_MULLO:   return rx_expand_builtin_mac (exp, gen_mullo);
2132     case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg
2133         (target, gen_mvfachi);
2134     case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg
2135         (target, gen_mvfacmi);
2136     case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg
2137         (op, gen_mvtachi, true);
2138     case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg
2139         (op, gen_mvtaclo, true);
2140     case RX_BUILTIN_RMPA:    emit_insn (gen_rmpa ()); return NULL_RTX;
2141     case RX_BUILTIN_MVFC:    return rx_expand_builtin_mvfc (arg, target);
2142     case RX_BUILTIN_MVTC:    return rx_expand_builtin_mvtc (exp);
2143     case RX_BUILTIN_MVTIPL:  return rx_expand_builtin_mvtipl (op);
2144     case RX_BUILTIN_RACW:    return rx_expand_void_builtin_1_arg
2145         (op, gen_racw, false);
2146     case RX_BUILTIN_ROUND:   return rx_expand_builtin_round (op, target);
2147     case RX_BUILTIN_REVW:    return rx_expand_int_builtin_1_arg
2148         (op, target, gen_revw, false);
2149     case RX_BUILTIN_WAIT:    emit_insn (gen_wait ()); return NULL_RTX;
2150
2151     default:
2152       internal_error ("bad builtin code");
2153       break;
2154     }
2155
2156   return NULL_RTX;
2157 }
2158 \f
2159 /* Place an element into a constructor or destructor section.
2160    Like default_ctor_section_asm_out_constructor in varasm.c
2161    except that it uses .init_array (or .fini_array) and it
2162    handles constructor priorities.  */
2163
2164 static void
2165 rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
2166 {
2167   section * s;
2168
2169   if (priority != DEFAULT_INIT_PRIORITY)
2170     {
2171       char buf[18];
2172
2173       sprintf (buf, "%s.%.5u",
2174                is_ctor ? ".init_array" : ".fini_array",
2175                priority);
2176       s = get_section (buf, SECTION_WRITE, NULL_TREE);
2177     }
2178   else if (is_ctor)
2179     s = ctors_section;
2180   else
2181     s = dtors_section;
2182
2183   switch_to_section (s);
2184   assemble_align (POINTER_SIZE);
2185   assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2186 }
2187
2188 static void
2189 rx_elf_asm_constructor (rtx symbol, int priority)
2190 {
2191   rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true);
2192 }
2193
2194 static void
2195 rx_elf_asm_destructor (rtx symbol, int priority)
2196 {
2197   rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
2198 }
2199 \f
2200 /* Check "fast_interrupt", "interrupt" and "naked" attributes.  */
2201
2202 static tree
2203 rx_handle_func_attribute (tree * node,
2204                           tree   name,
2205                           tree   args,
2206                           int    flags ATTRIBUTE_UNUSED,
2207                           bool * no_add_attrs)
2208 {
2209   gcc_assert (DECL_P (* node));
2210   gcc_assert (args == NULL_TREE);
2211
2212   if (TREE_CODE (* node) != FUNCTION_DECL)
2213     {
2214       warning (OPT_Wattributes, "%qE attribute only applies to functions",
2215                name);
2216       * no_add_attrs = true;
2217     }
2218
2219   /* FIXME: We ought to check for conflicting attributes.  */
2220
2221   /* FIXME: We ought to check that the interrupt and exception
2222      handler attributes have been applied to void functions.  */
2223   return NULL_TREE;
2224 }
2225
2226 /* Table of RX specific attributes.  */
2227 const struct attribute_spec rx_attribute_table[] =
2228 {
2229   /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler.  */
2230   { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
2231   { "interrupt",      0, 0, true, false, false, rx_handle_func_attribute },
2232   { "naked",          0, 0, true, false, false, rx_handle_func_attribute },
2233   { NULL,             0, 0, false, false, false, NULL }
2234 };
2235
2236 /* Extra processing for target specific command line options.  */
2237
2238 static bool
2239 rx_handle_option (size_t code, const char *  arg ATTRIBUTE_UNUSED, int value)
2240 {
2241   switch (code)
2242     {
2243     case OPT_mint_register_:
2244       switch (value)
2245         {
2246         case 4:
2247           fixed_regs[10] = call_used_regs [10] = 1;
2248           /* Fall through.  */
2249         case 3:
2250           fixed_regs[11] = call_used_regs [11] = 1;
2251           /* Fall through.  */
2252         case 2:
2253           fixed_regs[12] = call_used_regs [12] = 1;
2254           /* Fall through.  */
2255         case 1:
2256           fixed_regs[13] = call_used_regs [13] = 1;
2257           /* Fall through.  */
2258         case 0:
2259           return true;
2260         default:
2261           return false;
2262         }
2263       break;
2264
2265     case OPT_mmax_constant_size_:
2266       /* Make sure that the -mmax-constant_size option is in range.  */
2267       return value >= 0 && value <= 4;
2268
2269     case OPT_mcpu_:
2270       if (strcasecmp (arg, "RX610") == 0)
2271         rx_cpu_type = RX610;
2272       else if (strcasecmp (arg, "RX200") == 0)
2273         {
2274           target_flags |= MASK_NO_USE_FPU;
2275           rx_cpu_type = RX200;
2276         }
2277       else if (strcasecmp (arg, "RX600") != 0)
2278         warning (0, "unrecognized argument '%s' to -mcpu= option", arg);
2279       break;
2280       
2281     case OPT_fpu:
2282       if (rx_cpu_type == RX200)
2283         error ("the RX200 cpu does not have FPU hardware");
2284       break;
2285
2286     default:
2287       break;
2288     }
2289
2290   return true;
2291 }
2292
2293 /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE.  */
2294
2295 static void
2296 rx_override_options_after_change (void)
2297 {
2298   static bool first_time = TRUE;
2299
2300   if (first_time)
2301     {
2302       /* If this is the first time through and the user has not disabled
2303          the use of RX FPU hardware then enable -ffinite-math-only,
2304          since the FPU instructions do not support NaNs and infinities.  */
2305       if (TARGET_USE_FPU)
2306         flag_finite_math_only = 1;
2307
2308       first_time = FALSE;
2309     }
2310   else
2311     {
2312       /* Alert the user if they are changing the optimization options
2313          to use IEEE compliant floating point arithmetic with RX FPU insns.  */
2314       if (TARGET_USE_FPU
2315           && !flag_finite_math_only)
2316         warning (0, "RX FPU instructions do not support NaNs and infinities");
2317     }
2318 }
2319
2320 static void
2321 rx_option_override (void)
2322 {
2323   /* This target defaults to strict volatile bitfields.  */
2324   if (flag_strict_volatile_bitfields < 0)
2325     flag_strict_volatile_bitfields = 1;
2326
2327   rx_override_options_after_change ();
2328 }
2329
2330 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE.  */
2331 static const struct default_options rx_option_optimization_table[] =
2332   {
2333     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
2334     { OPT_LEVELS_NONE, 0, NULL, 0 }
2335   };
2336
2337 \f
2338 static bool
2339 rx_allocate_stack_slots_for_args (void)
2340 {
2341   /* Naked functions should not allocate stack slots for arguments.  */
2342   return ! is_naked_func (NULL_TREE);
2343 }
2344
2345 static bool
2346 rx_func_attr_inlinable (const_tree decl)
2347 {
2348   return ! is_fast_interrupt_func (decl)
2349     &&   ! is_interrupt_func (decl)
2350     &&   ! is_naked_func (decl);  
2351 }
2352
2353 /* Return nonzero if it is ok to make a tail-call to DECL,
2354    a function_decl or NULL if this is an indirect call, using EXP  */
2355
2356 static bool
2357 rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
2358 {
2359   /* Do not allow indirect tailcalls.  The
2360      sibcall patterns do not support them.  */
2361   if (decl == NULL)
2362     return false;
2363
2364   /* Never tailcall from inside interrupt handlers or naked functions.  */
2365   if (is_fast_interrupt_func (NULL_TREE)
2366       || is_interrupt_func (NULL_TREE)
2367       || is_naked_func (NULL_TREE))
2368     return false;
2369
2370   return true;
2371 }
2372
2373 static void
2374 rx_file_start (void)
2375 {
2376   if (! TARGET_AS100_SYNTAX)
2377     default_file_start ();
2378 }
2379
2380 static bool
2381 rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
2382 {
2383   /* The packed attribute overrides the MS behaviour.  */
2384   return ! TYPE_PACKED (record_type);
2385 }
2386 \f
2387 /* Returns true if X a legitimate constant for an immediate
2388    operand on the RX.  X is already known to satisfy CONSTANT_P.  */
2389
2390 bool
2391 rx_is_legitimate_constant (rtx x)
2392 {
2393   switch (GET_CODE (x))
2394     {
2395     case CONST:
2396       x = XEXP (x, 0);
2397
2398       if (GET_CODE (x) == PLUS)
2399         {
2400           if (! CONST_INT_P (XEXP (x, 1)))
2401             return false;
2402
2403           /* GCC would not pass us CONST_INT + CONST_INT so we
2404              know that we have {SYMBOL|LABEL} + CONST_INT.  */
2405           x = XEXP (x, 0);
2406           gcc_assert (! CONST_INT_P (x));
2407         }
2408
2409       switch (GET_CODE (x))
2410         {
2411         case LABEL_REF:
2412         case SYMBOL_REF:
2413           return true;
2414
2415         case UNSPEC:
2416           return XINT (x, 1) == UNSPEC_CONST;
2417
2418         default:
2419           /* FIXME: Can this ever happen ?  */
2420           abort ();
2421           return false;
2422         }
2423       break;
2424       
2425     case LABEL_REF:
2426     case SYMBOL_REF:
2427       return true;
2428     case CONST_DOUBLE:
2429       return (rx_max_constant_size == 0 || rx_max_constant_size == 4);
2430     case CONST_VECTOR:
2431       return false;
2432     default:
2433       gcc_assert (CONST_INT_P (x));
2434       break;
2435     }
2436
2437   return ok_for_max_constant (INTVAL (x));
2438 }
2439
2440 static int
2441 rx_address_cost (rtx addr, bool speed)
2442 {
2443   rtx a, b;
2444
2445   if (GET_CODE (addr) != PLUS)
2446     return COSTS_N_INSNS (1);
2447
2448   a = XEXP (addr, 0);
2449   b = XEXP (addr, 1);
2450
2451   if (REG_P (a) && REG_P (b))
2452     /* Try to discourage REG+REG addressing as it keeps two registers live.  */
2453     return COSTS_N_INSNS (4);
2454
2455   if (speed)
2456     /* [REG+OFF] is just as fast as [REG].  */
2457     return COSTS_N_INSNS (1);
2458
2459   if (CONST_INT_P (b)
2460       && ((INTVAL (b) > 128) || INTVAL (b) < -127))
2461     /* Try to discourage REG + <large OFF> when optimizing for size.  */
2462     return COSTS_N_INSNS (2);
2463     
2464   return COSTS_N_INSNS (1);
2465 }
2466
2467 static bool
2468 rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2469 {
2470   /* We can always eliminate to the frame pointer.
2471      We can eliminate to the stack pointer unless a frame
2472      pointer is needed.  */
2473
2474   return to == FRAME_POINTER_REGNUM
2475     || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed);
2476 }
2477 \f
2478
2479 static void
2480 rx_trampoline_template (FILE * file)
2481 {
2482   /* Output assembler code for a block containing the constant
2483      part of a trampoline, leaving space for the variable parts.
2484
2485      On the RX, (where r8 is the static chain regnum) the trampoline
2486      looks like:
2487
2488            mov          #<static chain value>, r8
2489            mov          #<function's address>, r9
2490            jmp          r9
2491
2492      In big-endian-data-mode however instructions are read into the CPU
2493      4 bytes at a time.  These bytes are then swapped around before being
2494      passed to the decoder.  So...we must partition our trampoline into
2495      4 byte packets and swap these packets around so that the instruction
2496      reader will reverse the process.  But, in order to avoid splitting
2497      the 32-bit constants across these packet boundaries, (making inserting
2498      them into the constructed trampoline very difficult) we have to pad the
2499      instruction sequence with NOP insns.  ie:
2500
2501            nop
2502            nop
2503            mov.l        #<...>, r8
2504            nop
2505            nop
2506            mov.l        #<...>, r9
2507            jmp          r9
2508            nop
2509            nop             */
2510
2511   if (! TARGET_BIG_ENDIAN_DATA)
2512     {
2513       asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM);
2514       asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM);
2515       asm_fprintf (file, "\tjmp\tr%d\n",                TRAMPOLINE_TEMP_REGNUM);
2516     }
2517   else
2518     {
2519       char r8 = '0' + STATIC_CHAIN_REGNUM;
2520       char r9 = '0' + TRAMPOLINE_TEMP_REGNUM;
2521
2522       if (TARGET_AS100_SYNTAX)
2523         {
2524           asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r8);
2525           asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
2526           asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r9);
2527           asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
2528           asm_fprintf (file, "\t.BYTE 003H,  003H, 00%cH, 07fH\n", r9);
2529         }
2530       else
2531         {
2532           asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r8);
2533           asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
2534           asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r9);
2535           asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
2536           asm_fprintf (file, "\t.byte 0x03,  0x03, 0x0%c, 0x7f\n", r9);
2537         }
2538     }
2539 }
2540
2541 static void
2542 rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
2543 {
2544   rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2545
2546   emit_block_move (tramp, assemble_trampoline_template (),
2547                    GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2548
2549   if (TARGET_BIG_ENDIAN_DATA)
2550     {
2551       emit_move_insn (adjust_address (tramp, SImode, 4), chain);
2552       emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
2553     }
2554   else
2555     {
2556       emit_move_insn (adjust_address (tramp, SImode, 2), chain);
2557       emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr);
2558     }
2559 }
2560 \f
2561 static int
2562 rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in)
2563 {
2564   return 2 + memory_move_secondary_cost (mode, regclass, in);
2565 }
2566
2567 /* Convert a CC_MODE to the set of flags that it represents.  */
2568
2569 static unsigned int
2570 flags_from_mode (enum machine_mode mode)
2571 {
2572   switch (mode)
2573     {
2574     case CC_ZSmode:
2575       return CC_FLAG_S | CC_FLAG_Z;
2576     case CC_ZSOmode:
2577       return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
2578     case CC_ZSCmode:
2579       return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C;
2580     case CCmode:
2581       return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C;
2582     case CC_Fmode:
2583       return CC_FLAG_FP;
2584     default:
2585       gcc_unreachable ();
2586     }
2587 }
2588
2589 /* Convert a set of flags to a CC_MODE that can implement it.  */
2590
2591 static enum machine_mode
2592 mode_from_flags (unsigned int f)
2593 {
2594   if (f & CC_FLAG_FP)
2595     return CC_Fmode;
2596   if (f & CC_FLAG_O)
2597     {
2598       if (f & CC_FLAG_C)
2599         return CCmode;
2600       else
2601         return CC_ZSOmode;
2602     }
2603   else if (f & CC_FLAG_C)
2604     return CC_ZSCmode;
2605   else
2606     return CC_ZSmode;
2607 }
2608
2609 /* Convert an RTX_CODE to the set of flags needed to implement it.
2610    This assumes an integer comparison.  */
2611
2612 static unsigned int
2613 flags_from_code (enum rtx_code code)
2614 {
2615   switch (code)
2616     {
2617     case LT:
2618     case GE:
2619       return CC_FLAG_S;
2620     case GT:
2621     case LE:
2622       return CC_FLAG_S | CC_FLAG_O | CC_FLAG_Z;
2623     case GEU:
2624     case LTU:
2625       return CC_FLAG_C;
2626     case GTU:
2627     case LEU:
2628       return CC_FLAG_C | CC_FLAG_Z;
2629     case EQ:
2630     case NE:
2631       return CC_FLAG_Z;
2632     default:
2633       gcc_unreachable ();
2634     }
2635 }
2636
2637 /* Return a CC_MODE of which both M1 and M2 are subsets.  */
2638
2639 static enum machine_mode
2640 rx_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
2641 {
2642   unsigned f;
2643
2644   /* Early out for identical modes.  */
2645   if (m1 == m2)
2646     return m1;
2647
2648   /* There's no valid combination for FP vs non-FP.  */
2649   f = flags_from_mode (m1) | flags_from_mode (m2);
2650   if (f & CC_FLAG_FP)
2651     return VOIDmode;
2652
2653   /* Otherwise, see what mode can implement all the flags.  */
2654   return mode_from_flags (f);
2655 }
2656
2657 /* Return the minimal CC mode needed to implement (CMP_CODE X Y).  */
2658
2659 enum machine_mode
2660 rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y ATTRIBUTE_UNUSED)
2661 {
2662   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
2663     return CC_Fmode;
2664
2665   return mode_from_flags (flags_from_code (cmp_code));
2666 }
2667
2668 /* Split the floating-point comparison IN into individual comparisons
2669    O1 and O2.  O2 may be UNKNOWN if there is no second comparison.
2670    Return true iff the comparison operands must be swapped.  */
2671
2672 bool
2673 rx_split_fp_compare (enum rtx_code in, enum rtx_code *o1, enum rtx_code *o2)
2674 {
2675   enum rtx_code cmp1 = in, cmp2 = UNKNOWN;
2676   bool swap = false;
2677
2678   switch (in)
2679     {
2680     case ORDERED:
2681     case UNORDERED:
2682     case LT:
2683     case GE:
2684     case EQ:
2685     case NE:
2686       break;
2687
2688     case GT:
2689     case LE:
2690       cmp1 = swap_condition (cmp1);
2691       swap = true;
2692       break;
2693
2694     case UNEQ:
2695       cmp1 = UNORDERED;
2696       cmp2 = EQ;
2697       break;
2698     case UNLT:
2699       cmp1 = UNORDERED;
2700       cmp2 = LT;
2701       break;
2702     case UNGE:
2703       cmp1 = UNORDERED;
2704       cmp2 = GE;
2705       break;
2706     case UNLE:
2707       cmp1 = UNORDERED;
2708       cmp2 = GT;
2709       swap = true;
2710       break;
2711     case UNGT:
2712       cmp1 = UNORDERED;
2713       cmp2 = LE;
2714       swap = true;
2715       break;
2716     case LTGT:
2717       cmp1 = ORDERED;
2718       cmp2 = NE;
2719       break;
2720
2721     default:
2722       gcc_unreachable ();
2723     }
2724
2725   *o1 = cmp1;
2726   *o2 = cmp2;
2727   return swap;
2728 }
2729
2730 /* Split the conditional branch.  Emit (COMPARE C1 C2) into CC_REG with
2731    CC_MODE, and use that in branches based on that compare.  */
2732
2733 void
2734 rx_split_cbranch (enum machine_mode cc_mode, enum rtx_code cmp1,
2735                   rtx c1, rtx c2, rtx label)
2736 {
2737   rtx flags, x;
2738
2739   flags = gen_rtx_REG (cc_mode, CC_REG);
2740   x = gen_rtx_COMPARE (cc_mode, c1, c2);
2741   x = gen_rtx_SET (VOIDmode, flags, x);
2742   emit_insn (x);
2743
2744   x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
2745   x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
2746   x = gen_rtx_SET (VOIDmode, pc_rtx, x);
2747   emit_jump_insn (x);
2748 }
2749
2750 /* A helper function for matching parallels that set the flags.  */
2751
2752 bool
2753 rx_match_ccmode (rtx insn, enum machine_mode cc_mode)
2754 {
2755   rtx op1, flags;
2756   enum machine_mode flags_mode;
2757
2758   gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2);
2759
2760   op1 = XVECEXP (PATTERN (insn), 0, 1);
2761   gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE);
2762
2763   flags = SET_DEST (op1);
2764   flags_mode = GET_MODE (flags);
2765
2766   if (GET_MODE (SET_SRC (op1)) != flags_mode)
2767     return false;
2768   if (GET_MODE_CLASS (flags_mode) != MODE_CC)
2769     return false;
2770
2771   /* Ensure that the mode of FLAGS is compatible with CC_MODE.  */
2772   if (flags_from_mode (flags_mode) & ~flags_from_mode (cc_mode))
2773     return false;
2774
2775   return true;
2776 }
2777
2778 \f
2779 #undef  TARGET_FUNCTION_VALUE
2780 #define TARGET_FUNCTION_VALUE           rx_function_value
2781
2782 #undef  TARGET_RETURN_IN_MSB
2783 #define TARGET_RETURN_IN_MSB            rx_return_in_msb
2784
2785 #undef  TARGET_IN_SMALL_DATA_P
2786 #define TARGET_IN_SMALL_DATA_P          rx_in_small_data
2787
2788 #undef  TARGET_RETURN_IN_MEMORY
2789 #define TARGET_RETURN_IN_MEMORY         rx_return_in_memory
2790
2791 #undef  TARGET_HAVE_SRODATA_SECTION
2792 #define TARGET_HAVE_SRODATA_SECTION     true
2793
2794 #undef  TARGET_ASM_SELECT_RTX_SECTION
2795 #define TARGET_ASM_SELECT_RTX_SECTION   rx_select_rtx_section
2796
2797 #undef  TARGET_ASM_SELECT_SECTION
2798 #define TARGET_ASM_SELECT_SECTION       rx_select_section
2799
2800 #undef  TARGET_INIT_BUILTINS
2801 #define TARGET_INIT_BUILTINS            rx_init_builtins
2802
2803 #undef  TARGET_EXPAND_BUILTIN
2804 #define TARGET_EXPAND_BUILTIN           rx_expand_builtin
2805
2806 #undef  TARGET_ASM_CONSTRUCTOR
2807 #define TARGET_ASM_CONSTRUCTOR          rx_elf_asm_constructor
2808
2809 #undef  TARGET_ASM_DESTRUCTOR
2810 #define TARGET_ASM_DESTRUCTOR           rx_elf_asm_destructor
2811
2812 #undef  TARGET_STRUCT_VALUE_RTX
2813 #define TARGET_STRUCT_VALUE_RTX         rx_struct_value_rtx
2814
2815 #undef  TARGET_ATTRIBUTE_TABLE
2816 #define TARGET_ATTRIBUTE_TABLE          rx_attribute_table
2817
2818 #undef  TARGET_ASM_FILE_START
2819 #define TARGET_ASM_FILE_START                   rx_file_start
2820
2821 #undef  TARGET_MS_BITFIELD_LAYOUT_P
2822 #define TARGET_MS_BITFIELD_LAYOUT_P             rx_is_ms_bitfield_layout
2823
2824 #undef  TARGET_LEGITIMATE_ADDRESS_P
2825 #define TARGET_LEGITIMATE_ADDRESS_P             rx_is_legitimate_address
2826
2827 #undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
2828 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS    rx_allocate_stack_slots_for_args
2829
2830 #undef  TARGET_ASM_FUNCTION_PROLOGUE
2831 #define TARGET_ASM_FUNCTION_PROLOGUE            rx_output_function_prologue
2832
2833 #undef  TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
2834 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P   rx_func_attr_inlinable
2835
2836 #undef  TARGET_FUNCTION_OK_FOR_SIBCALL
2837 #define TARGET_FUNCTION_OK_FOR_SIBCALL          rx_function_ok_for_sibcall
2838
2839 #undef  TARGET_FUNCTION_ARG
2840 #define TARGET_FUNCTION_ARG                     rx_function_arg
2841
2842 #undef  TARGET_FUNCTION_ARG_ADVANCE
2843 #define TARGET_FUNCTION_ARG_ADVANCE             rx_function_arg_advance
2844
2845 #undef  TARGET_FUNCTION_ARG_BOUNDARY
2846 #define TARGET_FUNCTION_ARG_BOUNDARY            rx_function_arg_boundary
2847
2848 #undef  TARGET_SET_CURRENT_FUNCTION
2849 #define TARGET_SET_CURRENT_FUNCTION             rx_set_current_function
2850
2851 #undef  TARGET_HANDLE_OPTION
2852 #define TARGET_HANDLE_OPTION                    rx_handle_option
2853
2854 #undef  TARGET_ASM_INTEGER
2855 #define TARGET_ASM_INTEGER                      rx_assemble_integer
2856
2857 #undef  TARGET_USE_BLOCKS_FOR_CONSTANT_P
2858 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P        hook_bool_mode_const_rtx_true
2859
2860 #undef  TARGET_MAX_ANCHOR_OFFSET
2861 #define TARGET_MAX_ANCHOR_OFFSET                32
2862
2863 #undef  TARGET_ADDRESS_COST
2864 #define TARGET_ADDRESS_COST                     rx_address_cost
2865
2866 #undef  TARGET_CAN_ELIMINATE
2867 #define TARGET_CAN_ELIMINATE                    rx_can_eliminate
2868
2869 #undef  TARGET_CONDITIONAL_REGISTER_USAGE
2870 #define TARGET_CONDITIONAL_REGISTER_USAGE       rx_conditional_register_usage
2871
2872 #undef  TARGET_ASM_TRAMPOLINE_TEMPLATE
2873 #define TARGET_ASM_TRAMPOLINE_TEMPLATE          rx_trampoline_template
2874
2875 #undef  TARGET_TRAMPOLINE_INIT
2876 #define TARGET_TRAMPOLINE_INIT                  rx_trampoline_init
2877
2878 #undef  TARGET_PRINT_OPERAND
2879 #define TARGET_PRINT_OPERAND                    rx_print_operand
2880
2881 #undef  TARGET_PRINT_OPERAND_ADDRESS
2882 #define TARGET_PRINT_OPERAND_ADDRESS            rx_print_operand_address
2883
2884 #undef  TARGET_CC_MODES_COMPATIBLE
2885 #define TARGET_CC_MODES_COMPATIBLE              rx_cc_modes_compatible
2886
2887 #undef  TARGET_MEMORY_MOVE_COST
2888 #define TARGET_MEMORY_MOVE_COST                 rx_memory_move_cost
2889
2890 #undef  TARGET_OPTION_OVERRIDE
2891 #define TARGET_OPTION_OVERRIDE                  rx_option_override
2892
2893 #undef  TARGET_OPTION_OPTIMIZATION_TABLE
2894 #define TARGET_OPTION_OPTIMIZATION_TABLE        rx_option_optimization_table
2895
2896 #undef  TARGET_PROMOTE_FUNCTION_MODE
2897 #define TARGET_PROMOTE_FUNCTION_MODE            rx_promote_function_mode
2898
2899 #undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
2900 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE    rx_override_options_after_change
2901
2902 #undef  TARGET_EXCEPT_UNWIND_INFO
2903 #define TARGET_EXCEPT_UNWIND_INFO               sjlj_except_unwind_info
2904
2905 struct gcc_target targetm = TARGET_INITIALIZER;
2906
2907 /* #include "gt-rx.h" */