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