1/* Subroutines used for code generation on Renesas RX processors.
2   Copyright (C) 2008-2020 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#define IN_TARGET_CODE 1
26
27#include "config.h"
28#include "system.h"
29#include "coretypes.h"
30#include "backend.h"
31#include "target.h"
32#include "rtl.h"
33#include "tree.h"
34#include "stringpool.h"
35#include "attribs.h"
36#include "cfghooks.h"
37#include "df.h"
38#include "memmodel.h"
39#include "tm_p.h"
40#include "regs.h"
41#include "emit-rtl.h"
42#include "diagnostic-core.h"
43#include "varasm.h"
44#include "stor-layout.h"
45#include "calls.h"
46#include "output.h"
47#include "flags.h"
48#include "explow.h"
49#include "expr.h"
50#include "toplev.h"
51#include "langhooks.h"
52#include "opts.h"
53#include "builtins.h"
54
55/* This file should be included last.  */
56#include "target-def.h"
57
58static unsigned int rx_gp_base_regnum_val = INVALID_REGNUM;
59static unsigned int rx_pid_base_regnum_val = INVALID_REGNUM;
60static unsigned int rx_num_interrupt_regs;
61
62static unsigned int
63rx_gp_base_regnum (void)
64{
65  if (rx_gp_base_regnum_val == INVALID_REGNUM)
66    gcc_unreachable ();
67  return rx_gp_base_regnum_val;
68}
69
70static unsigned int
71rx_pid_base_regnum (void)
72{
73  if (rx_pid_base_regnum_val == INVALID_REGNUM)
74    gcc_unreachable ();
75  return rx_pid_base_regnum_val;
76}
77
78/* Find a SYMBOL_REF in a "standard" MEM address and return its decl.  */
79
80static tree
81rx_decl_for_addr (rtx op)
82{
83  if (GET_CODE (op) == MEM)
84    op = XEXP (op, 0);
85  if (GET_CODE (op) == CONST)
86    op = XEXP (op, 0);
87  while (GET_CODE (op) == PLUS)
88    op = XEXP (op, 0);
89  if (GET_CODE (op) == SYMBOL_REF)
90    return SYMBOL_REF_DECL (op);
91  return NULL_TREE;
92}
93
94static void rx_print_operand (FILE *, rtx, int);
95
96#define CC_FLAG_S	(1 << 0)
97#define CC_FLAG_Z	(1 << 1)
98#define CC_FLAG_O	(1 << 2)
99#define CC_FLAG_C	(1 << 3)
100#define CC_FLAG_FP	(1 << 4)	/* Fake, to differentiate CC_Fmode.  */
101
102static unsigned int flags_from_mode (machine_mode mode);
103static unsigned int flags_from_code (enum rtx_code code);
104
105/* Return true if OP is a reference to an object in a PID data area.  */
106
107enum pid_type
108{
109  PID_NOT_PID = 0,	/* The object is not in the PID data area.  */
110  PID_ENCODED,		/* The object is in the PID data area.  */
111  PID_UNENCODED		/* The object will be placed in the PID data area, but it has not been placed there yet.  */
112};
113
114static enum pid_type
115rx_pid_data_operand (rtx op)
116{
117  tree op_decl;
118
119  if (!TARGET_PID)
120    return PID_NOT_PID;
121
122  if (GET_CODE (op) == PLUS
123      && GET_CODE (XEXP (op, 0)) == REG
124      && GET_CODE (XEXP (op, 1)) == CONST
125      && GET_CODE (XEXP (XEXP (op, 1), 0)) == UNSPEC)
126    return PID_ENCODED;
127
128  op_decl = rx_decl_for_addr (op);
129
130  if (op_decl)
131    {
132      if (TREE_READONLY (op_decl))
133	return PID_UNENCODED;
134    }
135  else
136    {
137      /* Sigh, some special cases.  */
138      if (GET_CODE (op) == SYMBOL_REF
139	  || GET_CODE (op) == LABEL_REF)
140	return PID_UNENCODED;
141    }
142
143  return PID_NOT_PID;
144}
145
146static rtx
147rx_legitimize_address (rtx x,
148		       rtx oldx ATTRIBUTE_UNUSED,
149		       machine_mode mode ATTRIBUTE_UNUSED)
150{
151  if (rx_pid_data_operand (x) == PID_UNENCODED)
152    {
153      rtx rv = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), x);
154      return rv;
155    }
156
157  if (GET_CODE (x) == PLUS
158      && GET_CODE (XEXP (x, 0)) == PLUS
159      && REG_P (XEXP (XEXP (x, 0), 0))
160      && REG_P (XEXP (x, 1)))
161    return force_reg (SImode, x);
162
163  return x;
164}
165
166/* Return true if OP is a reference to an object in a small data area.  */
167
168static bool
169rx_small_data_operand (rtx op)
170{
171  if (rx_small_data_limit == 0)
172    return false;
173
174  if (GET_CODE (op) == SYMBOL_REF)
175    return SYMBOL_REF_SMALL_P (op);
176
177  return false;
178}
179
180static bool
181rx_is_legitimate_address (machine_mode mode, rtx x,
182			  bool strict ATTRIBUTE_UNUSED)
183{
184  if (RTX_OK_FOR_BASE (x, strict))
185    /* Register Indirect.  */
186    return true;
187
188  if ((GET_MODE_SIZE (mode) == 4
189       || GET_MODE_SIZE (mode) == 2
190       || GET_MODE_SIZE (mode) == 1)
191      && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
192    /* Pre-decrement Register Indirect or
193       Post-increment Register Indirect.  */
194    return RTX_OK_FOR_BASE (XEXP (x, 0), strict);
195
196  switch (rx_pid_data_operand (x))
197    {
198    case PID_UNENCODED:
199      return false;
200    case PID_ENCODED:
201      return true;
202    default:
203      break;
204    }
205
206  if (GET_CODE (x) == PLUS)
207    {
208      rtx arg1 = XEXP (x, 0);
209      rtx arg2 = XEXP (x, 1);
210      rtx index = NULL_RTX;
211
212      if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict))
213	index = arg2;
214      else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict))
215	index = arg1;
216      else
217	return false;
218
219      switch (GET_CODE (index))
220	{
221	case CONST_INT:
222	  {
223	    /* Register Relative: REG + INT.
224	       Only positive, mode-aligned, mode-sized
225	       displacements are allowed.  */
226	    HOST_WIDE_INT val = INTVAL (index);
227	    int factor;
228
229	    if (val < 0)
230	      return false;
231
232	    switch (GET_MODE_SIZE (mode))
233	      {
234	      default:
235	      case 4: factor = 4; break;
236	      case 2: factor = 2; break;
237	      case 1: factor = 1; break;
238	      }
239
240	    if (val > (65535 * factor))
241	      return false;
242	    return (val % factor) == 0;
243	  }
244
245	case REG:
246	  /* Unscaled Indexed Register Indirect: REG + REG
247	     Size has to be "QI", REG has to be valid.  */
248	  return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict);
249
250	case MULT:
251	  {
252	    /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
253	       Factor has to equal the mode size, REG has to be valid.  */
254	    rtx factor;
255
256	    factor = XEXP (index, 1);
257	    index = XEXP (index, 0);
258
259	    return REG_P (index)
260	      && RTX_OK_FOR_BASE (index, strict)
261	      && CONST_INT_P (factor)
262	      && GET_MODE_SIZE (mode) == INTVAL (factor);
263	  }
264
265	default:
266	  return false;
267	}
268    }
269
270  /* Small data area accesses turn into register relative offsets.  */
271  return rx_small_data_operand (x);
272}
273
274/* Returns TRUE for simple memory addresses, ie ones
275   that do not involve register indirect addressing
276   or pre/post increment/decrement.  */
277
278bool
279rx_is_restricted_memory_address (rtx mem, machine_mode mode)
280{
281  if (! rx_is_legitimate_address
282      (mode, mem, reload_in_progress || reload_completed))
283    return false;
284
285  switch (GET_CODE (mem))
286    {
287    case REG:
288      /* Simple memory addresses are OK.  */
289      return true;
290
291    case SUBREG:
292      return RX_REG_P (SUBREG_REG (mem));
293
294    case PRE_DEC:
295    case POST_INC:
296      return false;
297
298    case PLUS:
299      {
300	rtx base, index;
301
302	/* Only allow REG+INT addressing.  */
303	base = XEXP (mem, 0);
304	index = XEXP (mem, 1);
305
306	if (! RX_REG_P (base) || ! CONST_INT_P (index))
307	  return false;
308
309	return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1);
310      }
311
312    case SYMBOL_REF:
313      /* Can happen when small data is being supported.
314         Assume that it will be resolved into GP+INT.  */
315      return true;
316
317    default:
318      gcc_unreachable ();
319    }
320}
321
322/* Implement TARGET_MODE_DEPENDENT_ADDRESS_P.  */
323
324static bool
325rx_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED)
326{
327  if (GET_CODE (addr) == CONST)
328    addr = XEXP (addr, 0);
329
330  switch (GET_CODE (addr))
331    {
332      /* --REG and REG++ only work in SImode.  */
333    case PRE_DEC:
334    case POST_INC:
335      return true;
336
337    case MINUS:
338    case PLUS:
339      if (! REG_P (XEXP (addr, 0)))
340	return true;
341
342      addr = XEXP (addr, 1);
343
344      switch (GET_CODE (addr))
345	{
346	case REG:
347	  /* REG+REG only works in SImode.  */
348	  return true;
349
350	case CONST_INT:
351	  /* REG+INT is only mode independent if INT is a
352	     multiple of 4, positive and will fit into 16-bits.  */
353	  if (((INTVAL (addr) & 3) == 0)
354	      && IN_RANGE (INTVAL (addr), 4, 0xfffc))
355	    return false;
356	  return true;
357
358	case SYMBOL_REF:
359	case LABEL_REF:
360	  return true;
361
362	case MULT:
363	  /* REG+REG*SCALE is always mode dependent.  */
364	  return true;
365
366	default:
367	  /* Not recognized, so treat as mode dependent.  */
368	  return true;
369	}
370
371    case CONST_INT:
372    case SYMBOL_REF:
373    case LABEL_REF:
374    case REG:
375      /* These are all mode independent.  */
376      return false;
377
378    default:
379      /* Everything else is unrecognized,
380	 so treat as mode dependent.  */
381      return true;
382    }
383}
384
385/* A C compound statement to output to stdio stream FILE the
386   assembler syntax for an instruction operand that is a memory
387   reference whose address is ADDR.  */
388
389static void
390rx_print_operand_address (FILE * file, machine_mode /*mode*/, rtx addr)
391{
392  switch (GET_CODE (addr))
393    {
394    case REG:
395      fprintf (file, "[");
396      rx_print_operand (file, addr, 0);
397      fprintf (file, "]");
398      break;
399
400    case PRE_DEC:
401      fprintf (file, "[-");
402      rx_print_operand (file, XEXP (addr, 0), 0);
403      fprintf (file, "]");
404      break;
405
406    case POST_INC:
407      fprintf (file, "[");
408      rx_print_operand (file, XEXP (addr, 0), 0);
409      fprintf (file, "+]");
410      break;
411
412    case PLUS:
413      {
414	rtx arg1 = XEXP (addr, 0);
415	rtx arg2 = XEXP (addr, 1);
416	rtx base, index;
417
418	if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true))
419	  base = arg1, index = arg2;
420	else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true))
421	  base = arg2, index = arg1;
422	else
423	  {
424	    rx_print_operand (file, arg1, 0);
425	    fprintf (file, " + ");
426	    rx_print_operand (file, arg2, 0);
427	    break;
428	  }
429
430	if (REG_P (index) || GET_CODE (index) == MULT)
431	  {
432	    fprintf (file, "[");
433	    rx_print_operand (file, index, 'A');
434	    fprintf (file, ",");
435	  }
436	else /* GET_CODE (index) == CONST_INT  */
437	  {
438	    rx_print_operand (file, index, 'A');
439	    fprintf (file, "[");
440	  }
441	rx_print_operand (file, base, 0);
442	fprintf (file, "]");
443	break;
444      }
445
446    case CONST:
447      if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
448	{
449	  addr = XEXP (addr, 0);
450	  gcc_assert (XINT (addr, 1) == UNSPEC_CONST);
451
452          addr = XVECEXP (addr, 0, 0);
453	  gcc_assert (CONST_INT_P (addr));
454	  fprintf (file, "#");
455	  output_addr_const (file, addr);
456	  break;
457	}
458      fprintf (file, "#");
459      output_addr_const (file, XEXP (addr, 0));
460      break;
461
462    case UNSPEC:
463      addr = XVECEXP (addr, 0, 0);
464      /* Fall through.  */
465    case LABEL_REF:
466    case SYMBOL_REF:
467      fprintf (file, "#");
468      /* Fall through.  */
469    default:
470      output_addr_const (file, addr);
471      break;
472    }
473}
474
475static void
476rx_print_integer (FILE * file, HOST_WIDE_INT val)
477{
478  if (val < 64)
479    fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
480  else
481    fprintf (file,
482	     TARGET_AS100_SYNTAX
483	     ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX,
484	     val);
485}
486
487static bool
488rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
489{
490  const char *  op = integer_asm_op (size, is_aligned);
491
492  if (! CONST_INT_P (x))
493    return default_assemble_integer (x, size, is_aligned);
494
495  if (op == NULL)
496    return false;
497  fputs (op, asm_out_file);
498
499  rx_print_integer (asm_out_file, INTVAL (x));
500  fputc ('\n', asm_out_file);
501  return true;
502}
503
504
505/* Handles the insertion of a single operand into the assembler output.
506   The %<letter> directives supported are:
507
508     %A  Print an operand without a leading # character.
509     %B  Print an integer comparison name.
510     %C  Print a control register name.
511     %F  Print a condition code flag name.
512     %G  Register used for small-data-area addressing
513     %H  Print high part of a DImode register, integer or address.
514     %L  Print low part of a DImode register, integer or address.
515     %N  Print the negation of the immediate value.
516     %P  Register used for PID addressing
517     %Q  If the operand is a MEM, then correctly generate
518         register indirect or register relative addressing.
519     %R  Like %Q but for zero-extending loads.  */
520
521static void
522rx_print_operand (FILE * file, rtx op, int letter)
523{
524  bool unsigned_load = false;
525  bool print_hash = true;
526
527  if (letter == 'A'
528      && ((GET_CODE (op) == CONST
529	   && GET_CODE (XEXP (op, 0)) == UNSPEC)
530	  || GET_CODE (op) == UNSPEC))
531    {
532      print_hash = false;
533      letter = 0;
534    }
535
536  switch (letter)
537    {
538    case 'A':
539      /* Print an operand without a leading #.  */
540      if (MEM_P (op))
541	op = XEXP (op, 0);
542
543      switch (GET_CODE (op))
544	{
545	case LABEL_REF:
546	case SYMBOL_REF:
547	  output_addr_const (file, op);
548	  break;
549	case CONST_INT:
550	  fprintf (file, "%ld", (long) INTVAL (op));
551	  break;
552	default:
553	  rx_print_operand (file, op, 0);
554	  break;
555	}
556      break;
557
558    case 'B':
559      {
560	enum rtx_code code = GET_CODE (op);
561	machine_mode mode = GET_MODE (XEXP (op, 0));
562	const char *ret;
563
564	if (mode == CC_Fmode)
565	  {
566	    /* C flag is undefined, and O flag carries unordered.  None of the
567	       branch combinations that include O use it helpfully.  */
568	    switch (code)
569	      {
570	      case ORDERED:
571		ret = "no";
572		break;
573	      case UNORDERED:
574		ret = "o";
575		break;
576	      case LT:
577		ret = "n";
578		break;
579	      case GE:
580		ret = "pz";
581		break;
582	      case EQ:
583		ret = "eq";
584		break;
585	      case NE:
586		ret = "ne";
587		break;
588	      default:
589		gcc_unreachable ();
590	      }
591	  }
592	else
593	  {
594	    unsigned int flags = flags_from_mode (mode);
595
596	    switch (code)
597	      {
598	      case LT:
599		ret = (flags & CC_FLAG_O ? "lt" : "n");
600		break;
601	      case GE:
602		ret = (flags & CC_FLAG_O ? "ge" : "pz");
603		break;
604	      case GT:
605		ret = "gt";
606		break;
607	      case LE:
608		ret = "le";
609		break;
610	      case GEU:
611		ret = "geu";
612		break;
613	      case LTU:
614		ret = "ltu";
615		break;
616	      case GTU:
617		ret = "gtu";
618		break;
619	      case LEU:
620		ret = "leu";
621		break;
622	      case EQ:
623		ret = "eq";
624		break;
625	      case NE:
626		ret = "ne";
627		break;
628	      default:
629		gcc_unreachable ();
630	      }
631	    gcc_checking_assert ((flags_from_code (code) & ~flags) == 0);
632	  }
633	fputs (ret, file);
634	break;
635      }
636
637    case 'C':
638      gcc_assert (CONST_INT_P (op));
639      switch (INTVAL (op))
640	{
641	case CTRLREG_PSW:   fprintf (file, "psw"); break;
642	case CTRLREG_USP:   fprintf (file, "usp"); break;
643	case CTRLREG_FPSW:  fprintf (file, "fpsw"); break;
644	case CTRLREG_BPSW:  fprintf (file, "bpsw"); break;
645	case CTRLREG_BPC:   fprintf (file, "bpc"); break;
646	case CTRLREG_ISP:   fprintf (file, "isp"); break;
647	case CTRLREG_FINTV: fprintf (file, "fintv"); break;
648	case CTRLREG_INTB:  fprintf (file, "intb"); break;
649	default:
650	  warning (0, "unrecognized control register number: %d"
651		   " - using %<psw%>", (int) INTVAL (op));
652	  fprintf (file, "psw");
653	  break;
654	}
655      break;
656
657    case 'F':
658      gcc_assert (CONST_INT_P (op));
659      switch (INTVAL (op))
660	{
661	case 0: case 'c': case 'C': fprintf (file, "C"); break;
662	case 1:	case 'z': case 'Z': fprintf (file, "Z"); break;
663	case 2: case 's': case 'S': fprintf (file, "S"); break;
664	case 3: case 'o': case 'O': fprintf (file, "O"); break;
665	case 8: case 'i': case 'I': fprintf (file, "I"); break;
666	case 9: case 'u': case 'U': fprintf (file, "U"); break;
667	default:
668	  gcc_unreachable ();
669	}
670      break;
671
672    case 'G':
673      fprintf (file, "%s", reg_names [rx_gp_base_regnum ()]);
674      break;
675
676    case 'H':
677      switch (GET_CODE (op))
678	{
679	case REG:
680	  fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
681	  break;
682	case CONST_INT:
683	  {
684	    HOST_WIDE_INT v = INTVAL (op);
685
686	    fprintf (file, "#");
687	    /* Trickery to avoid problems with shifting 32 bits at a time.  */
688	    v = v >> 16;
689	    v = v >> 16;
690	    rx_print_integer (file, v);
691	    break;
692	  }
693	case CONST_DOUBLE:
694	  fprintf (file, "#");
695	  rx_print_integer (file, CONST_DOUBLE_HIGH (op));
696	  break;
697	case MEM:
698	  if (! WORDS_BIG_ENDIAN)
699	    op = adjust_address (op, SImode, 4);
700	  output_address (GET_MODE (op), XEXP (op, 0));
701	  break;
702	default:
703	  gcc_unreachable ();
704	}
705      break;
706
707    case 'L':
708      switch (GET_CODE (op))
709	{
710	case REG:
711	  fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
712	  break;
713	case CONST_INT:
714	  fprintf (file, "#");
715	  rx_print_integer (file, INTVAL (op) & 0xffffffff);
716	  break;
717	case CONST_DOUBLE:
718	  fprintf (file, "#");
719	  rx_print_integer (file, CONST_DOUBLE_LOW (op));
720	  break;
721	case MEM:
722	  if (WORDS_BIG_ENDIAN)
723	    op = adjust_address (op, SImode, 4);
724	  output_address (GET_MODE (op), XEXP (op, 0));
725	  break;
726	default:
727	  gcc_unreachable ();
728	}
729      break;
730
731    case 'N':
732      gcc_assert (CONST_INT_P (op));
733      fprintf (file, "#");
734      rx_print_integer (file, - INTVAL (op));
735      break;
736
737    case 'P':
738      fprintf (file, "%s", reg_names [rx_pid_base_regnum ()]);
739      break;
740
741    case 'R':
742      gcc_assert (GET_MODE_SIZE (GET_MODE (op)) <= 4);
743      unsigned_load = true;
744      /* Fall through.  */
745    case 'Q':
746      if (MEM_P (op))
747	{
748	  HOST_WIDE_INT offset;
749	  rtx mem = op;
750
751	  op = XEXP (op, 0);
752
753	  if (REG_P (op))
754	    offset = 0;
755	  else if (GET_CODE (op) == PLUS)
756	    {
757	      rtx displacement;
758
759	      if (REG_P (XEXP (op, 0)))
760		{
761		  displacement = XEXP (op, 1);
762		  op = XEXP (op, 0);
763		}
764	      else
765		{
766		  displacement = XEXP (op, 0);
767		  op = XEXP (op, 1);
768		  gcc_assert (REG_P (op));
769		}
770
771	      gcc_assert (CONST_INT_P (displacement));
772	      offset = INTVAL (displacement);
773	      gcc_assert (offset >= 0);
774
775	      fprintf (file, "%ld", offset);
776	    }
777	  else
778	    gcc_unreachable ();
779
780	  fprintf (file, "[");
781	  rx_print_operand (file, op, 0);
782	  fprintf (file, "].");
783
784	  switch (GET_MODE_SIZE (GET_MODE (mem)))
785	    {
786	    case 1:
787	      gcc_assert (offset <= 65535 * 1);
788	      fprintf (file, unsigned_load ? "UB" : "B");
789	      break;
790	    case 2:
791	      gcc_assert (offset % 2 == 0);
792	      gcc_assert (offset <= 65535 * 2);
793	      fprintf (file, unsigned_load ? "UW" : "W");
794	      break;
795	    case 4:
796	      gcc_assert (offset % 4 == 0);
797	      gcc_assert (offset <= 65535 * 4);
798	      fprintf (file, "L");
799	      break;
800	    default:
801	      gcc_unreachable ();
802	    }
803	  break;
804	}
805
806      /* Fall through.  */
807
808    default:
809      if (GET_CODE (op) == CONST
810	  && GET_CODE (XEXP (op, 0)) == UNSPEC)
811	op = XEXP (op, 0);
812      else if (GET_CODE (op) == CONST
813	       && GET_CODE (XEXP (op, 0)) == PLUS
814	       && GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC
815	       && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
816	{
817	  if (print_hash)
818	    fprintf (file, "#");
819	  fprintf (file, "(");
820	  rx_print_operand (file, XEXP (XEXP (op, 0), 0), 'A');
821	  fprintf (file, " + ");
822	  output_addr_const (file, XEXP (XEXP (op, 0), 1));
823	  fprintf (file, ")");
824	  return;
825	}
826
827      switch (GET_CODE (op))
828	{
829	case MULT:
830	  /* Should be the scaled part of an
831	     indexed register indirect address.  */
832	  {
833	    rtx base = XEXP (op, 0);
834	    rtx index = XEXP (op, 1);
835
836	    /* Check for a swaped index register and scaling factor.
837	       Not sure if this can happen, but be prepared to handle it.  */
838	    if (CONST_INT_P (base) && REG_P (index))
839	      {
840		rtx tmp = base;
841		base = index;
842		index = tmp;
843	      }
844
845	    gcc_assert (REG_P (base));
846	    gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
847	    gcc_assert (CONST_INT_P (index));
848	    /* Do not try to verify the value of the scalar as it is based
849	       on the mode of the MEM not the mode of the MULT.  (Which
850	       will always be SImode).  */
851	    fprintf (file, "%s", reg_names [REGNO (base)]);
852	    break;
853	  }
854
855	case MEM:
856	  output_address (GET_MODE (op), XEXP (op, 0));
857	  break;
858
859	case PLUS:
860	  output_address (VOIDmode, op);
861	  break;
862
863	case REG:
864	  gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
865	  fprintf (file, "%s", reg_names [REGNO (op)]);
866	  break;
867
868	case SUBREG:
869	  gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER);
870	  fprintf (file, "%s", reg_names [subreg_regno (op)]);
871	  break;
872
873	  /* This will only be single precision....  */
874	case CONST_DOUBLE:
875	  {
876	    unsigned long val;
877
878	    REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op), val);
879	    if (print_hash)
880	      fprintf (file, "#");
881	    fprintf (file, TARGET_AS100_SYNTAX ? "0%lxH" : "0x%lx", val);
882	    break;
883	  }
884
885	case CONST_INT:
886	  if (print_hash)
887	    fprintf (file, "#");
888	  rx_print_integer (file, INTVAL (op));
889	  break;
890
891	case UNSPEC:
892	  switch (XINT (op, 1))
893	    {
894	    case UNSPEC_PID_ADDR:
895	      {
896		rtx sym, add;
897
898		if (print_hash)
899		  fprintf (file, "#");
900		sym = XVECEXP (op, 0, 0);
901		add = NULL_RTX;
902		fprintf (file, "(");
903		if (GET_CODE (sym) == PLUS)
904		  {
905		    add = XEXP (sym, 1);
906		    sym = XEXP (sym, 0);
907		  }
908		output_addr_const (file, sym);
909		if (add != NULL_RTX)
910		  {
911		    fprintf (file, "+");
912		    output_addr_const (file, add);
913		  }
914		fprintf (file, "-__pid_base");
915		fprintf (file, ")");
916		return;
917	      }
918	    }
919	  /* Fall through */
920
921	case CONST:
922	case SYMBOL_REF:
923	case LABEL_REF:
924	case CODE_LABEL:
925	  rx_print_operand_address (file, VOIDmode, op);
926	  break;
927
928	default:
929	  gcc_unreachable ();
930	}
931      break;
932    }
933}
934
935/* Maybe convert an operand into its PID format.  */
936
937rtx
938rx_maybe_pidify_operand (rtx op, int copy_to_reg)
939{
940  if (rx_pid_data_operand (op) == PID_UNENCODED)
941    {
942      if (GET_CODE (op) == MEM)
943	{
944	  rtx a = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), XEXP (op, 0));
945	  op = replace_equiv_address (op, a);
946	}
947      else
948	{
949	  op = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), op);
950	}
951
952      if (copy_to_reg)
953	op = copy_to_mode_reg (GET_MODE (op), op);
954    }
955  return op;
956}
957
958/* Returns an assembler template for a move instruction.  */
959
960char *
961rx_gen_move_template (rtx * operands, bool is_movu)
962{
963  static char  out_template [64];
964  const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
965  const char * src_template;
966  const char * dst_template;
967  rtx          dest = operands[0];
968  rtx          src  = operands[1];
969
970  /* Decide which extension, if any, should be given to the move instruction.  */
971  switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
972    {
973    case E_QImode:
974      /* The .B extension is not valid when
975	 loading an immediate into a register.  */
976      if (! REG_P (dest) || ! CONST_INT_P (src))
977	extension = ".B";
978      break;
979    case E_HImode:
980      if (! REG_P (dest) || ! CONST_INT_P (src))
981	/* The .W extension is not valid when
982	   loading an immediate into a register.  */
983	extension = ".W";
984      break;
985    case E_DFmode:
986    case E_DImode:
987    case E_SFmode:
988    case E_SImode:
989      extension = ".L";
990      break;
991    case E_VOIDmode:
992      /* This mode is used by constants.  */
993      break;
994    default:
995      debug_rtx (src);
996      gcc_unreachable ();
997    }
998
999  if (MEM_P (src) && rx_pid_data_operand (XEXP (src, 0)) == PID_UNENCODED)
1000    {
1001      gcc_assert (GET_MODE (src) != DImode);
1002      gcc_assert (GET_MODE (src) != DFmode);
1003
1004      src_template = "(%A1 - __pid_base)[%P1]";
1005    }
1006  else if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
1007    {
1008      gcc_assert (GET_MODE (src) != DImode);
1009      gcc_assert (GET_MODE (src) != DFmode);
1010
1011      src_template = "%%gp(%A1)[%G1]";
1012    }
1013  else
1014    src_template = "%1";
1015
1016  if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
1017    {
1018      gcc_assert (GET_MODE (dest) != DImode);
1019      gcc_assert (GET_MODE (dest) != DFmode);
1020
1021      dst_template = "%%gp(%A0)[%G0]";
1022    }
1023  else
1024    dst_template = "%0";
1025
1026  if (GET_MODE (dest) == DImode || GET_MODE (dest) == DFmode)
1027    {
1028      gcc_assert (! is_movu);
1029
1030      if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1))
1031	sprintf (out_template, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0");
1032      else
1033	sprintf (out_template, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0");
1034    }
1035  else
1036    sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
1037	     extension, src_template, dst_template);
1038  return out_template;
1039}
1040
1041/* Return VALUE rounded up to the next ALIGNMENT boundary.  */
1042
1043static inline unsigned int
1044rx_round_up (unsigned int value, unsigned int alignment)
1045{
1046  alignment -= 1;
1047  return (value + alignment) & (~ alignment);
1048}
1049
1050/* Return the number of bytes in the argument registers
1051   occupied by an argument of type TYPE and mode MODE.  */
1052
1053static unsigned int
1054rx_function_arg_size (machine_mode mode, const_tree type)
1055{
1056  unsigned int num_bytes;
1057
1058  num_bytes = (mode == BLKmode)
1059    ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1060  return rx_round_up (num_bytes, UNITS_PER_WORD);
1061}
1062
1063#define NUM_ARG_REGS		4
1064#define MAX_NUM_ARG_BYTES	(NUM_ARG_REGS * UNITS_PER_WORD)
1065
1066/* Return an RTL expression describing the register holding function
1067   argument ARG or NULL_RTX if the parameter should be passed on the
1068   stack.  CUM describes the previous parameters to the function.  */
1069
1070static rtx
1071rx_function_arg (cumulative_args_t cum, const function_arg_info &arg)
1072{
1073  unsigned int next_reg;
1074  unsigned int bytes_so_far = *get_cumulative_args (cum);
1075  unsigned int size;
1076  unsigned int rounded_size;
1077
1078  size = arg.promoted_size_in_bytes ();
1079  /* If the size is not known it cannot be passed in registers.  */
1080  if (size < 1)
1081    return NULL_RTX;
1082
1083  rounded_size = rx_round_up (size, UNITS_PER_WORD);
1084
1085  /* Don't pass this arg via registers if there
1086     are insufficient registers to hold all of it.  */
1087  if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES)
1088    return NULL_RTX;
1089
1090  /* Unnamed arguments and the last named argument in a
1091     variadic function are always passed on the stack.  */
1092  if (!arg.named)
1093    return NULL_RTX;
1094
1095  /* Structures must occupy an exact number of registers,
1096     otherwise they are passed on the stack.  */
1097  if ((arg.type == NULL || AGGREGATE_TYPE_P (arg.type))
1098      && (size % UNITS_PER_WORD) != 0)
1099    return NULL_RTX;
1100
1101  next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
1102
1103  return gen_rtx_REG (arg.mode, next_reg);
1104}
1105
1106static void
1107rx_function_arg_advance (cumulative_args_t cum,
1108			 const function_arg_info &arg)
1109{
1110  *get_cumulative_args (cum) += rx_function_arg_size (arg.mode, arg.type);
1111}
1112
1113static unsigned int
1114rx_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
1115			  const_tree type ATTRIBUTE_UNUSED)
1116{
1117  /* Older versions of the RX backend aligned all on-stack arguments
1118     to 32-bits.  The RX C ABI however says that they should be
1119     aligned to their natural alignment.  (See section 5.2.2 of the ABI).  */
1120  if (TARGET_GCC_ABI)
1121    return STACK_BOUNDARY;
1122
1123  if (type)
1124    {
1125      if (DECL_P (type))
1126	return DECL_ALIGN (type);
1127      return TYPE_ALIGN (type);
1128    }
1129
1130  return PARM_BOUNDARY;
1131}
1132
1133/* Return an RTL describing where a function return value of type RET_TYPE
1134   is held.  */
1135
1136static rtx
1137rx_function_value (const_tree ret_type,
1138		   const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1139		   bool       outgoing ATTRIBUTE_UNUSED)
1140{
1141  machine_mode mode = TYPE_MODE (ret_type);
1142
1143  /* RX ABI specifies that small integer types are
1144     promoted to int when returned by a function.  */
1145  if (GET_MODE_SIZE (mode) > 0
1146      && GET_MODE_SIZE (mode) < 4
1147      && ! COMPLEX_MODE_P (mode)
1148      && ! VECTOR_TYPE_P (ret_type)
1149      && ! VECTOR_MODE_P (mode)
1150      )
1151    return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
1152
1153  return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
1154}
1155
1156/* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
1157   regard to function returns as does TARGET_FUNCTION_VALUE.  */
1158
1159static machine_mode
1160rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
1161			  machine_mode mode,
1162			  int * punsignedp ATTRIBUTE_UNUSED,
1163			  const_tree funtype ATTRIBUTE_UNUSED,
1164			  int for_return)
1165{
1166  if (for_return != 1
1167      || GET_MODE_SIZE (mode) >= 4
1168      || COMPLEX_MODE_P (mode)
1169      || VECTOR_MODE_P (mode)
1170      || VECTOR_TYPE_P (type)
1171      || GET_MODE_SIZE (mode) < 1)
1172    return mode;
1173
1174  return SImode;
1175}
1176
1177static bool
1178rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1179{
1180  HOST_WIDE_INT size;
1181
1182  if (TYPE_MODE (type) != BLKmode
1183      && ! AGGREGATE_TYPE_P (type))
1184    return false;
1185
1186  size = int_size_in_bytes (type);
1187  /* Large structs and those whose size is not an
1188     exact multiple of 4 are returned in memory.  */
1189  return size < 1
1190    || size > 16
1191    || (size % UNITS_PER_WORD) != 0;
1192}
1193
1194static rtx
1195rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
1196		     int incoming ATTRIBUTE_UNUSED)
1197{
1198  return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM);
1199}
1200
1201static bool
1202rx_return_in_msb (const_tree valtype)
1203{
1204  return TARGET_BIG_ENDIAN_DATA
1205    && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE);
1206}
1207
1208/* Returns true if the provided function has the specified attribute.  */
1209
1210static inline bool
1211has_func_attr (const_tree decl, const char * func_attr)
1212{
1213  if (decl == NULL_TREE)
1214    decl = current_function_decl;
1215
1216  return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1217}
1218
1219/* Returns true if the provided function has the "fast_interrupt" attribute.  */
1220
1221bool
1222is_fast_interrupt_func (const_tree decl)
1223{
1224  return has_func_attr (decl, "fast_interrupt");
1225}
1226
1227/* Returns true if the provided function has the "interrupt" attribute.  */
1228
1229bool
1230is_interrupt_func (const_tree decl)
1231{
1232  return has_func_attr (decl, "interrupt");
1233}
1234
1235/* Returns true if the provided function has the "naked" attribute.  */
1236
1237static inline bool
1238is_naked_func (const_tree decl)
1239{
1240  return has_func_attr (decl, "naked");
1241}
1242
1243static bool use_fixed_regs = false;
1244
1245static void
1246rx_conditional_register_usage (void)
1247{
1248  static bool using_fixed_regs = false;
1249
1250  if (TARGET_PID)
1251    {
1252      rx_pid_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs;
1253      fixed_regs[rx_pid_base_regnum_val] = call_used_regs [rx_pid_base_regnum_val] = 1;
1254    }
1255
1256  if (rx_small_data_limit > 0)
1257    {
1258      if (TARGET_PID)
1259	rx_gp_base_regnum_val = rx_pid_base_regnum_val - 1;
1260      else
1261	rx_gp_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs;
1262
1263      fixed_regs[rx_gp_base_regnum_val] = call_used_regs [rx_gp_base_regnum_val] = 1;
1264    }
1265
1266  if (use_fixed_regs != using_fixed_regs)
1267    {
1268      static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
1269      static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
1270
1271      if (use_fixed_regs)
1272	{
1273	  unsigned int r;
1274
1275	  memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
1276	  memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
1277
1278	  /* This is for fast interrupt handlers.  Any register in
1279	     the range r10 to r13 (inclusive) that is currently
1280	     marked as fixed is now a viable, call-used register.  */
1281	  for (r = 10; r <= 13; r++)
1282	    if (fixed_regs[r])
1283	      {
1284		fixed_regs[r] = 0;
1285		call_used_regs[r] = 1;
1286	      }
1287
1288	  /* Mark r7 as fixed.  This is just a hack to avoid
1289	     altering the reg_alloc_order array so that the newly
1290	     freed r10-r13 registers are the preferred registers.  */
1291	  fixed_regs[7] = call_used_regs[7] = 1;
1292	}
1293      else
1294	{
1295	  /* Restore the normal register masks.  */
1296	  memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
1297	  memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
1298	}
1299
1300      using_fixed_regs = use_fixed_regs;
1301    }
1302}
1303
1304struct decl_chain
1305{
1306  tree fndecl;
1307  struct decl_chain * next;
1308};
1309
1310/* Stack of decls for which we have issued warnings.  */
1311static struct decl_chain * warned_decls = NULL;
1312
1313static void
1314add_warned_decl (tree fndecl)
1315{
1316  struct decl_chain * warned = (struct decl_chain *) xmalloc (sizeof * warned);
1317
1318  warned->fndecl = fndecl;
1319  warned->next = warned_decls;
1320  warned_decls = warned;
1321}
1322
1323/* Returns TRUE if FNDECL is on our list of warned about decls.  */
1324
1325static bool
1326already_warned (tree fndecl)
1327{
1328  struct decl_chain * warned;
1329
1330  for (warned = warned_decls;
1331       warned != NULL;
1332       warned = warned->next)
1333    if (warned->fndecl == fndecl)
1334      return true;
1335
1336  return false;
1337}
1338
1339/* Perform any actions necessary before starting to compile FNDECL.
1340   For the RX we use this to make sure that we have the correct
1341   set of register masks selected.  If FNDECL is NULL then we are
1342   compiling top level things.  */
1343
1344static void
1345rx_set_current_function (tree fndecl)
1346{
1347  /* Remember the last target of rx_set_current_function.  */
1348  static tree rx_previous_fndecl;
1349  bool prev_was_fast_interrupt;
1350  bool current_is_fast_interrupt;
1351
1352  /* Only change the context if the function changes.  This hook is called
1353     several times in the course of compiling a function, and we don't want
1354     to slow things down too much or call target_reinit when it isn't safe.  */
1355  if (fndecl == rx_previous_fndecl)
1356    return;
1357
1358  prev_was_fast_interrupt
1359    = rx_previous_fndecl
1360    ? is_fast_interrupt_func (rx_previous_fndecl) : false;
1361
1362  current_is_fast_interrupt
1363    = fndecl ? is_fast_interrupt_func (fndecl) : false;
1364
1365  if (prev_was_fast_interrupt != current_is_fast_interrupt)
1366    {
1367      use_fixed_regs = current_is_fast_interrupt;
1368      target_reinit ();
1369    }
1370
1371  if (current_is_fast_interrupt && rx_warn_multiple_fast_interrupts)
1372    {
1373      /* We do not warn about the first fast interrupt routine that
1374	 we see.  Instead we just push it onto the stack.  */
1375      if (warned_decls == NULL)
1376	add_warned_decl (fndecl);
1377
1378      /* Otherwise if this fast interrupt is one for which we have
1379	 not already issued a warning, generate one and then push
1380	 it onto the stack as well.  */
1381      else if (! already_warned (fndecl))
1382	{
1383	  warning (0, "multiple fast interrupt routines seen: %qE and %qE",
1384		   fndecl, warned_decls->fndecl);
1385	  add_warned_decl (fndecl);
1386	}
1387    }
1388
1389  rx_previous_fndecl = fndecl;
1390}
1391
1392/* Typical stack layout should looks like this after the function's prologue:
1393
1394                            |    |
1395                              --                       ^
1396                            |    | \                   |
1397                            |    |   arguments saved   | Increasing
1398                            |    |   on the stack      |  addresses
1399    PARENT   arg pointer -> |    | /
1400  -------------------------- ---- -------------------
1401    CHILD                   |ret |   return address
1402                              --
1403                            |    | \
1404                            |    |   call saved
1405                            |    |   registers
1406			    |    | /
1407                              --
1408                            |    | \
1409                            |    |   local
1410                            |    |   variables
1411        frame pointer ->    |    | /
1412                              --
1413                            |    | \
1414                            |    |   outgoing          | Decreasing
1415                            |    |   arguments         |  addresses
1416   current stack pointer -> |    | /                   |
1417  -------------------------- ---- ------------------   V
1418                            |    |                 */
1419
1420static unsigned int
1421bit_count (unsigned int x)
1422{
1423  const unsigned int m1 = 0x55555555;
1424  const unsigned int m2 = 0x33333333;
1425  const unsigned int m4 = 0x0f0f0f0f;
1426
1427  x -= (x >> 1) & m1;
1428  x = (x & m2) + ((x >> 2) & m2);
1429  x = (x + (x >> 4)) & m4;
1430  x += x >>  8;
1431
1432  return (x + (x >> 16)) & 0x3f;
1433}
1434
1435#if defined(TARGET_SAVE_ACC_REGISTER)
1436#define MUST_SAVE_ACC_REGISTER			\
1437  (TARGET_SAVE_ACC_REGISTER			\
1438   && (is_interrupt_func (NULL_TREE)		\
1439       || is_fast_interrupt_func (NULL_TREE)))
1440#else
1441#define MUST_SAVE_ACC_REGISTER 0
1442#endif
1443
1444/* Returns either the lowest numbered and highest numbered registers that
1445   occupy the call-saved area of the stack frame, if the registers are
1446   stored as a contiguous block, or else a bitmask of the individual
1447   registers if they are stored piecemeal.
1448
1449   Also computes the size of the frame and the size of the outgoing
1450   arguments block (in bytes).  */
1451
1452static void
1453rx_get_stack_layout (unsigned int * lowest,
1454		     unsigned int * highest,
1455		     unsigned int * register_mask,
1456		     unsigned int * frame_size,
1457		     unsigned int * stack_size)
1458{
1459  unsigned int reg;
1460  unsigned int low;
1461  unsigned int high;
1462  unsigned int fixed_reg = 0;
1463  unsigned int save_mask;
1464  unsigned int pushed_mask;
1465  unsigned int unneeded_pushes;
1466
1467  if (is_naked_func (NULL_TREE))
1468    {
1469      /* Naked functions do not create their own stack frame.
1470	 Instead the programmer must do that for us.  */
1471      * lowest = 0;
1472      * highest = 0;
1473      * register_mask = 0;
1474      * frame_size = 0;
1475      * stack_size = 0;
1476      return;
1477    }
1478
1479  for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++)
1480    {
1481      if ((df_regs_ever_live_p (reg)
1482	   /* Always save all call clobbered registers inside non-leaf
1483	      interrupt handlers, even if they are not live - they may
1484	      be used in (non-interrupt aware) routines called from this one.  */
1485	   || (call_used_or_fixed_reg_p (reg)
1486	       && is_interrupt_func (NULL_TREE)
1487	       && ! crtl->is_leaf))
1488	  && (! call_used_or_fixed_reg_p (reg)
1489	      /* Even call clobbered registered must
1490		 be pushed inside interrupt handlers.  */
1491	      || is_interrupt_func (NULL_TREE)
1492	      /* Likewise for fast interrupt handlers, except registers r10 -
1493		 r13.  These are normally call-saved, but may have been set
1494		 to call-used by rx_conditional_register_usage.  If so then
1495		 they can be used in the fast interrupt handler without
1496		 saving them on the stack.  */
1497	      || (is_fast_interrupt_func (NULL_TREE)
1498		  && ! IN_RANGE (reg, 10, 13))))
1499	{
1500	  if (low == 0)
1501	    low = reg;
1502	  high = reg;
1503
1504	  save_mask |= 1 << reg;
1505	}
1506
1507      /* Remember if we see a fixed register
1508	 after having found the low register.  */
1509      if (low != 0 && fixed_reg == 0 && fixed_regs [reg])
1510	fixed_reg = reg;
1511    }
1512
1513  /* If we have to save the accumulator register, make sure
1514     that at least two registers are pushed into the frame.  */
1515  if (MUST_SAVE_ACC_REGISTER
1516      && bit_count (save_mask) < 2)
1517    {
1518      save_mask |= (1 << 13) | (1 << 14);
1519      if (low == 0)
1520	low = 13;
1521      if (high == 0 || low == high)
1522	high = low + 1;
1523    }
1524
1525  /* Decide if it would be faster fill in the call-saved area of the stack
1526     frame using multiple PUSH instructions instead of a single PUSHM
1527     instruction.
1528
1529     SAVE_MASK is a bitmask of the registers that must be stored in the
1530     call-save area.  PUSHED_MASK is a bitmask of the registers that would
1531     be pushed into the area if we used a PUSHM instruction.  UNNEEDED_PUSHES
1532     is a bitmask of those registers in pushed_mask that are not in
1533     save_mask.
1534
1535     We use a simple heuristic that says that it is better to use
1536     multiple PUSH instructions if the number of unnecessary pushes is
1537     greater than the number of necessary pushes.
1538
1539     We also use multiple PUSH instructions if there are any fixed registers
1540     between LOW and HIGH.  The only way that this can happen is if the user
1541     has specified --fixed-<reg-name> on the command line and in such
1542     circumstances we do not want to touch the fixed registers at all.
1543
1544     Note also that the code in the prologue/epilogue handlers will
1545     automatically merge multiple PUSHes of adjacent registers into a single
1546     PUSHM.
1547
1548     FIXME: Is it worth improving this heuristic ?  */
1549  pushed_mask = (HOST_WIDE_INT_M1U << low) & ~(HOST_WIDE_INT_M1U << (high + 1));
1550  unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
1551
1552  if ((fixed_reg && fixed_reg <= high)
1553      || (optimize_function_for_speed_p (cfun)
1554	  && bit_count (save_mask) < bit_count (unneeded_pushes)))
1555    {
1556      /* Use multiple pushes.  */
1557      * lowest = 0;
1558      * highest = 0;
1559      * register_mask = save_mask;
1560    }
1561  else
1562    {
1563      /* Use one push multiple instruction.  */
1564      * lowest = low;
1565      * highest = high;
1566      * register_mask = 0;
1567    }
1568
1569  * frame_size = rx_round_up
1570    (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT);
1571
1572  if (crtl->args.size > 0)
1573    * frame_size += rx_round_up
1574      (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT);
1575
1576  * stack_size = rx_round_up
1577    (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT);
1578}
1579
1580/* Generate a PUSHM instruction that matches the given operands.  */
1581
1582void
1583rx_emit_stack_pushm (rtx * operands)
1584{
1585  HOST_WIDE_INT last_reg;
1586  rtx first_push;
1587
1588  gcc_assert (CONST_INT_P (operands[0]));
1589  last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1;
1590
1591  gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1592  first_push = XVECEXP (operands[1], 0, 1);
1593  gcc_assert (SET_P (first_push));
1594  first_push = SET_SRC (first_push);
1595  gcc_assert (REG_P (first_push));
1596
1597  asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
1598	       reg_names [REGNO (first_push) - last_reg],
1599	       reg_names [REGNO (first_push)]);
1600}
1601
1602/* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate.  */
1603
1604static rtx
1605gen_rx_store_vector (unsigned int low, unsigned int high)
1606{
1607  unsigned int i;
1608  unsigned int count = (high - low) + 2;
1609  rtx vector;
1610
1611  vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1612
1613  XVECEXP (vector, 0, 0) =
1614    gen_rtx_SET (stack_pointer_rtx,
1615		 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1616				GEN_INT ((count - 1) * UNITS_PER_WORD)));
1617
1618  for (i = 0; i < count - 1; i++)
1619    XVECEXP (vector, 0, i + 1) =
1620      gen_rtx_SET (gen_rtx_MEM (SImode,
1621				gen_rtx_MINUS (SImode, stack_pointer_rtx,
1622					       GEN_INT ((i + 1) * UNITS_PER_WORD))),
1623		   gen_rtx_REG (SImode, high - i));
1624  return vector;
1625}
1626
1627/* Mark INSN as being frame related.  If it is a PARALLEL
1628   then mark each element as being frame related as well.  */
1629
1630static void
1631mark_frame_related (rtx insn)
1632{
1633  RTX_FRAME_RELATED_P (insn) = 1;
1634  insn = PATTERN (insn);
1635
1636  if (GET_CODE (insn) == PARALLEL)
1637    {
1638      unsigned int i;
1639
1640      for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
1641	RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
1642    }
1643}
1644
1645/* Create CFI notes for register pops.  */
1646static void
1647add_pop_cfi_notes (rtx_insn *insn, unsigned int high, unsigned int low)
1648{
1649  rtx t = plus_constant (Pmode, stack_pointer_rtx,
1650                        (high - low + 1) * UNITS_PER_WORD);
1651  t = gen_rtx_SET (stack_pointer_rtx, t);
1652  add_reg_note (insn, REG_CFA_ADJUST_CFA, t);
1653  RTX_FRAME_RELATED_P (insn) = 1;
1654  for (unsigned int i = low; i <= high; i++)
1655    add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (word_mode, i));
1656}
1657
1658
1659static bool
1660ok_for_max_constant (HOST_WIDE_INT val)
1661{
1662  if (rx_max_constant_size == 0  || rx_max_constant_size == 4)
1663    /* If there is no constraint on the size of constants
1664       used as operands, then any value is legitimate.  */
1665    return true;
1666
1667  /* rx_max_constant_size specifies the maximum number
1668     of bytes that can be used to hold a signed value.  */
1669  return IN_RANGE (val, (HOST_WIDE_INT_M1U << (rx_max_constant_size * 8)),
1670		        ( 1 << (rx_max_constant_size * 8)));
1671}
1672
1673/* Generate an ADD of SRC plus VAL into DEST.
1674   Handles the case where VAL is too big for max_constant_value.
1675   Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true.  */
1676
1677static void
1678gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
1679{
1680  rtx insn;
1681
1682  if (val == NULL_RTX || INTVAL (val) == 0)
1683    {
1684      gcc_assert (dest != src);
1685
1686      insn = emit_move_insn (dest, src);
1687    }
1688  else if (ok_for_max_constant (INTVAL (val)))
1689    insn = emit_insn (gen_addsi3 (dest, src, val));
1690  else
1691    {
1692      /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
1693	 will not reject it.  */
1694      val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST));
1695      insn = emit_insn (gen_addsi3 (dest, src, val));
1696
1697      if (is_frame_related)
1698	/* We have to provide our own frame related note here
1699	   as the dwarf2out code cannot be expected to grok
1700	   our unspec.  */
1701	add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1702		      gen_rtx_SET (dest, gen_rtx_PLUS (SImode, src, val)));
1703      return;
1704    }
1705
1706  if (is_frame_related)
1707    RTX_FRAME_RELATED_P (insn) = 1;
1708}
1709
1710static void
1711push_regs (unsigned int high, unsigned int low)
1712{
1713  rtx insn;
1714
1715  if (low == high)
1716    insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
1717  else
1718    insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD),
1719				       gen_rx_store_vector (low, high)));
1720  mark_frame_related (insn);
1721}
1722
1723void
1724rx_expand_prologue (void)
1725{
1726  unsigned int stack_size;
1727  unsigned int frame_size;
1728  unsigned int mask;
1729  unsigned int low;
1730  unsigned int high;
1731  unsigned int reg;
1732
1733  /* Naked functions use their own, programmer provided prologues.  */
1734  if (is_naked_func (NULL_TREE))
1735    return;
1736
1737  rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1738
1739  if (flag_stack_usage_info)
1740    current_function_static_stack_size = frame_size + stack_size;
1741
1742  /* If we use any of the callee-saved registers, save them now.  */
1743  if (mask)
1744    {
1745      /* Push registers in reverse order.  */
1746      for (reg = CC_REGNUM; reg --;)
1747	if (mask & (1 << reg))
1748	  {
1749	    low = high = reg;
1750
1751	    /* Look for a span of registers.
1752	       Note - we do not have to worry about -Os and whether
1753	       it is better to use a single, longer PUSHM as
1754	       rx_get_stack_layout has already done that for us.  */
1755	    while (reg-- > 0)
1756	      if ((mask & (1 << reg)) == 0)
1757		break;
1758	      else
1759		--low;
1760
1761	    push_regs (high, low);
1762	    if (reg == (unsigned) -1)
1763	      break;
1764	  }
1765    }
1766  else if (low)
1767    push_regs (high, low);
1768
1769  if (MUST_SAVE_ACC_REGISTER)
1770    {
1771      unsigned int acc_high, acc_low;
1772
1773      /* Interrupt handlers have to preserve the accumulator
1774	 register if so requested by the user.  Use the first
1775         two pushed registers as intermediaries.  */
1776      if (mask)
1777	{
1778	  acc_low = acc_high = 0;
1779
1780	  for (reg = 1; reg < CC_REGNUM; reg ++)
1781	    if (mask & (1 << reg))
1782	      {
1783		if (acc_low == 0)
1784		  acc_low = reg;
1785		else
1786		  {
1787		    acc_high = reg;
1788		    break;
1789		  }
1790	      }
1791
1792	  /* We have assumed that there are at least two registers pushed... */
1793	  gcc_assert (acc_high != 0);
1794
1795	  /* Note - the bottom 16 bits of the accumulator are inaccessible.
1796	     We just assume that they are zero.  */
1797	  emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1798	  emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1799	  emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low)));
1800	  emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high)));
1801	}
1802      else
1803	{
1804	  acc_low = low;
1805	  acc_high = low + 1;
1806
1807	  /* We have assumed that there are at least two registers pushed... */
1808	  gcc_assert (acc_high <= high);
1809
1810	  emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1811	  emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1812	  emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD),
1813				      gen_rx_store_vector (acc_low, acc_high)));
1814	}
1815    }
1816
1817  /* If needed, set up the frame pointer.  */
1818  if (frame_pointer_needed)
1819    gen_safe_add (frame_pointer_rtx, stack_pointer_rtx,
1820		  GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1821
1822  /* Allocate space for the outgoing args.
1823     If the stack frame has not already been set up then handle this as well.  */
1824  if (stack_size)
1825    {
1826      if (frame_size)
1827	{
1828	  if (frame_pointer_needed)
1829	    gen_safe_add (stack_pointer_rtx, frame_pointer_rtx,
1830			  GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1831	  else
1832	    gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1833			  GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)),
1834			  true);
1835	}
1836      else
1837	gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1838		      GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1839    }
1840  else if (frame_size)
1841    {
1842      if (! frame_pointer_needed)
1843	gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1844		      GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1845      else
1846	gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
1847		      false /* False because the epilogue will use the FP not the SP.  */);
1848    }
1849}
1850
1851static void
1852add_vector_labels (FILE *file, const char *aname)
1853{
1854  tree vec_attr;
1855  tree val_attr;
1856  const char *vname = "vect";
1857  const char *s;
1858  int vnum;
1859
1860  /* This node is for the vector/interrupt tag itself */
1861  vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl));
1862  if (!vec_attr)
1863    return;
1864
1865  /* Now point it at the first argument */
1866  vec_attr = TREE_VALUE (vec_attr);
1867
1868  /* Iterate through the arguments.  */
1869  while (vec_attr)
1870    {
1871      val_attr = TREE_VALUE (vec_attr);
1872      switch (TREE_CODE (val_attr))
1873	{
1874	case STRING_CST:
1875	  s = TREE_STRING_POINTER (val_attr);
1876	  goto string_id_common;
1877
1878	case IDENTIFIER_NODE:
1879	  s = IDENTIFIER_POINTER (val_attr);
1880
1881	string_id_common:
1882	  if (strcmp (s, "$default") == 0)
1883	    {
1884	      fprintf (file, "\t.global\t$tableentry$default$%s\n", vname);
1885	      fprintf (file, "$tableentry$default$%s:\n", vname);
1886	    }
1887	  else
1888	    vname = s;
1889	  break;
1890
1891	case INTEGER_CST:
1892	  vnum = TREE_INT_CST_LOW (val_attr);
1893
1894	  fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname);
1895	  fprintf (file, "$tableentry$%d$%s:\n", vnum, vname);
1896	  break;
1897
1898	default:
1899	  ;
1900	}
1901
1902      vec_attr = TREE_CHAIN (vec_attr);
1903    }
1904
1905}
1906
1907static void
1908rx_output_function_prologue (FILE * file)
1909{
1910  add_vector_labels (file, "interrupt");
1911  add_vector_labels (file, "vector");
1912
1913  if (is_fast_interrupt_func (NULL_TREE))
1914    asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
1915
1916  if (is_interrupt_func (NULL_TREE))
1917    asm_fprintf (file, "\t; Note: Interrupt Handler\n");
1918
1919  if (is_naked_func (NULL_TREE))
1920    asm_fprintf (file, "\t; Note: Naked Function\n");
1921
1922  if (cfun->static_chain_decl != NULL)
1923    asm_fprintf (file, "\t; Note: Nested function declared "
1924		 "inside another function.\n");
1925
1926  if (crtl->calls_eh_return)
1927    asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n");
1928}
1929
1930/* Generate a POPM or RTSD instruction that matches the given operands.  */
1931
1932void
1933rx_emit_stack_popm (rtx * operands, bool is_popm)
1934{
1935  HOST_WIDE_INT stack_adjust;
1936  HOST_WIDE_INT last_reg;
1937  rtx first_push;
1938
1939  gcc_assert (CONST_INT_P (operands[0]));
1940  stack_adjust = INTVAL (operands[0]);
1941
1942  gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1943  last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3);
1944
1945  first_push = XVECEXP (operands[1], 0, 1);
1946  gcc_assert (SET_P (first_push));
1947  first_push = SET_DEST (first_push);
1948  gcc_assert (REG_P (first_push));
1949
1950  if (is_popm)
1951    asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n",
1952		 reg_names [REGNO (first_push)],
1953		 reg_names [REGNO (first_push) + last_reg]);
1954  else
1955    asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n",
1956		 (int) stack_adjust,
1957		 reg_names [REGNO (first_push)],
1958		 reg_names [REGNO (first_push) + last_reg]);
1959}
1960
1961/* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate.  */
1962
1963static rtx
1964gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high)
1965{
1966  unsigned int i;
1967  unsigned int bias = 3;
1968  unsigned int count = (high - low) + bias;
1969  rtx vector;
1970
1971  vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1972
1973  XVECEXP (vector, 0, 0) =
1974    gen_rtx_SET (stack_pointer_rtx,
1975		 plus_constant (Pmode, stack_pointer_rtx, adjust));
1976
1977  for (i = 0; i < count - 2; i++)
1978    XVECEXP (vector, 0, i + 1) =
1979      gen_rtx_SET (gen_rtx_REG (SImode, low + i),
1980		   gen_rtx_MEM (SImode,
1981				i == 0 ? stack_pointer_rtx
1982				: plus_constant (Pmode, stack_pointer_rtx,
1983						 i * UNITS_PER_WORD)));
1984
1985  XVECEXP (vector, 0, count - 1) = ret_rtx;
1986
1987  return vector;
1988}
1989
1990/* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate.  */
1991
1992static rtx
1993gen_rx_popm_vector (unsigned int low, unsigned int high)
1994{
1995  unsigned int i;
1996  unsigned int count = (high - low) + 2;
1997  rtx vector;
1998
1999  vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2000
2001  XVECEXP (vector, 0, 0) =
2002    gen_rtx_SET (stack_pointer_rtx,
2003		 plus_constant (Pmode, stack_pointer_rtx,
2004				(count - 1) * UNITS_PER_WORD));
2005
2006  for (i = 0; i < count - 1; i++)
2007    XVECEXP (vector, 0, i + 1) =
2008      gen_rtx_SET (gen_rtx_REG (SImode, low + i),
2009		   gen_rtx_MEM (SImode,
2010				i == 0 ? stack_pointer_rtx
2011				: plus_constant (Pmode, stack_pointer_rtx,
2012						 i * UNITS_PER_WORD)));
2013
2014  return vector;
2015}
2016
2017/* Returns true if a simple return insn can be used.  */
2018
2019bool
2020rx_can_use_simple_return (void)
2021{
2022  unsigned int low;
2023  unsigned int high;
2024  unsigned int frame_size;
2025  unsigned int stack_size;
2026  unsigned int register_mask;
2027
2028  if (is_naked_func (NULL_TREE)
2029      || is_fast_interrupt_func (NULL_TREE)
2030      || is_interrupt_func (NULL_TREE))
2031    return false;
2032
2033  rx_get_stack_layout (& low, & high, & register_mask,
2034		       & frame_size, & stack_size);
2035
2036  return (register_mask == 0
2037	  && (frame_size + stack_size) == 0
2038	  && low == 0);
2039}
2040
2041static void
2042pop_regs (unsigned int high, unsigned int low)
2043{
2044  rtx_insn *insn;
2045  if (high == low)
2046    insn = emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
2047  else
2048    insn = emit_insn (gen_stack_popm (GEN_INT (((high - low) + 1)
2049						* UNITS_PER_WORD),
2050				      gen_rx_popm_vector (low, high)));
2051  add_pop_cfi_notes (insn, high, low);
2052}
2053
2054void
2055rx_expand_epilogue (bool is_sibcall)
2056{
2057  unsigned int low;
2058  unsigned int high;
2059  unsigned int frame_size;
2060  unsigned int stack_size;
2061  unsigned int register_mask;
2062  unsigned int regs_size;
2063  unsigned int reg;
2064  unsigned HOST_WIDE_INT total_size;
2065
2066  /* FIXME: We do not support indirect sibcalls at the moment becaause we
2067     cannot guarantee that the register holding the function address is a
2068     call-used register.  If it is a call-saved register then the stack
2069     pop instructions generated in the epilogue will corrupt the address
2070     before it is used.
2071
2072     Creating a new call-used-only register class works but then the
2073     reload pass gets stuck because it cannot always find a call-used
2074     register for spilling sibcalls.
2075
2076     The other possible solution is for this pass to scan forward for the
2077     sibcall instruction (if it has been generated) and work out if it
2078     is an indirect sibcall using a call-saved register.  If it is then
2079     the address can copied into a call-used register in this epilogue
2080     code and the sibcall instruction modified to use that register.  */
2081
2082  if (is_naked_func (NULL_TREE))
2083    {
2084      gcc_assert (! is_sibcall);
2085
2086      /* Naked functions use their own, programmer provided epilogues.
2087	 But, in order to keep gcc happy we have to generate some kind of
2088	 epilogue RTL.  */
2089      emit_jump_insn (gen_naked_return ());
2090      return;
2091    }
2092
2093  rx_get_stack_layout (& low, & high, & register_mask,
2094		       & frame_size, & stack_size);
2095
2096  total_size = frame_size + stack_size;
2097  regs_size = ((high - low) + 1) * UNITS_PER_WORD;
2098
2099  /* See if we are unable to use the special stack frame deconstruct and
2100     return instructions.  In most cases we can use them, but the exceptions
2101     are:
2102
2103     - Sibling calling functions deconstruct the frame but do not return to
2104       their caller.  Instead they branch to their sibling and allow their
2105       return instruction to return to this function's parent.
2106
2107     - Fast and normal interrupt handling functions have to use special
2108       return instructions.
2109
2110     - Functions where we have pushed a fragmented set of registers into the
2111       call-save area must have the same set of registers popped.  */
2112  if (is_sibcall
2113      || is_fast_interrupt_func (NULL_TREE)
2114      || is_interrupt_func (NULL_TREE)
2115      || register_mask)
2116    {
2117      /* Cannot use the special instructions - deconstruct by hand.  */
2118      if (total_size)
2119	gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
2120		      GEN_INT (total_size), false);
2121
2122      if (MUST_SAVE_ACC_REGISTER)
2123	{
2124	  unsigned int acc_low, acc_high;
2125
2126	  /* Reverse the saving of the accumulator register onto the stack.
2127	     Note we must adjust the saved "low" accumulator value as it
2128	     is really the middle 32-bits of the accumulator.  */
2129	  if (register_mask)
2130	    {
2131	      acc_low = acc_high = 0;
2132
2133	      for (reg = 1; reg < CC_REGNUM; reg ++)
2134		if (register_mask & (1 << reg))
2135		  {
2136		    if (acc_low == 0)
2137		      acc_low = reg;
2138		    else
2139		      {
2140			acc_high = reg;
2141			break;
2142		      }
2143		  }
2144	      emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high)));
2145	      emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low)));
2146	    }
2147	  else
2148	    {
2149	      acc_low = low;
2150	      acc_high = low + 1;
2151	      emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD),
2152					 gen_rx_popm_vector (acc_low, acc_high)));
2153	    }
2154
2155	  emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low),
2156				  gen_rtx_REG (SImode, acc_low),
2157				  GEN_INT (16)));
2158	  emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low)));
2159	  emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high)));
2160	}
2161
2162      if (register_mask)
2163	{
2164	  for (reg = 0; reg < CC_REGNUM; reg ++)
2165	    if (register_mask & (1 << reg))
2166	      {
2167		low = high = reg;
2168		while (register_mask & (1 << high))
2169		  high ++;
2170		pop_regs (high - 1, low);
2171		reg = high;
2172	      }
2173	}
2174      else if (low)
2175	pop_regs (high, low);
2176
2177      if (is_fast_interrupt_func (NULL_TREE))
2178	{
2179	  gcc_assert (! is_sibcall);
2180	  emit_jump_insn (gen_fast_interrupt_return ());
2181	}
2182      else if (is_interrupt_func (NULL_TREE))
2183	{
2184	  gcc_assert (! is_sibcall);
2185	  emit_jump_insn (gen_exception_return ());
2186	}
2187      else if (! is_sibcall)
2188	emit_jump_insn (gen_simple_return ());
2189
2190      return;
2191    }
2192
2193  /* If we allocated space on the stack, free it now.  */
2194  if (total_size)
2195    {
2196      unsigned HOST_WIDE_INT rtsd_size;
2197
2198      /* See if we can use the RTSD instruction.  */
2199      rtsd_size = total_size + regs_size;
2200      if (rtsd_size < 1024 && (rtsd_size % 4) == 0)
2201	{
2202	  if (low)
2203	    emit_jump_insn (gen_pop_and_return
2204			    (GEN_INT (rtsd_size),
2205			     gen_rx_rtsd_vector (rtsd_size, low, high)));
2206	  else
2207	    emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size)));
2208
2209	  return;
2210	}
2211
2212      gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
2213		    GEN_INT (total_size), false);
2214    }
2215
2216  if (low)
2217    emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size),
2218					gen_rx_rtsd_vector (regs_size,
2219							    low, high)));
2220  else
2221    emit_jump_insn (gen_simple_return ());
2222}
2223
2224
2225/* Compute the offset (in words) between FROM (arg pointer
2226   or frame pointer) and TO (frame pointer or stack pointer).
2227   See ASCII art comment at the start of rx_expand_prologue
2228   for more information.  */
2229
2230int
2231rx_initial_elimination_offset (int from, int to)
2232{
2233  unsigned int low;
2234  unsigned int high;
2235  unsigned int frame_size;
2236  unsigned int stack_size;
2237  unsigned int mask;
2238
2239  rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
2240
2241  if (from == ARG_POINTER_REGNUM)
2242    {
2243      /* Extend the computed size of the stack frame to
2244	 include the registers pushed in the prologue.  */
2245      if (low)
2246	frame_size += ((high - low) + 1) * UNITS_PER_WORD;
2247      else
2248	frame_size += bit_count (mask) * UNITS_PER_WORD;
2249
2250      /* Remember to include the return address.  */
2251      frame_size += 1 * UNITS_PER_WORD;
2252
2253      if (to == FRAME_POINTER_REGNUM)
2254	return frame_size;
2255
2256      gcc_assert (to == STACK_POINTER_REGNUM);
2257      return frame_size + stack_size;
2258    }
2259
2260  gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM);
2261  return stack_size;
2262}
2263
2264/* Decide if a variable should go into one of the small data sections.  */
2265
2266static bool
2267rx_in_small_data (const_tree decl)
2268{
2269  int size;
2270  const char * section;
2271
2272  if (rx_small_data_limit == 0)
2273    return false;
2274
2275  if (TREE_CODE (decl) != VAR_DECL)
2276    return false;
2277
2278  /* We do not put read-only variables into a small data area because
2279     they would be placed with the other read-only sections, far away
2280     from the read-write data sections, and we only have one small
2281     data area pointer.
2282     Similarly commons are placed in the .bss section which might be
2283     far away (and out of alignment with respect to) the .data section.  */
2284  if (TREE_READONLY (decl) || DECL_COMMON (decl))
2285    return false;
2286
2287  section = DECL_SECTION_NAME (decl);
2288  if (section)
2289    return (strcmp (section, "D_2") == 0) || (strcmp (section, "B_2") == 0);
2290
2291  size = int_size_in_bytes (TREE_TYPE (decl));
2292
2293  return (size > 0) && (size <= rx_small_data_limit);
2294}
2295
2296/* Return a section for X.
2297   The only special thing we do here is to honor small data.  */
2298
2299static section *
2300rx_select_rtx_section (machine_mode mode,
2301		       rtx x,
2302		       unsigned HOST_WIDE_INT align)
2303{
2304  if (rx_small_data_limit > 0
2305      && GET_MODE_SIZE (mode) <= rx_small_data_limit
2306      && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
2307    return sdata_section;
2308
2309  return default_elf_select_rtx_section (mode, x, align);
2310}
2311
2312static section *
2313rx_select_section (tree decl,
2314		   int reloc,
2315		   unsigned HOST_WIDE_INT align)
2316{
2317  if (rx_small_data_limit > 0)
2318    {
2319      switch (categorize_decl_for_section (decl, reloc))
2320	{
2321	case SECCAT_SDATA:	return sdata_section;
2322	case SECCAT_SBSS:	return sbss_section;
2323	case SECCAT_SRODATA:
2324	  /* Fall through.  We do not put small, read only
2325	     data into the C_2 section because we are not
2326	     using the C_2 section.  We do not use the C_2
2327	     section because it is located with the other
2328	     read-only data sections, far away from the read-write
2329	     data sections and we only have one small data
2330	     pointer (r13).  */
2331	default:
2332	  break;
2333	}
2334    }
2335
2336  /* If we are supporting the Renesas assembler
2337     we cannot use mergeable sections.  */
2338  if (TARGET_AS100_SYNTAX)
2339    switch (categorize_decl_for_section (decl, reloc))
2340      {
2341      case SECCAT_RODATA_MERGE_CONST:
2342      case SECCAT_RODATA_MERGE_STR_INIT:
2343      case SECCAT_RODATA_MERGE_STR:
2344	return readonly_data_section;
2345
2346      default:
2347	break;
2348      }
2349
2350  return default_elf_select_section (decl, reloc, align);
2351}
2352
2353enum rx_builtin
2354{
2355  RX_BUILTIN_BRK,
2356  RX_BUILTIN_CLRPSW,
2357  RX_BUILTIN_INT,
2358  RX_BUILTIN_MACHI,
2359  RX_BUILTIN_MACLO,
2360  RX_BUILTIN_MULHI,
2361  RX_BUILTIN_MULLO,
2362  RX_BUILTIN_MVFACHI,
2363  RX_BUILTIN_MVFACMI,
2364  RX_BUILTIN_MVFC,
2365  RX_BUILTIN_MVTACHI,
2366  RX_BUILTIN_MVTACLO,
2367  RX_BUILTIN_MVTC,
2368  RX_BUILTIN_MVTIPL,
2369  RX_BUILTIN_RACW,
2370  RX_BUILTIN_REVW,
2371  RX_BUILTIN_RMPA,
2372  RX_BUILTIN_ROUND,
2373  RX_BUILTIN_SETPSW,
2374  RX_BUILTIN_WAIT,
2375  RX_BUILTIN_max
2376};
2377
2378static GTY(()) tree rx_builtins[(int) RX_BUILTIN_max];
2379
2380static void
2381rx_init_builtins (void)
2382{
2383#define ADD_RX_BUILTIN0(UC_NAME, LC_NAME, RET_TYPE)		\
2384   rx_builtins[RX_BUILTIN_##UC_NAME] =					\
2385   add_builtin_function ("__builtin_rx_" LC_NAME,			\
2386			build_function_type_list (RET_TYPE##_type_node, \
2387						  NULL_TREE),		\
2388			RX_BUILTIN_##UC_NAME,				\
2389			BUILT_IN_MD, NULL, NULL_TREE)
2390
2391#define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE)		\
2392   rx_builtins[RX_BUILTIN_##UC_NAME] =					\
2393   add_builtin_function ("__builtin_rx_" LC_NAME,			\
2394			build_function_type_list (RET_TYPE##_type_node, \
2395						  ARG_TYPE##_type_node, \
2396						  NULL_TREE),		\
2397			RX_BUILTIN_##UC_NAME,				\
2398			BUILT_IN_MD, NULL, NULL_TREE)
2399
2400#define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
2401  rx_builtins[RX_BUILTIN_##UC_NAME] =					\
2402  add_builtin_function ("__builtin_rx_" LC_NAME,			\
2403			build_function_type_list (RET_TYPE##_type_node, \
2404						  ARG_TYPE1##_type_node,\
2405						  ARG_TYPE2##_type_node,\
2406						  NULL_TREE),		\
2407			RX_BUILTIN_##UC_NAME,				\
2408			BUILT_IN_MD, NULL, NULL_TREE)
2409
2410#define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
2411  rx_builtins[RX_BUILTIN_##UC_NAME] =					\
2412  add_builtin_function ("__builtin_rx_" LC_NAME,			\
2413			build_function_type_list (RET_TYPE##_type_node, \
2414						  ARG_TYPE1##_type_node,\
2415						  ARG_TYPE2##_type_node,\
2416						  ARG_TYPE3##_type_node,\
2417						  NULL_TREE),		\
2418			RX_BUILTIN_##UC_NAME,				\
2419			BUILT_IN_MD, NULL, NULL_TREE)
2420
2421  ADD_RX_BUILTIN0 (BRK,     "brk",     void);
2422  ADD_RX_BUILTIN1 (CLRPSW,  "clrpsw",  void,  integer);
2423  ADD_RX_BUILTIN1 (SETPSW,  "setpsw",  void,  integer);
2424  ADD_RX_BUILTIN1 (INT,     "int",     void,  integer);
2425  ADD_RX_BUILTIN2 (MACHI,   "machi",   void,  intSI, intSI);
2426  ADD_RX_BUILTIN2 (MACLO,   "maclo",   void,  intSI, intSI);
2427  ADD_RX_BUILTIN2 (MULHI,   "mulhi",   void,  intSI, intSI);
2428  ADD_RX_BUILTIN2 (MULLO,   "mullo",   void,  intSI, intSI);
2429  ADD_RX_BUILTIN0 (MVFACHI, "mvfachi", intSI);
2430  ADD_RX_BUILTIN0 (MVFACMI, "mvfacmi", intSI);
2431  ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void,  intSI);
2432  ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void,  intSI);
2433  ADD_RX_BUILTIN0 (RMPA,    "rmpa",    void);
2434  ADD_RX_BUILTIN1 (MVFC,    "mvfc",    intSI, integer);
2435  ADD_RX_BUILTIN2 (MVTC,    "mvtc",    void,  integer, integer);
2436  ADD_RX_BUILTIN1 (MVTIPL,  "mvtipl",  void,  integer);
2437  ADD_RX_BUILTIN1 (RACW,    "racw",    void,  integer);
2438  ADD_RX_BUILTIN1 (ROUND,   "round",   intSI, float);
2439  ADD_RX_BUILTIN1 (REVW,    "revw",    intSI, intSI);
2440  ADD_RX_BUILTIN0 (WAIT,    "wait",    void);
2441}
2442
2443/* Return the RX builtin for CODE.  */
2444
2445static tree
2446rx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2447{
2448  if (code >= RX_BUILTIN_max)
2449    return error_mark_node;
2450
2451  return rx_builtins[code];
2452}
2453
2454static rtx
2455rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
2456{
2457  if (reg && ! REG_P (arg))
2458    arg = force_reg (SImode, arg);
2459
2460  emit_insn (gen_func (arg));
2461
2462  return NULL_RTX;
2463}
2464
2465static rtx
2466rx_expand_builtin_mvtc (tree exp)
2467{
2468  rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2469  rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2470
2471  if (! CONST_INT_P (arg1))
2472    return NULL_RTX;
2473
2474  if (! REG_P (arg2))
2475    arg2 = force_reg (SImode, arg2);
2476
2477  emit_insn (gen_mvtc (arg1, arg2));
2478
2479  return NULL_RTX;
2480}
2481
2482static rtx
2483rx_expand_builtin_mvfc (tree t_arg, rtx target)
2484{
2485  rtx arg = expand_normal (t_arg);
2486
2487  if (! CONST_INT_P (arg))
2488    return NULL_RTX;
2489
2490  if (target == NULL_RTX)
2491    return NULL_RTX;
2492
2493  if (! REG_P (target))
2494    target = force_reg (SImode, target);
2495
2496  emit_insn (gen_mvfc (target, arg));
2497
2498  return target;
2499}
2500
2501static rtx
2502rx_expand_builtin_mvtipl (rtx arg)
2503{
2504  /* The RX610 does not support the MVTIPL instruction.  */
2505  if (rx_cpu_type == RX610)
2506    return NULL_RTX;
2507
2508  if (! CONST_INT_P (arg) || ! IN_RANGE (INTVAL (arg), 0, (1 << 4) - 1))
2509    return NULL_RTX;
2510
2511  emit_insn (gen_mvtipl (arg));
2512
2513  return NULL_RTX;
2514}
2515
2516static rtx
2517rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
2518{
2519  rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2520  rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2521
2522  if (! REG_P (arg1))
2523    arg1 = force_reg (SImode, arg1);
2524
2525  if (! REG_P (arg2))
2526    arg2 = force_reg (SImode, arg2);
2527
2528  emit_insn (gen_func (arg1, arg2));
2529
2530  return NULL_RTX;
2531}
2532
2533static rtx
2534rx_expand_int_builtin_1_arg (rtx arg,
2535			     rtx target,
2536			     rtx (* gen_func)(rtx, rtx),
2537			     bool mem_ok)
2538{
2539  if (! REG_P (arg))
2540    if (!mem_ok || ! MEM_P (arg))
2541      arg = force_reg (SImode, arg);
2542
2543  if (target == NULL_RTX || ! REG_P (target))
2544    target = gen_reg_rtx (SImode);
2545
2546  emit_insn (gen_func (target, arg));
2547
2548  return target;
2549}
2550
2551static rtx
2552rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx))
2553{
2554  if (target == NULL_RTX || ! REG_P (target))
2555    target = gen_reg_rtx (SImode);
2556
2557  emit_insn (gen_func (target));
2558
2559  return target;
2560}
2561
2562static rtx
2563rx_expand_builtin_round (rtx arg, rtx target)
2564{
2565  if ((! REG_P (arg) && ! MEM_P (arg))
2566      || GET_MODE (arg) != SFmode)
2567    arg = force_reg (SFmode, arg);
2568
2569  if (target == NULL_RTX || ! REG_P (target))
2570    target = gen_reg_rtx (SImode);
2571
2572  emit_insn (gen_lrintsf2 (target, arg));
2573
2574  return target;
2575}
2576
2577static int
2578valid_psw_flag (rtx op, const char *which)
2579{
2580  static int mvtc_inform_done = 0;
2581
2582  if (GET_CODE (op) == CONST_INT)
2583    switch (INTVAL (op))
2584      {
2585      case 0: case 'c': case 'C':
2586      case 1: case 'z': case 'Z':
2587      case 2: case 's': case 'S':
2588      case 3: case 'o': case 'O':
2589      case 8: case 'i': case 'I':
2590      case 9: case 'u': case 'U':
2591	return 1;
2592      }
2593
2594  error ("%<__builtin_rx_%s%> takes %<C%>, %<Z%>, %<S%>, %<O%>, %<I%>, "
2595	 "or %<U%>", which);
2596  if (!mvtc_inform_done)
2597    error ("use %<__builtin_rx_mvtc%> (0, ... ) to write arbitrary values to PSW");
2598  mvtc_inform_done = 1;
2599
2600  return 0;
2601}
2602
2603static rtx
2604rx_expand_builtin (tree exp,
2605		   rtx target,
2606		   rtx subtarget ATTRIBUTE_UNUSED,
2607		   machine_mode mode ATTRIBUTE_UNUSED,
2608		   int ignore ATTRIBUTE_UNUSED)
2609{
2610  tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2611  tree arg    = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
2612  rtx  op     = arg ? expand_normal (arg) : NULL_RTX;
2613  unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
2614
2615  switch (fcode)
2616    {
2617    case RX_BUILTIN_BRK:     emit_insn (gen_brk ()); return NULL_RTX;
2618    case RX_BUILTIN_CLRPSW:
2619      if (!valid_psw_flag (op, "clrpsw"))
2620	return NULL_RTX;
2621      return rx_expand_void_builtin_1_arg (op, gen_clrpsw, false);
2622    case RX_BUILTIN_SETPSW:
2623      if (!valid_psw_flag (op, "setpsw"))
2624	return NULL_RTX;
2625      return rx_expand_void_builtin_1_arg (op, gen_setpsw, false);
2626    case RX_BUILTIN_INT:     return rx_expand_void_builtin_1_arg
2627	(op, gen_int, false);
2628    case RX_BUILTIN_MACHI:   return rx_expand_builtin_mac (exp, gen_machi);
2629    case RX_BUILTIN_MACLO:   return rx_expand_builtin_mac (exp, gen_maclo);
2630    case RX_BUILTIN_MULHI:   return rx_expand_builtin_mac (exp, gen_mulhi);
2631    case RX_BUILTIN_MULLO:   return rx_expand_builtin_mac (exp, gen_mullo);
2632    case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg
2633	(target, gen_mvfachi);
2634    case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg
2635	(target, gen_mvfacmi);
2636    case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg
2637	(op, gen_mvtachi, true);
2638    case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg
2639	(op, gen_mvtaclo, true);
2640    case RX_BUILTIN_RMPA:
2641      if (rx_allow_string_insns)
2642	emit_insn (gen_rmpa ());
2643      else
2644	error ("%<-mno-allow-string-insns%> forbids the generation "
2645	       "of the RMPA instruction");
2646      return NULL_RTX;
2647    case RX_BUILTIN_MVFC:    return rx_expand_builtin_mvfc (arg, target);
2648    case RX_BUILTIN_MVTC:    return rx_expand_builtin_mvtc (exp);
2649    case RX_BUILTIN_MVTIPL:  return rx_expand_builtin_mvtipl (op);
2650    case RX_BUILTIN_RACW:    return rx_expand_void_builtin_1_arg
2651	(op, gen_racw, false);
2652    case RX_BUILTIN_ROUND:   return rx_expand_builtin_round (op, target);
2653    case RX_BUILTIN_REVW:    return rx_expand_int_builtin_1_arg
2654	(op, target, gen_revw, false);
2655    case RX_BUILTIN_WAIT:    emit_insn (gen_wait ()); return NULL_RTX;
2656
2657    default:
2658      internal_error ("bad builtin code");
2659      break;
2660    }
2661
2662  return NULL_RTX;
2663}
2664
2665/* Place an element into a constructor or destructor section.
2666   Like default_ctor_section_asm_out_constructor in varasm.c
2667   except that it uses .init_array (or .fini_array) and it
2668   handles constructor priorities.  */
2669
2670static void
2671rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
2672{
2673  section * s;
2674
2675  if (priority != DEFAULT_INIT_PRIORITY)
2676    {
2677      char buf[18];
2678
2679      sprintf (buf, "%s.%.5u",
2680	       is_ctor ? ".init_array" : ".fini_array",
2681	       priority);
2682      s = get_section (buf, SECTION_WRITE, NULL_TREE);
2683    }
2684  else if (is_ctor)
2685    s = ctors_section;
2686  else
2687    s = dtors_section;
2688
2689  switch_to_section (s);
2690  assemble_align (POINTER_SIZE);
2691  assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2692}
2693
2694static void
2695rx_elf_asm_constructor (rtx symbol, int priority)
2696{
2697  rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true);
2698}
2699
2700static void
2701rx_elf_asm_destructor (rtx symbol, int priority)
2702{
2703  rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
2704}
2705
2706/* Check "fast_interrupt", "interrupt" and "naked" attributes.  */
2707
2708static tree
2709rx_handle_func_attribute (tree * node,
2710			  tree   name,
2711			  tree   args ATTRIBUTE_UNUSED,
2712			  int    flags ATTRIBUTE_UNUSED,
2713			  bool * no_add_attrs)
2714{
2715  gcc_assert (DECL_P (* node));
2716
2717  if (TREE_CODE (* node) != FUNCTION_DECL)
2718    {
2719      warning (OPT_Wattributes, "%qE attribute only applies to functions",
2720	       name);
2721      * no_add_attrs = true;
2722    }
2723
2724  /* FIXME: We ought to check for conflicting attributes.  */
2725
2726  /* FIXME: We ought to check that the interrupt and exception
2727     handler attributes have been applied to void functions.  */
2728  return NULL_TREE;
2729}
2730
2731/* Check "vector" attribute.  */
2732
2733static tree
2734rx_handle_vector_attribute (tree * node,
2735			    tree   name,
2736			    tree   args,
2737			    int    flags ATTRIBUTE_UNUSED,
2738			    bool * no_add_attrs)
2739{
2740  gcc_assert (DECL_P (* node));
2741  gcc_assert (args != NULL_TREE);
2742
2743  if (TREE_CODE (* node) != FUNCTION_DECL)
2744    {
2745      warning (OPT_Wattributes, "%qE attribute only applies to functions",
2746	       name);
2747      * no_add_attrs = true;
2748    }
2749
2750  return NULL_TREE;
2751}
2752
2753/* Table of RX specific attributes.  */
2754const struct attribute_spec rx_attribute_table[] =
2755{
2756  /* Name, min_len, max_len, decl_req, type_req, fn_type_req,
2757     affects_type_identity, handler, exclude.  */
2758  { "fast_interrupt", 0, 0, true, false, false, false,
2759    rx_handle_func_attribute, NULL },
2760  { "interrupt",      0, -1, true, false, false, false,
2761    rx_handle_func_attribute, NULL },
2762  { "naked",          0, 0, true, false, false, false,
2763    rx_handle_func_attribute, NULL },
2764  { "vector",         1, -1, true, false, false, false,
2765    rx_handle_vector_attribute, NULL },
2766  { NULL,             0, 0, false, false, false, false, NULL, NULL }
2767};
2768
2769/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE.  */
2770
2771static void
2772rx_override_options_after_change (void)
2773{
2774  static bool first_time = TRUE;
2775
2776  if (first_time)
2777    {
2778      /* If this is the first time through and the user has not disabled
2779	 the use of RX FPU hardware then enable -ffinite-math-only,
2780	 since the FPU instructions do not support NaNs and infinities.  */
2781      if (TARGET_USE_FPU)
2782	flag_finite_math_only = 1;
2783
2784      first_time = FALSE;
2785    }
2786  else
2787    {
2788      /* Alert the user if they are changing the optimization options
2789	 to use IEEE compliant floating point arithmetic with RX FPU insns.  */
2790      if (TARGET_USE_FPU
2791	  && !flag_finite_math_only)
2792	warning (0, "RX FPU instructions do not support NaNs and infinities");
2793    }
2794}
2795
2796static void
2797rx_option_override (void)
2798{
2799  unsigned int i;
2800  cl_deferred_option *opt;
2801  vec<cl_deferred_option> *v = (vec<cl_deferred_option> *) rx_deferred_options;
2802
2803  if (v)
2804    FOR_EACH_VEC_ELT (*v, i, opt)
2805      {
2806	switch (opt->opt_index)
2807	  {
2808	  case OPT_mint_register_:
2809	    switch (opt->value)
2810	      {
2811	      case 4:
2812		fixed_regs[10] = call_used_regs [10] = 1;
2813		/* Fall through.  */
2814	      case 3:
2815		fixed_regs[11] = call_used_regs [11] = 1;
2816		/* Fall through.  */
2817	      case 2:
2818		fixed_regs[12] = call_used_regs [12] = 1;
2819		/* Fall through.  */
2820	      case 1:
2821		fixed_regs[13] = call_used_regs [13] = 1;
2822		/* Fall through.  */
2823	      case 0:
2824		rx_num_interrupt_regs = opt->value;
2825		break;
2826	      default:
2827		rx_num_interrupt_regs = 0;
2828		/* Error message already given because rx_handle_option
2829		  returned false.  */
2830		break;
2831	      }
2832	    break;
2833
2834	  default:
2835	    gcc_unreachable ();
2836	  }
2837      }
2838
2839  /* This target defaults to strict volatile bitfields.  */
2840  if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
2841    flag_strict_volatile_bitfields = 1;
2842
2843  rx_override_options_after_change ();
2844
2845  /* These values are bytes, not log.  */
2846  if (! optimize_size)
2847    {
2848      if (flag_align_jumps && !str_align_jumps)
2849	str_align_jumps = ((rx_cpu_type == RX100
2850			    || rx_cpu_type == RX200) ? "4" : "8");
2851      if (flag_align_loops && !str_align_loops)
2852	str_align_loops = ((rx_cpu_type == RX100
2853			    || rx_cpu_type == RX200) ? "4" : "8");
2854      if (flag_align_labels && !str_align_labels)
2855	str_align_labels = ((rx_cpu_type == RX100
2856			     || rx_cpu_type == RX200) ? "4" : "8");
2857    }
2858}
2859
2860
2861static bool
2862rx_allocate_stack_slots_for_args (void)
2863{
2864  /* Naked functions should not allocate stack slots for arguments.  */
2865  return ! is_naked_func (NULL_TREE);
2866}
2867
2868static bool
2869rx_func_attr_inlinable (const_tree decl)
2870{
2871  return ! is_fast_interrupt_func (decl)
2872    &&   ! is_interrupt_func (decl)
2873    &&   ! is_naked_func (decl);
2874}
2875
2876static bool
2877rx_warn_func_return (tree decl)
2878{
2879  /* Naked functions are implemented entirely in assembly, including the
2880     return sequence, so suppress warnings about this.  */
2881  return !is_naked_func (decl);
2882}
2883
2884/* Return nonzero if it is ok to make a tail-call to DECL,
2885   a function_decl or NULL if this is an indirect call, using EXP  */
2886
2887static bool
2888rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
2889{
2890  if (TARGET_JSR)
2891    return false;
2892
2893  /* Do not allow indirect tailcalls.  The
2894     sibcall patterns do not support them.  */
2895  if (decl == NULL)
2896    return false;
2897
2898  /* Never tailcall from inside interrupt handlers or naked functions.  */
2899  if (is_fast_interrupt_func (NULL_TREE)
2900      || is_interrupt_func (NULL_TREE)
2901      || is_naked_func (NULL_TREE))
2902    return false;
2903
2904  return true;
2905}
2906
2907static void
2908rx_file_start (void)
2909{
2910  if (! TARGET_AS100_SYNTAX)
2911    default_file_start ();
2912}
2913
2914static bool
2915rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
2916{
2917  /* The packed attribute overrides the MS behavior.  */
2918  return ! TYPE_PACKED (record_type);
2919}
2920
2921/* Returns true if X a legitimate constant for an immediate
2922   operand on the RX.  X is already known to satisfy CONSTANT_P.  */
2923
2924bool
2925rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2926{
2927  switch (GET_CODE (x))
2928    {
2929    case CONST:
2930      x = XEXP (x, 0);
2931
2932      if (GET_CODE (x) == PLUS)
2933	{
2934	  if (! CONST_INT_P (XEXP (x, 1)))
2935	    return false;
2936
2937	  /* GCC would not pass us CONST_INT + CONST_INT so we
2938	     know that we have {SYMBOL|LABEL} + CONST_INT.  */
2939	  x = XEXP (x, 0);
2940	  gcc_assert (! CONST_INT_P (x));
2941	}
2942
2943      switch (GET_CODE (x))
2944	{
2945	case LABEL_REF:
2946	case SYMBOL_REF:
2947	  return true;
2948
2949	case UNSPEC:
2950	  return XINT (x, 1) == UNSPEC_CONST || XINT (x, 1) == UNSPEC_PID_ADDR;
2951
2952	default:
2953	  /* FIXME: Can this ever happen ?  */
2954	  gcc_unreachable ();
2955	}
2956      break;
2957
2958    case LABEL_REF:
2959    case SYMBOL_REF:
2960      return true;
2961    case CONST_DOUBLE:
2962      return (rx_max_constant_size == 0 || rx_max_constant_size == 4);
2963    case CONST_VECTOR:
2964      return false;
2965    default:
2966      gcc_assert (CONST_INT_P (x));
2967      break;
2968    }
2969
2970  return ok_for_max_constant (INTVAL (x));
2971}
2972
2973static int
2974rx_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
2975		 addr_space_t as ATTRIBUTE_UNUSED, bool speed)
2976{
2977  rtx a, b;
2978
2979  if (GET_CODE (addr) != PLUS)
2980    return COSTS_N_INSNS (1);
2981
2982  a = XEXP (addr, 0);
2983  b = XEXP (addr, 1);
2984
2985  if (REG_P (a) && REG_P (b))
2986    /* Try to discourage REG+REG addressing as it keeps two registers live.  */
2987    return COSTS_N_INSNS (4);
2988
2989  if (speed)
2990    /* [REG+OFF] is just as fast as [REG].  */
2991    return COSTS_N_INSNS (1);
2992
2993  if (CONST_INT_P (b)
2994      && ((INTVAL (b) > 128) || INTVAL (b) < -127))
2995    /* Try to discourage REG + <large OFF> when optimizing for size.  */
2996    return COSTS_N_INSNS (2);
2997
2998  return COSTS_N_INSNS (1);
2999}
3000
3001static bool
3002rx_rtx_costs (rtx x, machine_mode mode, int outer_code ATTRIBUTE_UNUSED,
3003	      int opno ATTRIBUTE_UNUSED, int* total, bool speed)
3004{
3005  if (x == const0_rtx)
3006    {
3007      *total = 0;
3008      return true;
3009    }
3010
3011  switch (GET_CODE (x))
3012    {
3013    case MULT:
3014      if (mode == DImode)
3015	{
3016	  *total = COSTS_N_INSNS (2);
3017	  return true;
3018	}
3019      /* fall through */
3020
3021    case PLUS:
3022    case MINUS:
3023    case AND:
3024    case COMPARE:
3025    case IOR:
3026    case XOR:
3027      *total = COSTS_N_INSNS (1);
3028      return true;
3029
3030    case DIV:
3031      if (speed)
3032	/* This is the worst case for a division.  Pessimize divisions when
3033	   not optimizing for size and allow reciprocal optimizations which
3034	   produce bigger code.  */
3035	*total = COSTS_N_INSNS (20);
3036      else
3037	*total = COSTS_N_INSNS (3);
3038      return true;
3039
3040    case UDIV:
3041      if (speed)
3042	/* This is the worst case for a division.  Pessimize divisions when
3043	   not optimizing for size and allow reciprocal optimizations which
3044	   produce bigger code.  */
3045	*total = COSTS_N_INSNS (18);
3046      else
3047	*total = COSTS_N_INSNS (3);
3048      return true;
3049
3050    default:
3051      break;
3052    }
3053
3054  return false;
3055}
3056
3057static bool
3058rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
3059{
3060  /* We can always eliminate to the frame pointer.
3061     We can eliminate to the stack pointer unless a frame
3062     pointer is needed.  */
3063
3064  return to == FRAME_POINTER_REGNUM
3065    || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed);
3066}
3067
3068
3069static void
3070rx_trampoline_template (FILE * file)
3071{
3072  /* Output assembler code for a block containing the constant
3073     part of a trampoline, leaving space for the variable parts.
3074
3075     On the RX, (where r8 is the static chain regnum) the trampoline
3076     looks like:
3077
3078	   mov 		#<static chain value>, r8
3079	   mov          #<function's address>, r9
3080	   jmp		r9
3081
3082     In big-endian-data-mode however instructions are read into the CPU
3083     4 bytes at a time.  These bytes are then swapped around before being
3084     passed to the decoder.  So...we must partition our trampoline into
3085     4 byte packets and swap these packets around so that the instruction
3086     reader will reverse the process.  But, in order to avoid splitting
3087     the 32-bit constants across these packet boundaries, (making inserting
3088     them into the constructed trampoline very difficult) we have to pad the
3089     instruction sequence with NOP insns.  ie:
3090
3091           nop
3092	   nop
3093           mov.l	#<...>, r8
3094	   nop
3095	   nop
3096           mov.l	#<...>, r9
3097           jmp		r9
3098	   nop
3099	   nop             */
3100
3101  if (! TARGET_BIG_ENDIAN_DATA)
3102    {
3103      asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM);
3104      asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM);
3105      asm_fprintf (file, "\tjmp\tr%d\n",                TRAMPOLINE_TEMP_REGNUM);
3106    }
3107  else
3108    {
3109      char r8 = '0' + STATIC_CHAIN_REGNUM;
3110      char r9 = '0' + TRAMPOLINE_TEMP_REGNUM;
3111
3112      if (TARGET_AS100_SYNTAX)
3113        {
3114          asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r8);
3115          asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
3116          asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H,  003H\n", r9);
3117          asm_fprintf (file, "\t.BYTE 0deH,  0adH, 0beH,  0efH\n");
3118          asm_fprintf (file, "\t.BYTE 003H,  003H, 00%cH, 07fH\n", r9);
3119        }
3120      else
3121        {
3122          asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r8);
3123          asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
3124          asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03,  0x03\n", r9);
3125          asm_fprintf (file, "\t.byte 0xde,  0xad, 0xbe,  0xef\n");
3126          asm_fprintf (file, "\t.byte 0x03,  0x03, 0x0%c, 0x7f\n", r9);
3127        }
3128    }
3129}
3130
3131static void
3132rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
3133{
3134  rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3135
3136  emit_block_move (tramp, assemble_trampoline_template (),
3137		   GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3138
3139  if (TARGET_BIG_ENDIAN_DATA)
3140    {
3141      emit_move_insn (adjust_address (tramp, SImode, 4), chain);
3142      emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
3143    }
3144  else
3145    {
3146      emit_move_insn (adjust_address (tramp, SImode, 2), chain);
3147      emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr);
3148    }
3149}
3150
3151static int
3152rx_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3153		     reg_class_t regclass ATTRIBUTE_UNUSED,
3154		     bool in)
3155{
3156  return (in ? 2 : 0) + REGISTER_MOVE_COST (mode, regclass, regclass);
3157}
3158
3159/* Convert a CC_MODE to the set of flags that it represents.  */
3160
3161static unsigned int
3162flags_from_mode (machine_mode mode)
3163{
3164  switch (mode)
3165    {
3166    case E_CC_ZSmode:
3167      return CC_FLAG_S | CC_FLAG_Z;
3168    case E_CC_ZSOmode:
3169      return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
3170    case E_CC_ZSCmode:
3171      return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C;
3172    case E_CCmode:
3173      return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C;
3174    case E_CC_Fmode:
3175      return CC_FLAG_FP;
3176    default:
3177      gcc_unreachable ();
3178    }
3179}
3180
3181/* Convert a set of flags to a CC_MODE that can implement it.  */
3182
3183static machine_mode
3184mode_from_flags (unsigned int f)
3185{
3186  if (f & CC_FLAG_FP)
3187    return CC_Fmode;
3188  if (f & CC_FLAG_O)
3189    {
3190      if (f & CC_FLAG_C)
3191	return CCmode;
3192      else
3193	return CC_ZSOmode;
3194    }
3195  else if (f & CC_FLAG_C)
3196    return CC_ZSCmode;
3197  else
3198    return CC_ZSmode;
3199}
3200
3201/* Convert an RTX_CODE to the set of flags needed to implement it.
3202   This assumes an integer comparison.  */
3203
3204static unsigned int
3205flags_from_code (enum rtx_code code)
3206{
3207  switch (code)
3208    {
3209    case LT:
3210    case GE:
3211      return CC_FLAG_S;
3212    case GT:
3213    case LE:
3214      return CC_FLAG_S | CC_FLAG_O | CC_FLAG_Z;
3215    case GEU:
3216    case LTU:
3217      return CC_FLAG_C;
3218    case GTU:
3219    case LEU:
3220      return CC_FLAG_C | CC_FLAG_Z;
3221    case EQ:
3222    case NE:
3223      return CC_FLAG_Z;
3224    default:
3225      gcc_unreachable ();
3226    }
3227}
3228
3229/* Return a CC_MODE of which both M1 and M2 are subsets.  */
3230
3231static machine_mode
3232rx_cc_modes_compatible (machine_mode m1, machine_mode m2)
3233{
3234  unsigned f;
3235
3236  /* Early out for identical modes.  */
3237  if (m1 == m2)
3238    return m1;
3239
3240  /* There's no valid combination for FP vs non-FP.  */
3241  f = flags_from_mode (m1) | flags_from_mode (m2);
3242  if (f & CC_FLAG_FP)
3243    return VOIDmode;
3244
3245  /* Otherwise, see what mode can implement all the flags.  */
3246  return mode_from_flags (f);
3247}
3248
3249/* Return the minimal CC mode needed to implement (CMP_CODE X Y).  */
3250
3251machine_mode
3252rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y)
3253{
3254  if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
3255    return CC_Fmode;
3256
3257  if (y != const0_rtx)
3258    return CCmode;
3259
3260  return mode_from_flags (flags_from_code (cmp_code));
3261}
3262
3263/* Split the conditional branch.  Emit (COMPARE C1 C2) into CC_REG with
3264   CC_MODE, and use that in branches based on that compare.  */
3265
3266void
3267rx_split_cbranch (machine_mode cc_mode, enum rtx_code cmp1,
3268		  rtx c1, rtx c2, rtx label)
3269{
3270  rtx flags, x;
3271
3272  flags = gen_rtx_REG (cc_mode, CC_REG);
3273  x = gen_rtx_COMPARE (cc_mode, c1, c2);
3274  x = gen_rtx_SET (flags, x);
3275  emit_insn (x);
3276
3277  x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
3278  x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
3279  x = gen_rtx_SET (pc_rtx, x);
3280  emit_jump_insn (x);
3281}
3282
3283/* A helper function for matching parallels that set the flags.  */
3284
3285bool
3286rx_match_ccmode (rtx insn, machine_mode cc_mode)
3287{
3288  rtx op1, flags;
3289  machine_mode flags_mode;
3290
3291  gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2);
3292
3293  op1 = XVECEXP (PATTERN (insn), 0, 0);
3294  gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE);
3295
3296  flags = SET_DEST (op1);
3297  flags_mode = GET_MODE (flags);
3298
3299  if (GET_MODE (SET_SRC (op1)) != flags_mode)
3300    return false;
3301  if (GET_MODE_CLASS (flags_mode) != MODE_CC)
3302    return false;
3303
3304  /* Ensure that the mode of FLAGS is compatible with CC_MODE.  */
3305  if (flags_from_mode (flags_mode) & ~flags_from_mode (cc_mode))
3306    return false;
3307
3308  return true;
3309}
3310
3311
3312static int
3313rx_max_skip_for_label (rtx_insn *lab)
3314{
3315  int opsize;
3316  rtx_insn *op;
3317
3318  if (optimize_size)
3319    return 0;
3320
3321  if (lab == NULL)
3322    return 0;
3323
3324  op = lab;
3325  do
3326    {
3327      op = next_nonnote_nondebug_insn (op);
3328    }
3329  while (op && (LABEL_P (op)
3330		|| (INSN_P (op) && GET_CODE (PATTERN (op)) == USE)));
3331  if (!op)
3332    return 0;
3333
3334  opsize = get_attr_length (op);
3335  if (opsize >= 0 && opsize < 8)
3336    return MAX (0, opsize - 1);
3337  return 0;
3338}
3339
3340static int
3341rx_align_log_for_label (rtx_insn *lab, int uses_threshold)
3342{
3343  /* This is a simple heuristic to guess when an alignment would not be useful
3344     because the delay due to the inserted NOPs would be greater than the delay
3345     due to the misaligned branch.  If uses_threshold is zero then the alignment
3346     is always useful.  */
3347  if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold)
3348    return 0;
3349
3350  if (optimize_size)
3351    return 0;
3352
3353  /* Return zero if max_skip not a positive number.  */
3354  int max_skip = rx_max_skip_for_label (lab);
3355  if (max_skip <= 0)
3356    return 0;
3357
3358  /* These values are log, not bytes.  */
3359  if (rx_cpu_type == RX100 || rx_cpu_type == RX200)
3360    return 2; /* 4 bytes */
3361  return 3;   /* 8 bytes */
3362}
3363
3364align_flags
3365rx_align_for_label (rtx_insn *lab, int uses_threshold)
3366{
3367  return align_flags (rx_align_log_for_label (lab, uses_threshold),
3368		      rx_max_skip_for_label (lab));
3369}
3370
3371/* Compute the real length of the extending load-and-op instructions.  */
3372
3373int
3374rx_adjust_insn_length (rtx_insn *insn, int current_length)
3375{
3376  rtx extend, mem, offset;
3377  bool zero;
3378  int factor;
3379
3380  if (!INSN_P (insn))
3381    return current_length;
3382
3383  switch (INSN_CODE (insn))
3384    {
3385    default:
3386      return current_length;
3387
3388    case CODE_FOR_plussi3_zero_extendhi:
3389    case CODE_FOR_andsi3_zero_extendhi:
3390    case CODE_FOR_iorsi3_zero_extendhi:
3391    case CODE_FOR_xorsi3_zero_extendhi:
3392    case CODE_FOR_divsi3_zero_extendhi:
3393    case CODE_FOR_udivsi3_zero_extendhi:
3394    case CODE_FOR_minussi3_zero_extendhi:
3395    case CODE_FOR_smaxsi3_zero_extendhi:
3396    case CODE_FOR_sminsi3_zero_extendhi:
3397    case CODE_FOR_multsi3_zero_extendhi:
3398    case CODE_FOR_comparesi3_zero_extendhi:
3399      zero = true;
3400      factor = 2;
3401      break;
3402
3403    case CODE_FOR_plussi3_sign_extendhi:
3404    case CODE_FOR_andsi3_sign_extendhi:
3405    case CODE_FOR_iorsi3_sign_extendhi:
3406    case CODE_FOR_xorsi3_sign_extendhi:
3407    case CODE_FOR_divsi3_sign_extendhi:
3408    case CODE_FOR_udivsi3_sign_extendhi:
3409    case CODE_FOR_minussi3_sign_extendhi:
3410    case CODE_FOR_smaxsi3_sign_extendhi:
3411    case CODE_FOR_sminsi3_sign_extendhi:
3412    case CODE_FOR_multsi3_sign_extendhi:
3413    case CODE_FOR_comparesi3_sign_extendhi:
3414      zero = false;
3415      factor = 2;
3416      break;
3417
3418    case CODE_FOR_plussi3_zero_extendqi:
3419    case CODE_FOR_andsi3_zero_extendqi:
3420    case CODE_FOR_iorsi3_zero_extendqi:
3421    case CODE_FOR_xorsi3_zero_extendqi:
3422    case CODE_FOR_divsi3_zero_extendqi:
3423    case CODE_FOR_udivsi3_zero_extendqi:
3424    case CODE_FOR_minussi3_zero_extendqi:
3425    case CODE_FOR_smaxsi3_zero_extendqi:
3426    case CODE_FOR_sminsi3_zero_extendqi:
3427    case CODE_FOR_multsi3_zero_extendqi:
3428    case CODE_FOR_comparesi3_zero_extendqi:
3429      zero = true;
3430      factor = 1;
3431      break;
3432
3433    case CODE_FOR_plussi3_sign_extendqi:
3434    case CODE_FOR_andsi3_sign_extendqi:
3435    case CODE_FOR_iorsi3_sign_extendqi:
3436    case CODE_FOR_xorsi3_sign_extendqi:
3437    case CODE_FOR_divsi3_sign_extendqi:
3438    case CODE_FOR_udivsi3_sign_extendqi:
3439    case CODE_FOR_minussi3_sign_extendqi:
3440    case CODE_FOR_smaxsi3_sign_extendqi:
3441    case CODE_FOR_sminsi3_sign_extendqi:
3442    case CODE_FOR_multsi3_sign_extendqi:
3443    case CODE_FOR_comparesi3_sign_extendqi:
3444      zero = false;
3445      factor = 1;
3446      break;
3447    }
3448
3449  /* We are expecting: (SET (REG) (<OP> (REG) (<EXTEND> (MEM)))).  */
3450  extend = single_set (insn);
3451  gcc_assert (extend != NULL_RTX);
3452
3453  extend = SET_SRC (extend);
3454  if (GET_CODE (XEXP (extend, 0)) == ZERO_EXTEND
3455      || GET_CODE (XEXP (extend, 0)) == SIGN_EXTEND)
3456    extend = XEXP (extend, 0);
3457  else
3458    extend = XEXP (extend, 1);
3459
3460  gcc_assert ((zero && (GET_CODE (extend) == ZERO_EXTEND))
3461	      || (! zero && (GET_CODE (extend) == SIGN_EXTEND)));
3462
3463  mem = XEXP (extend, 0);
3464  gcc_checking_assert (MEM_P (mem));
3465  if (REG_P (XEXP (mem, 0)))
3466    return (zero && factor == 1) ? 2 : 3;
3467
3468  /* We are expecting: (MEM (PLUS (REG) (CONST_INT))).  */
3469  gcc_checking_assert (GET_CODE (XEXP (mem, 0)) == PLUS);
3470  gcc_checking_assert (REG_P (XEXP (XEXP (mem, 0), 0)));
3471
3472  offset = XEXP (XEXP (mem, 0), 1);
3473  gcc_checking_assert (GET_CODE (offset) == CONST_INT);
3474
3475  if (IN_RANGE (INTVAL (offset), 0, 255 * factor))
3476    return (zero && factor == 1) ? 3 : 4;
3477
3478  return (zero && factor == 1) ? 4 : 5;
3479}
3480
3481static bool
3482rx_narrow_volatile_bitfield (void)
3483{
3484  return true;
3485}
3486
3487static bool
3488rx_ok_to_inline (tree caller, tree callee)
3489{
3490  /* Do not inline functions with local variables
3491     into a naked CALLER - naked function have no stack frame and
3492     locals need a frame in order to have somewhere to live.
3493
3494     Unfortunately we have no way to determine the presence of
3495     local variables in CALLEE, so we have to be cautious and
3496     assume that there might be some there.
3497
3498     We do allow inlining when CALLEE has the "inline" type
3499     modifier or the "always_inline" or "gnu_inline" attributes.  */
3500  return lookup_attribute ("naked", DECL_ATTRIBUTES (caller)) == NULL_TREE
3501    || DECL_DECLARED_INLINE_P (callee)
3502    || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE
3503    || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE;
3504}
3505
3506static bool
3507rx_enable_lra (void)
3508{
3509  return TARGET_ENABLE_LRA;
3510}
3511
3512rx_atomic_sequence::rx_atomic_sequence (const_tree fun_decl)
3513{
3514  if (is_fast_interrupt_func (fun_decl) || is_interrupt_func (fun_decl))
3515    {
3516      /* If we are inside an interrupt handler, assume that interrupts are
3517	 off -- which is the default hardware behavior.  In this case, there
3518	 is no need to disable the interrupts.  */
3519      m_prev_psw_reg = NULL;
3520    }
3521  else
3522    {
3523      m_prev_psw_reg = gen_reg_rtx (SImode);
3524      emit_insn (gen_mvfc (m_prev_psw_reg, GEN_INT (CTRLREG_PSW)));
3525      emit_insn (gen_clrpsw (GEN_INT ('I')));
3526    }
3527}
3528
3529rx_atomic_sequence::~rx_atomic_sequence (void)
3530{
3531  if (m_prev_psw_reg != NULL)
3532    emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW), m_prev_psw_reg));
3533}
3534
3535/* Given an insn and a reg number, tell whether the reg dies or is unused
3536   after the insn.  */
3537bool
3538rx_reg_dead_or_unused_after_insn (const rtx_insn* i, int regno)
3539{
3540  return find_regno_note (i, REG_DEAD, regno) != NULL
3541	 || find_regno_note (i, REG_UNUSED, regno) != NULL;
3542}
3543
3544/* Copy dead and unused notes from SRC to DST for the specified REGNO.  */
3545void
3546rx_copy_reg_dead_or_unused_notes (rtx reg, const rtx_insn* src, rtx_insn* dst)
3547{
3548  int regno = REGNO (SUBREG_P (reg) ? SUBREG_REG (reg) : reg);
3549
3550  if (rtx note = find_regno_note (src, REG_DEAD, regno))
3551    add_shallow_copy_of_reg_note (dst, note);
3552
3553  if (rtx note = find_regno_note (src, REG_UNUSED, regno))
3554    add_shallow_copy_of_reg_note (dst, note);
3555}
3556
3557/* Try to fuse the current bit-operation insn with the surrounding memory load
3558   and store.  */
3559bool
3560rx_fuse_in_memory_bitop (rtx* operands, rtx_insn* curr_insn,
3561			 rtx (*gen_insn)(rtx, rtx))
3562{
3563  rtx op2_reg = SUBREG_P (operands[2]) ? SUBREG_REG (operands[2]) : operands[2];
3564
3565  set_of_reg op2_def = rx_find_set_of_reg (op2_reg, curr_insn,
3566					   prev_nonnote_nondebug_insn_bb);
3567  if (op2_def.set_src == NULL_RTX
3568      || !MEM_P (op2_def.set_src)
3569      || GET_MODE (op2_def.set_src) != QImode
3570      || !rx_is_restricted_memory_address (XEXP (op2_def.set_src, 0),
3571					   GET_MODE (op2_def.set_src))
3572      || reg_used_between_p (operands[2], op2_def.insn, curr_insn)
3573      || !rx_reg_dead_or_unused_after_insn (curr_insn, REGNO (op2_reg))
3574    )
3575    return false;
3576
3577  /* The register operand originates from a memory load and the memory load
3578     could be fused with the bitop insn.
3579     Look for the following memory store with the same memory operand.  */
3580  rtx mem = op2_def.set_src;
3581
3582  /* If the memory is an auto-mod address, it can't be fused.  */
3583  if (GET_CODE (XEXP (mem, 0)) == POST_INC
3584      || GET_CODE (XEXP (mem, 0)) == PRE_INC
3585      || GET_CODE (XEXP (mem, 0)) == POST_DEC
3586      || GET_CODE (XEXP (mem, 0)) == PRE_DEC)
3587    return false;
3588
3589  rtx_insn* op0_use = rx_find_use_of_reg (operands[0], curr_insn,
3590					  next_nonnote_nondebug_insn_bb);
3591  if (op0_use == NULL
3592      || !(GET_CODE (PATTERN (op0_use)) == SET
3593	   && RX_REG_P (XEXP (PATTERN (op0_use), 1))
3594	   && reg_overlap_mentioned_p (operands[0], XEXP (PATTERN (op0_use), 1))
3595	   && rtx_equal_p (mem, XEXP (PATTERN (op0_use), 0)))
3596      || !rx_reg_dead_or_unused_after_insn (op0_use, REGNO (operands[0]))
3597      || reg_set_between_p (operands[2], curr_insn, op0_use))
3598    return false;
3599
3600  /* If the load-modify-store operation is fused it could potentially modify
3601     load/store ordering if there are other memory accesses between the load
3602     and the store for this insn.  If there are volatile mems between the load
3603     and store it's better not to change the ordering.  If there is a call
3604     between the load and store, it's also not safe to fuse it.  */
3605  for (rtx_insn* i = next_nonnote_nondebug_insn_bb (op2_def.insn);
3606       i != NULL && i != op0_use;
3607       i = next_nonnote_nondebug_insn_bb (i))
3608    if (volatile_insn_p (PATTERN (i)) || CALL_P (i))
3609      return false;
3610
3611  emit_insn (gen_insn (mem, gen_lowpart (QImode, operands[1])));
3612  set_insn_deleted (op2_def.insn);
3613  set_insn_deleted (op0_use);
3614  return true;
3615}
3616
3617/* Implement TARGET_HARD_REGNO_NREGS.  */
3618
3619static unsigned int
3620rx_hard_regno_nregs (unsigned int, machine_mode mode)
3621{
3622  return CLASS_MAX_NREGS (0, mode);
3623}
3624
3625/* Implement TARGET_HARD_REGNO_MODE_OK.  */
3626
3627static bool
3628rx_hard_regno_mode_ok (unsigned int regno, machine_mode)
3629{
3630  return REGNO_REG_CLASS (regno) == GR_REGS;
3631}
3632
3633/* Implement TARGET_MODES_TIEABLE_P.  */
3634
3635static bool
3636rx_modes_tieable_p (machine_mode mode1, machine_mode mode2)
3637{
3638  return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
3639	   || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
3640	  == (GET_MODE_CLASS (mode2) == MODE_FLOAT
3641	      || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
3642}
3643
3644#undef  TARGET_NARROW_VOLATILE_BITFIELD
3645#define TARGET_NARROW_VOLATILE_BITFIELD		rx_narrow_volatile_bitfield
3646
3647#undef  TARGET_CAN_INLINE_P
3648#define TARGET_CAN_INLINE_P			rx_ok_to_inline
3649
3650#undef  TARGET_FUNCTION_VALUE
3651#define TARGET_FUNCTION_VALUE		rx_function_value
3652
3653#undef  TARGET_RETURN_IN_MSB
3654#define TARGET_RETURN_IN_MSB		rx_return_in_msb
3655
3656#undef  TARGET_IN_SMALL_DATA_P
3657#define TARGET_IN_SMALL_DATA_P		rx_in_small_data
3658
3659#undef  TARGET_RETURN_IN_MEMORY
3660#define TARGET_RETURN_IN_MEMORY		rx_return_in_memory
3661
3662#undef  TARGET_HAVE_SRODATA_SECTION
3663#define TARGET_HAVE_SRODATA_SECTION	true
3664
3665#undef	TARGET_ASM_SELECT_RTX_SECTION
3666#define	TARGET_ASM_SELECT_RTX_SECTION	rx_select_rtx_section
3667
3668#undef	TARGET_ASM_SELECT_SECTION
3669#define	TARGET_ASM_SELECT_SECTION	rx_select_section
3670
3671#undef  TARGET_INIT_BUILTINS
3672#define TARGET_INIT_BUILTINS		rx_init_builtins
3673
3674#undef  TARGET_BUILTIN_DECL
3675#define TARGET_BUILTIN_DECL		rx_builtin_decl
3676
3677#undef  TARGET_EXPAND_BUILTIN
3678#define TARGET_EXPAND_BUILTIN		rx_expand_builtin
3679
3680#undef  TARGET_ASM_CONSTRUCTOR
3681#define TARGET_ASM_CONSTRUCTOR		rx_elf_asm_constructor
3682
3683#undef  TARGET_ASM_DESTRUCTOR
3684#define TARGET_ASM_DESTRUCTOR		rx_elf_asm_destructor
3685
3686#undef  TARGET_STRUCT_VALUE_RTX
3687#define TARGET_STRUCT_VALUE_RTX		rx_struct_value_rtx
3688
3689#undef  TARGET_ATTRIBUTE_TABLE
3690#define TARGET_ATTRIBUTE_TABLE		rx_attribute_table
3691
3692#undef  TARGET_ASM_FILE_START
3693#define TARGET_ASM_FILE_START			rx_file_start
3694
3695#undef  TARGET_MS_BITFIELD_LAYOUT_P
3696#define TARGET_MS_BITFIELD_LAYOUT_P		rx_is_ms_bitfield_layout
3697
3698#undef  TARGET_LEGITIMATE_ADDRESS_P
3699#define TARGET_LEGITIMATE_ADDRESS_P		rx_is_legitimate_address
3700
3701#undef  TARGET_MODE_DEPENDENT_ADDRESS_P
3702#define TARGET_MODE_DEPENDENT_ADDRESS_P		rx_mode_dependent_address_p
3703
3704#undef  TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
3705#define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS	rx_allocate_stack_slots_for_args
3706
3707#undef  TARGET_ASM_FUNCTION_PROLOGUE
3708#define TARGET_ASM_FUNCTION_PROLOGUE 		rx_output_function_prologue
3709
3710#undef  TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
3711#define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P 	rx_func_attr_inlinable
3712
3713#undef  TARGET_FUNCTION_OK_FOR_SIBCALL
3714#define TARGET_FUNCTION_OK_FOR_SIBCALL		rx_function_ok_for_sibcall
3715
3716#undef  TARGET_FUNCTION_ARG
3717#define TARGET_FUNCTION_ARG     		rx_function_arg
3718
3719#undef  TARGET_FUNCTION_ARG_ADVANCE
3720#define TARGET_FUNCTION_ARG_ADVANCE     	rx_function_arg_advance
3721
3722#undef	TARGET_FUNCTION_ARG_BOUNDARY
3723#define	TARGET_FUNCTION_ARG_BOUNDARY		rx_function_arg_boundary
3724
3725#undef  TARGET_SET_CURRENT_FUNCTION
3726#define TARGET_SET_CURRENT_FUNCTION		rx_set_current_function
3727
3728#undef  TARGET_ASM_INTEGER
3729#define TARGET_ASM_INTEGER			rx_assemble_integer
3730
3731#undef  TARGET_USE_BLOCKS_FOR_CONSTANT_P
3732#define TARGET_USE_BLOCKS_FOR_CONSTANT_P	hook_bool_mode_const_rtx_true
3733
3734#undef  TARGET_MAX_ANCHOR_OFFSET
3735#define TARGET_MAX_ANCHOR_OFFSET		32
3736
3737#undef  TARGET_ADDRESS_COST
3738#define TARGET_ADDRESS_COST			rx_address_cost
3739
3740#undef  TARGET_CAN_ELIMINATE
3741#define TARGET_CAN_ELIMINATE			rx_can_eliminate
3742
3743#undef  TARGET_CONDITIONAL_REGISTER_USAGE
3744#define TARGET_CONDITIONAL_REGISTER_USAGE	rx_conditional_register_usage
3745
3746#undef  TARGET_ASM_TRAMPOLINE_TEMPLATE
3747#define TARGET_ASM_TRAMPOLINE_TEMPLATE		rx_trampoline_template
3748
3749#undef  TARGET_TRAMPOLINE_INIT
3750#define TARGET_TRAMPOLINE_INIT			rx_trampoline_init
3751
3752#undef  TARGET_PRINT_OPERAND
3753#define TARGET_PRINT_OPERAND			rx_print_operand
3754
3755#undef  TARGET_PRINT_OPERAND_ADDRESS
3756#define TARGET_PRINT_OPERAND_ADDRESS		rx_print_operand_address
3757
3758#undef  TARGET_CC_MODES_COMPATIBLE
3759#define TARGET_CC_MODES_COMPATIBLE		rx_cc_modes_compatible
3760
3761#undef  TARGET_MEMORY_MOVE_COST
3762#define TARGET_MEMORY_MOVE_COST			rx_memory_move_cost
3763
3764#undef  TARGET_OPTION_OVERRIDE
3765#define TARGET_OPTION_OVERRIDE			rx_option_override
3766
3767#undef  TARGET_PROMOTE_FUNCTION_MODE
3768#define TARGET_PROMOTE_FUNCTION_MODE		rx_promote_function_mode
3769
3770#undef  TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
3771#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE	rx_override_options_after_change
3772
3773#undef  TARGET_FLAGS_REGNUM
3774#define TARGET_FLAGS_REGNUM			CC_REG
3775
3776#undef  TARGET_LEGITIMATE_CONSTANT_P
3777#define TARGET_LEGITIMATE_CONSTANT_P		rx_is_legitimate_constant
3778
3779#undef  TARGET_LEGITIMIZE_ADDRESS
3780#define TARGET_LEGITIMIZE_ADDRESS		rx_legitimize_address
3781
3782#undef  TARGET_WARN_FUNC_RETURN
3783#define TARGET_WARN_FUNC_RETURN 		rx_warn_func_return
3784
3785#undef  TARGET_LRA_P
3786#define TARGET_LRA_P 				rx_enable_lra
3787
3788#undef  TARGET_HARD_REGNO_NREGS
3789#define TARGET_HARD_REGNO_NREGS			rx_hard_regno_nregs
3790#undef  TARGET_HARD_REGNO_MODE_OK
3791#define TARGET_HARD_REGNO_MODE_OK		rx_hard_regno_mode_ok
3792
3793#undef  TARGET_MODES_TIEABLE_P
3794#define TARGET_MODES_TIEABLE_P			rx_modes_tieable_p
3795
3796#undef  TARGET_RTX_COSTS
3797#define TARGET_RTX_COSTS rx_rtx_costs
3798
3799#undef  TARGET_HAVE_SPECULATION_SAFE_VALUE
3800#define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3801
3802struct gcc_target targetm = TARGET_INITIALIZER;
3803
3804#include "gt-rx.h"
3805