gcc/
[official-gcc.git] / gcc / config / rx / rx.c
blob5cadd3ae94709c4a447117b8482c6b58c5a6cde9
1 /* Subroutines used for code generation on Renesas RX processors.
2 Copyright (C) 2008-2015 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
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.
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.
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/>. */
21 /* To Do:
23 * Re-enable memory-to-memory copies and fix up reload. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "alias.h"
30 #include "symtab.h"
31 #include "tree.h"
32 #include "varasm.h"
33 #include "stor-layout.h"
34 #include "calls.h"
35 #include "rtl.h"
36 #include "regs.h"
37 #include "hard-reg-set.h"
38 #include "insn-config.h"
39 #include "conditions.h"
40 #include "output.h"
41 #include "insn-attr.h"
42 #include "flags.h"
43 #include "function.h"
44 #include "expmed.h"
45 #include "dojump.h"
46 #include "explow.h"
47 #include "emit-rtl.h"
48 #include "stmt.h"
49 #include "expr.h"
50 #include "insn-codes.h"
51 #include "optabs.h"
52 #include "libfuncs.h"
53 #include "recog.h"
54 #include "diagnostic-core.h"
55 #include "toplev.h"
56 #include "reload.h"
57 #include "dominance.h"
58 #include "cfg.h"
59 #include "cfgrtl.h"
60 #include "cfganal.h"
61 #include "lcm.h"
62 #include "cfgbuild.h"
63 #include "cfgcleanup.h"
64 #include "predict.h"
65 #include "basic-block.h"
66 #include "df.h"
67 #include "tm_p.h"
68 #include "debug.h"
69 #include "target.h"
70 #include "langhooks.h"
71 #include "opts.h"
72 #include "plugin-api.h"
73 #include "ipa-ref.h"
74 #include "cgraph.h"
75 #include "builtins.h"
77 #include "target-def.h"
79 static unsigned int rx_gp_base_regnum_val = INVALID_REGNUM;
80 static unsigned int rx_pid_base_regnum_val = INVALID_REGNUM;
81 static unsigned int rx_num_interrupt_regs;
83 static unsigned int
84 rx_gp_base_regnum (void)
86 if (rx_gp_base_regnum_val == INVALID_REGNUM)
87 gcc_unreachable ();
88 return rx_gp_base_regnum_val;
91 static unsigned int
92 rx_pid_base_regnum (void)
94 if (rx_pid_base_regnum_val == INVALID_REGNUM)
95 gcc_unreachable ();
96 return rx_pid_base_regnum_val;
99 /* Find a SYMBOL_REF in a "standard" MEM address and return its decl. */
101 static tree
102 rx_decl_for_addr (rtx op)
104 if (GET_CODE (op) == MEM)
105 op = XEXP (op, 0);
106 if (GET_CODE (op) == CONST)
107 op = XEXP (op, 0);
108 while (GET_CODE (op) == PLUS)
109 op = XEXP (op, 0);
110 if (GET_CODE (op) == SYMBOL_REF)
111 return SYMBOL_REF_DECL (op);
112 return NULL_TREE;
115 static void rx_print_operand (FILE *, rtx, int);
117 #define CC_FLAG_S (1 << 0)
118 #define CC_FLAG_Z (1 << 1)
119 #define CC_FLAG_O (1 << 2)
120 #define CC_FLAG_C (1 << 3)
121 #define CC_FLAG_FP (1 << 4) /* Fake, to differentiate CC_Fmode. */
123 static unsigned int flags_from_mode (machine_mode mode);
124 static unsigned int flags_from_code (enum rtx_code code);
126 /* Return true if OP is a reference to an object in a PID data area. */
128 enum pid_type
130 PID_NOT_PID = 0, /* The object is not in the PID data area. */
131 PID_ENCODED, /* The object is in the PID data area. */
132 PID_UNENCODED /* The object will be placed in the PID data area, but it has not been placed there yet. */
135 static enum pid_type
136 rx_pid_data_operand (rtx op)
138 tree op_decl;
140 if (!TARGET_PID)
141 return PID_NOT_PID;
143 if (GET_CODE (op) == PLUS
144 && GET_CODE (XEXP (op, 0)) == REG
145 && GET_CODE (XEXP (op, 1)) == CONST
146 && GET_CODE (XEXP (XEXP (op, 1), 0)) == UNSPEC)
147 return PID_ENCODED;
149 op_decl = rx_decl_for_addr (op);
151 if (op_decl)
153 if (TREE_READONLY (op_decl))
154 return PID_UNENCODED;
156 else
158 /* Sigh, some special cases. */
159 if (GET_CODE (op) == SYMBOL_REF
160 || GET_CODE (op) == LABEL_REF)
161 return PID_UNENCODED;
164 return PID_NOT_PID;
167 static rtx
168 rx_legitimize_address (rtx x,
169 rtx oldx ATTRIBUTE_UNUSED,
170 machine_mode mode ATTRIBUTE_UNUSED)
172 if (rx_pid_data_operand (x) == PID_UNENCODED)
174 rtx rv = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), x);
175 return rv;
178 if (GET_CODE (x) == PLUS
179 && GET_CODE (XEXP (x, 0)) == PLUS
180 && REG_P (XEXP (XEXP (x, 0), 0))
181 && REG_P (XEXP (x, 1)))
182 return force_reg (SImode, x);
184 return x;
187 /* Return true if OP is a reference to an object in a small data area. */
189 static bool
190 rx_small_data_operand (rtx op)
192 if (rx_small_data_limit == 0)
193 return false;
195 if (GET_CODE (op) == SYMBOL_REF)
196 return SYMBOL_REF_SMALL_P (op);
198 return false;
201 static bool
202 rx_is_legitimate_address (machine_mode mode, rtx x,
203 bool strict ATTRIBUTE_UNUSED)
205 if (RTX_OK_FOR_BASE (x, strict))
206 /* Register Indirect. */
207 return true;
209 if ((GET_MODE_SIZE (mode) == 4
210 || GET_MODE_SIZE (mode) == 2
211 || GET_MODE_SIZE (mode) == 1)
212 && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
213 /* Pre-decrement Register Indirect or
214 Post-increment Register Indirect. */
215 return RTX_OK_FOR_BASE (XEXP (x, 0), strict);
217 switch (rx_pid_data_operand (x))
219 case PID_UNENCODED:
220 return false;
221 case PID_ENCODED:
222 return true;
223 default:
224 break;
227 if (GET_CODE (x) == PLUS)
229 rtx arg1 = XEXP (x, 0);
230 rtx arg2 = XEXP (x, 1);
231 rtx index = NULL_RTX;
233 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict))
234 index = arg2;
235 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict))
236 index = arg1;
237 else
238 return false;
240 switch (GET_CODE (index))
242 case CONST_INT:
244 /* Register Relative: REG + INT.
245 Only positive, mode-aligned, mode-sized
246 displacements are allowed. */
247 HOST_WIDE_INT val = INTVAL (index);
248 int factor;
250 if (val < 0)
251 return false;
253 switch (GET_MODE_SIZE (mode))
255 default:
256 case 4: factor = 4; break;
257 case 2: factor = 2; break;
258 case 1: factor = 1; break;
261 if (val > (65535 * factor))
262 return false;
263 return (val % factor) == 0;
266 case REG:
267 /* Unscaled Indexed Register Indirect: REG + REG
268 Size has to be "QI", REG has to be valid. */
269 return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict);
271 case MULT:
273 /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
274 Factor has to equal the mode size, REG has to be valid. */
275 rtx factor;
277 factor = XEXP (index, 1);
278 index = XEXP (index, 0);
280 return REG_P (index)
281 && RTX_OK_FOR_BASE (index, strict)
282 && CONST_INT_P (factor)
283 && GET_MODE_SIZE (mode) == INTVAL (factor);
286 default:
287 return false;
291 /* Small data area accesses turn into register relative offsets. */
292 return rx_small_data_operand (x);
295 /* Returns TRUE for simple memory addreses, ie ones
296 that do not involve register indirect addressing
297 or pre/post increment/decrement. */
299 bool
300 rx_is_restricted_memory_address (rtx mem, machine_mode mode)
302 if (! rx_is_legitimate_address
303 (mode, mem, reload_in_progress || reload_completed))
304 return false;
306 switch (GET_CODE (mem))
308 case REG:
309 /* Simple memory addresses are OK. */
310 return true;
312 case PRE_DEC:
313 case POST_INC:
314 return false;
316 case PLUS:
318 rtx base, index;
320 /* Only allow REG+INT addressing. */
321 base = XEXP (mem, 0);
322 index = XEXP (mem, 1);
324 if (! RX_REG_P (base) || ! CONST_INT_P (index))
325 return false;
327 return IN_RANGE (INTVAL (index), 0, (0x10000 * GET_MODE_SIZE (mode)) - 1);
330 case SYMBOL_REF:
331 /* Can happen when small data is being supported.
332 Assume that it will be resolved into GP+INT. */
333 return true;
335 default:
336 gcc_unreachable ();
340 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
342 static bool
343 rx_mode_dependent_address_p (const_rtx addr, addr_space_t as ATTRIBUTE_UNUSED)
345 if (GET_CODE (addr) == CONST)
346 addr = XEXP (addr, 0);
348 switch (GET_CODE (addr))
350 /* --REG and REG++ only work in SImode. */
351 case PRE_DEC:
352 case POST_INC:
353 return true;
355 case MINUS:
356 case PLUS:
357 if (! REG_P (XEXP (addr, 0)))
358 return true;
360 addr = XEXP (addr, 1);
362 switch (GET_CODE (addr))
364 case REG:
365 /* REG+REG only works in SImode. */
366 return true;
368 case CONST_INT:
369 /* REG+INT is only mode independent if INT is a
370 multiple of 4, positive and will fit into 16-bits. */
371 if (((INTVAL (addr) & 3) == 0)
372 && IN_RANGE (INTVAL (addr), 4, 0xfffc))
373 return false;
374 return true;
376 case SYMBOL_REF:
377 case LABEL_REF:
378 return true;
380 case MULT:
381 gcc_assert (REG_P (XEXP (addr, 0)));
382 gcc_assert (CONST_INT_P (XEXP (addr, 1)));
383 /* REG+REG*SCALE is always mode dependent. */
384 return true;
386 default:
387 /* Not recognized, so treat as mode dependent. */
388 return true;
391 case CONST_INT:
392 case SYMBOL_REF:
393 case LABEL_REF:
394 case REG:
395 /* These are all mode independent. */
396 return false;
398 default:
399 /* Everything else is unrecognized,
400 so treat as mode dependent. */
401 return true;
405 /* A C compound statement to output to stdio stream FILE the
406 assembler syntax for an instruction operand that is a memory
407 reference whose address is ADDR. */
409 static void
410 rx_print_operand_address (FILE * file, rtx addr)
412 switch (GET_CODE (addr))
414 case REG:
415 fprintf (file, "[");
416 rx_print_operand (file, addr, 0);
417 fprintf (file, "]");
418 break;
420 case PRE_DEC:
421 fprintf (file, "[-");
422 rx_print_operand (file, XEXP (addr, 0), 0);
423 fprintf (file, "]");
424 break;
426 case POST_INC:
427 fprintf (file, "[");
428 rx_print_operand (file, XEXP (addr, 0), 0);
429 fprintf (file, "+]");
430 break;
432 case PLUS:
434 rtx arg1 = XEXP (addr, 0);
435 rtx arg2 = XEXP (addr, 1);
436 rtx base, index;
438 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true))
439 base = arg1, index = arg2;
440 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true))
441 base = arg2, index = arg1;
442 else
444 rx_print_operand (file, arg1, 0);
445 fprintf (file, " + ");
446 rx_print_operand (file, arg2, 0);
447 break;
450 if (REG_P (index) || GET_CODE (index) == MULT)
452 fprintf (file, "[");
453 rx_print_operand (file, index, 'A');
454 fprintf (file, ",");
456 else /* GET_CODE (index) == CONST_INT */
458 rx_print_operand (file, index, 'A');
459 fprintf (file, "[");
461 rx_print_operand (file, base, 0);
462 fprintf (file, "]");
463 break;
466 case CONST:
467 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
469 addr = XEXP (addr, 0);
470 gcc_assert (XINT (addr, 1) == UNSPEC_CONST);
472 addr = XVECEXP (addr, 0, 0);
473 gcc_assert (CONST_INT_P (addr));
474 fprintf (file, "#");
475 output_addr_const (file, addr);
476 break;
478 fprintf (file, "#");
479 output_addr_const (file, XEXP (addr, 0));
480 break;
482 case UNSPEC:
483 addr = XVECEXP (addr, 0, 0);
484 /* Fall through. */
485 case LABEL_REF:
486 case SYMBOL_REF:
487 fprintf (file, "#");
488 /* Fall through. */
489 default:
490 output_addr_const (file, addr);
491 break;
495 static void
496 rx_print_integer (FILE * file, HOST_WIDE_INT val)
498 if (IN_RANGE (val, -64, 64))
499 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
500 else
501 fprintf (file,
502 TARGET_AS100_SYNTAX
503 ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX,
504 val);
507 static bool
508 rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
510 const char * op = integer_asm_op (size, is_aligned);
512 if (! CONST_INT_P (x))
513 return default_assemble_integer (x, size, is_aligned);
515 if (op == NULL)
516 return false;
517 fputs (op, asm_out_file);
519 rx_print_integer (asm_out_file, INTVAL (x));
520 fputc ('\n', asm_out_file);
521 return true;
525 /* Handles the insertion of a single operand into the assembler output.
526 The %<letter> directives supported are:
528 %A Print an operand without a leading # character.
529 %B Print an integer comparison name.
530 %C Print a control register name.
531 %F Print a condition code flag name.
532 %G Register used for small-data-area addressing
533 %H Print high part of a DImode register, integer or address.
534 %L Print low part of a DImode register, integer or address.
535 %N Print the negation of the immediate value.
536 %P Register used for PID addressing
537 %Q If the operand is a MEM, then correctly generate
538 register indirect or register relative addressing.
539 %R Like %Q but for zero-extending loads. */
541 static void
542 rx_print_operand (FILE * file, rtx op, int letter)
544 bool unsigned_load = false;
545 bool print_hash = true;
547 if (letter == 'A'
548 && ((GET_CODE (op) == CONST
549 && GET_CODE (XEXP (op, 0)) == UNSPEC)
550 || GET_CODE (op) == UNSPEC))
552 print_hash = false;
553 letter = 0;
556 switch (letter)
558 case 'A':
559 /* Print an operand without a leading #. */
560 if (MEM_P (op))
561 op = XEXP (op, 0);
563 switch (GET_CODE (op))
565 case LABEL_REF:
566 case SYMBOL_REF:
567 output_addr_const (file, op);
568 break;
569 case CONST_INT:
570 fprintf (file, "%ld", (long) INTVAL (op));
571 break;
572 default:
573 rx_print_operand (file, op, 0);
574 break;
576 break;
578 case 'B':
580 enum rtx_code code = GET_CODE (op);
581 machine_mode mode = GET_MODE (XEXP (op, 0));
582 const char *ret;
584 if (mode == CC_Fmode)
586 /* C flag is undefined, and O flag carries unordered. None of the
587 branch combinations that include O use it helpfully. */
588 switch (code)
590 case ORDERED:
591 ret = "no";
592 break;
593 case UNORDERED:
594 ret = "o";
595 break;
596 case LT:
597 ret = "n";
598 break;
599 case GE:
600 ret = "pz";
601 break;
602 case EQ:
603 ret = "eq";
604 break;
605 case NE:
606 ret = "ne";
607 break;
608 default:
609 gcc_unreachable ();
612 else
614 unsigned int flags = flags_from_mode (mode);
616 switch (code)
618 case LT:
619 ret = (flags & CC_FLAG_O ? "lt" : "n");
620 break;
621 case GE:
622 ret = (flags & CC_FLAG_O ? "ge" : "pz");
623 break;
624 case GT:
625 ret = "gt";
626 break;
627 case LE:
628 ret = "le";
629 break;
630 case GEU:
631 ret = "geu";
632 break;
633 case LTU:
634 ret = "ltu";
635 break;
636 case GTU:
637 ret = "gtu";
638 break;
639 case LEU:
640 ret = "leu";
641 break;
642 case EQ:
643 ret = "eq";
644 break;
645 case NE:
646 ret = "ne";
647 break;
648 default:
649 gcc_unreachable ();
651 gcc_checking_assert ((flags_from_code (code) & ~flags) == 0);
653 fputs (ret, file);
654 break;
657 case 'C':
658 gcc_assert (CONST_INT_P (op));
659 switch (INTVAL (op))
661 case 0: fprintf (file, "psw"); break;
662 case 2: fprintf (file, "usp"); break;
663 case 3: fprintf (file, "fpsw"); break;
664 case 4: fprintf (file, "cpen"); break;
665 case 8: fprintf (file, "bpsw"); break;
666 case 9: fprintf (file, "bpc"); break;
667 case 0xa: fprintf (file, "isp"); break;
668 case 0xb: fprintf (file, "fintv"); break;
669 case 0xc: fprintf (file, "intb"); break;
670 default:
671 warning (0, "unrecognized control register number: %d - using 'psw'",
672 (int) INTVAL (op));
673 fprintf (file, "psw");
674 break;
676 break;
678 case 'F':
679 gcc_assert (CONST_INT_P (op));
680 switch (INTVAL (op))
682 case 0: case 'c': case 'C': fprintf (file, "C"); break;
683 case 1: case 'z': case 'Z': fprintf (file, "Z"); break;
684 case 2: case 's': case 'S': fprintf (file, "S"); break;
685 case 3: case 'o': case 'O': fprintf (file, "O"); break;
686 case 8: case 'i': case 'I': fprintf (file, "I"); break;
687 case 9: case 'u': case 'U': fprintf (file, "U"); break;
688 default:
689 gcc_unreachable ();
691 break;
693 case 'G':
694 fprintf (file, "%s", reg_names [rx_gp_base_regnum ()]);
695 break;
697 case 'H':
698 switch (GET_CODE (op))
700 case REG:
701 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
702 break;
703 case CONST_INT:
705 HOST_WIDE_INT v = INTVAL (op);
707 fprintf (file, "#");
708 /* Trickery to avoid problems with shifting 32 bits at a time. */
709 v = v >> 16;
710 v = v >> 16;
711 rx_print_integer (file, v);
712 break;
714 case CONST_DOUBLE:
715 fprintf (file, "#");
716 rx_print_integer (file, CONST_DOUBLE_HIGH (op));
717 break;
718 case MEM:
719 if (! WORDS_BIG_ENDIAN)
720 op = adjust_address (op, SImode, 4);
721 output_address (XEXP (op, 0));
722 break;
723 default:
724 gcc_unreachable ();
726 break;
728 case 'L':
729 switch (GET_CODE (op))
731 case REG:
732 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
733 break;
734 case CONST_INT:
735 fprintf (file, "#");
736 rx_print_integer (file, INTVAL (op) & 0xffffffff);
737 break;
738 case CONST_DOUBLE:
739 fprintf (file, "#");
740 rx_print_integer (file, CONST_DOUBLE_LOW (op));
741 break;
742 case MEM:
743 if (WORDS_BIG_ENDIAN)
744 op = adjust_address (op, SImode, 4);
745 output_address (XEXP (op, 0));
746 break;
747 default:
748 gcc_unreachable ();
750 break;
752 case 'N':
753 gcc_assert (CONST_INT_P (op));
754 fprintf (file, "#");
755 rx_print_integer (file, - INTVAL (op));
756 break;
758 case 'P':
759 fprintf (file, "%s", reg_names [rx_pid_base_regnum ()]);
760 break;
762 case 'R':
763 gcc_assert (GET_MODE_SIZE (GET_MODE (op)) <= 4);
764 unsigned_load = true;
765 /* Fall through. */
766 case 'Q':
767 if (MEM_P (op))
769 HOST_WIDE_INT offset;
770 rtx mem = op;
772 op = XEXP (op, 0);
774 if (REG_P (op))
775 offset = 0;
776 else if (GET_CODE (op) == PLUS)
778 rtx displacement;
780 if (REG_P (XEXP (op, 0)))
782 displacement = XEXP (op, 1);
783 op = XEXP (op, 0);
785 else
787 displacement = XEXP (op, 0);
788 op = XEXP (op, 1);
789 gcc_assert (REG_P (op));
792 gcc_assert (CONST_INT_P (displacement));
793 offset = INTVAL (displacement);
794 gcc_assert (offset >= 0);
796 fprintf (file, "%ld", offset);
798 else
799 gcc_unreachable ();
801 fprintf (file, "[");
802 rx_print_operand (file, op, 0);
803 fprintf (file, "].");
805 switch (GET_MODE_SIZE (GET_MODE (mem)))
807 case 1:
808 gcc_assert (offset <= 65535 * 1);
809 fprintf (file, unsigned_load ? "UB" : "B");
810 break;
811 case 2:
812 gcc_assert (offset % 2 == 0);
813 gcc_assert (offset <= 65535 * 2);
814 fprintf (file, unsigned_load ? "UW" : "W");
815 break;
816 case 4:
817 gcc_assert (offset % 4 == 0);
818 gcc_assert (offset <= 65535 * 4);
819 fprintf (file, "L");
820 break;
821 default:
822 gcc_unreachable ();
824 break;
827 /* Fall through. */
829 default:
830 if (GET_CODE (op) == CONST
831 && GET_CODE (XEXP (op, 0)) == UNSPEC)
832 op = XEXP (op, 0);
833 else if (GET_CODE (op) == CONST
834 && GET_CODE (XEXP (op, 0)) == PLUS
835 && GET_CODE (XEXP (XEXP (op, 0), 0)) == UNSPEC
836 && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT)
838 if (print_hash)
839 fprintf (file, "#");
840 fprintf (file, "(");
841 rx_print_operand (file, XEXP (XEXP (op, 0), 0), 'A');
842 fprintf (file, " + ");
843 output_addr_const (file, XEXP (XEXP (op, 0), 1));
844 fprintf (file, ")");
845 return;
848 switch (GET_CODE (op))
850 case MULT:
851 /* Should be the scaled part of an
852 indexed register indirect address. */
854 rtx base = XEXP (op, 0);
855 rtx index = XEXP (op, 1);
857 /* Check for a swaped index register and scaling factor.
858 Not sure if this can happen, but be prepared to handle it. */
859 if (CONST_INT_P (base) && REG_P (index))
861 rtx tmp = base;
862 base = index;
863 index = tmp;
866 gcc_assert (REG_P (base));
867 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
868 gcc_assert (CONST_INT_P (index));
869 /* Do not try to verify the value of the scalar as it is based
870 on the mode of the MEM not the mode of the MULT. (Which
871 will always be SImode). */
872 fprintf (file, "%s", reg_names [REGNO (base)]);
873 break;
876 case MEM:
877 output_address (XEXP (op, 0));
878 break;
880 case PLUS:
881 output_address (op);
882 break;
884 case REG:
885 gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
886 fprintf (file, "%s", reg_names [REGNO (op)]);
887 break;
889 case SUBREG:
890 gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER);
891 fprintf (file, "%s", reg_names [subreg_regno (op)]);
892 break;
894 /* This will only be single precision.... */
895 case CONST_DOUBLE:
897 unsigned long val;
898 REAL_VALUE_TYPE rv;
900 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
901 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
902 if (print_hash)
903 fprintf (file, "#");
904 fprintf (file, TARGET_AS100_SYNTAX ? "0%lxH" : "0x%lx", val);
905 break;
908 case CONST_INT:
909 if (print_hash)
910 fprintf (file, "#");
911 rx_print_integer (file, INTVAL (op));
912 break;
914 case UNSPEC:
915 switch (XINT (op, 1))
917 case UNSPEC_PID_ADDR:
919 rtx sym, add;
921 if (print_hash)
922 fprintf (file, "#");
923 sym = XVECEXP (op, 0, 0);
924 add = NULL_RTX;
925 fprintf (file, "(");
926 if (GET_CODE (sym) == PLUS)
928 add = XEXP (sym, 1);
929 sym = XEXP (sym, 0);
931 output_addr_const (file, sym);
932 if (add != NULL_RTX)
934 fprintf (file, "+");
935 output_addr_const (file, add);
937 fprintf (file, "-__pid_base");
938 fprintf (file, ")");
939 return;
942 /* Fall through */
944 case CONST:
945 case SYMBOL_REF:
946 case LABEL_REF:
947 case CODE_LABEL:
948 rx_print_operand_address (file, op);
949 break;
951 default:
952 gcc_unreachable ();
954 break;
958 /* Maybe convert an operand into its PID format. */
961 rx_maybe_pidify_operand (rtx op, int copy_to_reg)
963 if (rx_pid_data_operand (op) == PID_UNENCODED)
965 if (GET_CODE (op) == MEM)
967 rtx a = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), XEXP (op, 0));
968 op = replace_equiv_address (op, a);
970 else
972 op = gen_pid_addr (gen_rtx_REG (SImode, rx_pid_base_regnum ()), op);
975 if (copy_to_reg)
976 op = copy_to_mode_reg (GET_MODE (op), op);
978 return op;
981 /* Returns an assembler template for a move instruction. */
983 char *
984 rx_gen_move_template (rtx * operands, bool is_movu)
986 static char out_template [64];
987 const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
988 const char * src_template;
989 const char * dst_template;
990 rtx dest = operands[0];
991 rtx src = operands[1];
993 /* Decide which extension, if any, should be given to the move instruction. */
994 switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
996 case QImode:
997 /* The .B extension is not valid when
998 loading an immediate into a register. */
999 if (! REG_P (dest) || ! CONST_INT_P (src))
1000 extension = ".B";
1001 break;
1002 case HImode:
1003 if (! REG_P (dest) || ! CONST_INT_P (src))
1004 /* The .W extension is not valid when
1005 loading an immediate into a register. */
1006 extension = ".W";
1007 break;
1008 case DFmode:
1009 case DImode:
1010 case SFmode:
1011 case SImode:
1012 extension = ".L";
1013 break;
1014 case VOIDmode:
1015 /* This mode is used by constants. */
1016 break;
1017 default:
1018 debug_rtx (src);
1019 gcc_unreachable ();
1022 if (MEM_P (src) && rx_pid_data_operand (XEXP (src, 0)) == PID_UNENCODED)
1024 gcc_assert (GET_MODE (src) != DImode);
1025 gcc_assert (GET_MODE (src) != DFmode);
1027 src_template = "(%A1 - __pid_base)[%P1]";
1029 else if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
1031 gcc_assert (GET_MODE (src) != DImode);
1032 gcc_assert (GET_MODE (src) != DFmode);
1034 src_template = "%%gp(%A1)[%G1]";
1036 else
1037 src_template = "%1";
1039 if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
1041 gcc_assert (GET_MODE (dest) != DImode);
1042 gcc_assert (GET_MODE (dest) != DFmode);
1044 dst_template = "%%gp(%A0)[%G0]";
1046 else
1047 dst_template = "%0";
1049 if (GET_MODE (dest) == DImode || GET_MODE (dest) == DFmode)
1051 gcc_assert (! is_movu);
1053 if (REG_P (src) && REG_P (dest) && (REGNO (dest) == REGNO (src) + 1))
1054 sprintf (out_template, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0");
1055 else
1056 sprintf (out_template, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0");
1058 else
1059 sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
1060 extension, src_template, dst_template);
1061 return out_template;
1064 /* Return VALUE rounded up to the next ALIGNMENT boundary. */
1066 static inline unsigned int
1067 rx_round_up (unsigned int value, unsigned int alignment)
1069 alignment -= 1;
1070 return (value + alignment) & (~ alignment);
1073 /* Return the number of bytes in the argument registers
1074 occupied by an argument of type TYPE and mode MODE. */
1076 static unsigned int
1077 rx_function_arg_size (machine_mode mode, const_tree type)
1079 unsigned int num_bytes;
1081 num_bytes = (mode == BLKmode)
1082 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1083 return rx_round_up (num_bytes, UNITS_PER_WORD);
1086 #define NUM_ARG_REGS 4
1087 #define MAX_NUM_ARG_BYTES (NUM_ARG_REGS * UNITS_PER_WORD)
1089 /* Return an RTL expression describing the register holding a function
1090 parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
1091 be passed on the stack. CUM describes the previous parameters to the
1092 function and NAMED is false if the parameter is part of a variable
1093 parameter list, or the last named parameter before the start of a
1094 variable parameter list. */
1096 static rtx
1097 rx_function_arg (cumulative_args_t cum, machine_mode mode,
1098 const_tree type, bool named)
1100 unsigned int next_reg;
1101 unsigned int bytes_so_far = *get_cumulative_args (cum);
1102 unsigned int size;
1103 unsigned int rounded_size;
1105 /* An exploded version of rx_function_arg_size. */
1106 size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
1107 /* If the size is not known it cannot be passed in registers. */
1108 if (size < 1)
1109 return NULL_RTX;
1111 rounded_size = rx_round_up (size, UNITS_PER_WORD);
1113 /* Don't pass this arg via registers if there
1114 are insufficient registers to hold all of it. */
1115 if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES)
1116 return NULL_RTX;
1118 /* Unnamed arguments and the last named argument in a
1119 variadic function are always passed on the stack. */
1120 if (!named)
1121 return NULL_RTX;
1123 /* Structures must occupy an exact number of registers,
1124 otherwise they are passed on the stack. */
1125 if ((type == NULL || AGGREGATE_TYPE_P (type))
1126 && (size % UNITS_PER_WORD) != 0)
1127 return NULL_RTX;
1129 next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
1131 return gen_rtx_REG (mode, next_reg);
1134 static void
1135 rx_function_arg_advance (cumulative_args_t cum, machine_mode mode,
1136 const_tree type, bool named ATTRIBUTE_UNUSED)
1138 *get_cumulative_args (cum) += rx_function_arg_size (mode, type);
1141 static unsigned int
1142 rx_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED,
1143 const_tree type ATTRIBUTE_UNUSED)
1145 /* Older versions of the RX backend aligned all on-stack arguments
1146 to 32-bits. The RX C ABI however says that they should be
1147 aligned to their natural alignment. (See section 5.2.2 of the ABI). */
1148 if (TARGET_GCC_ABI)
1149 return STACK_BOUNDARY;
1151 if (type)
1153 if (DECL_P (type))
1154 return DECL_ALIGN (type);
1155 return TYPE_ALIGN (type);
1158 return PARM_BOUNDARY;
1161 /* Return an RTL describing where a function return value of type RET_TYPE
1162 is held. */
1164 static rtx
1165 rx_function_value (const_tree ret_type,
1166 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
1167 bool outgoing ATTRIBUTE_UNUSED)
1169 machine_mode mode = TYPE_MODE (ret_type);
1171 /* RX ABI specifies that small integer types are
1172 promoted to int when returned by a function. */
1173 if (GET_MODE_SIZE (mode) > 0
1174 && GET_MODE_SIZE (mode) < 4
1175 && ! COMPLEX_MODE_P (mode)
1176 && ! VECTOR_TYPE_P (ret_type)
1177 && ! VECTOR_MODE_P (mode)
1179 return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
1181 return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
1184 /* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
1185 regard to function returns as does TARGET_FUNCTION_VALUE. */
1187 static machine_mode
1188 rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
1189 machine_mode mode,
1190 int * punsignedp ATTRIBUTE_UNUSED,
1191 const_tree funtype ATTRIBUTE_UNUSED,
1192 int for_return)
1194 if (for_return != 1
1195 || GET_MODE_SIZE (mode) >= 4
1196 || COMPLEX_MODE_P (mode)
1197 || VECTOR_MODE_P (mode)
1198 || VECTOR_TYPE_P (type)
1199 || GET_MODE_SIZE (mode) < 1)
1200 return mode;
1202 return SImode;
1205 static bool
1206 rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
1208 HOST_WIDE_INT size;
1210 if (TYPE_MODE (type) != BLKmode
1211 && ! AGGREGATE_TYPE_P (type))
1212 return false;
1214 size = int_size_in_bytes (type);
1215 /* Large structs and those whose size is not an
1216 exact multiple of 4 are returned in memory. */
1217 return size < 1
1218 || size > 16
1219 || (size % UNITS_PER_WORD) != 0;
1222 static rtx
1223 rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
1224 int incoming ATTRIBUTE_UNUSED)
1226 return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM);
1229 static bool
1230 rx_return_in_msb (const_tree valtype)
1232 return TARGET_BIG_ENDIAN_DATA
1233 && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE);
1236 /* Returns true if the provided function has the specified attribute. */
1238 static inline bool
1239 has_func_attr (const_tree decl, const char * func_attr)
1241 if (decl == NULL_TREE)
1242 decl = current_function_decl;
1244 return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
1247 /* Returns true if the provided function has the "fast_interrupt" attribute. */
1249 static inline bool
1250 is_fast_interrupt_func (const_tree decl)
1252 return has_func_attr (decl, "fast_interrupt");
1255 /* Returns true if the provided function has the "interrupt" attribute. */
1257 static inline bool
1258 is_interrupt_func (const_tree decl)
1260 return has_func_attr (decl, "interrupt");
1263 /* Returns true if the provided function has the "naked" attribute. */
1265 static inline bool
1266 is_naked_func (const_tree decl)
1268 return has_func_attr (decl, "naked");
1271 static bool use_fixed_regs = false;
1273 static void
1274 rx_conditional_register_usage (void)
1276 static bool using_fixed_regs = false;
1278 if (TARGET_PID)
1280 rx_pid_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs;
1281 fixed_regs[rx_pid_base_regnum_val] = call_used_regs [rx_pid_base_regnum_val] = 1;
1284 if (rx_small_data_limit > 0)
1286 if (TARGET_PID)
1287 rx_gp_base_regnum_val = rx_pid_base_regnum_val - 1;
1288 else
1289 rx_gp_base_regnum_val = GP_BASE_REGNUM - rx_num_interrupt_regs;
1291 fixed_regs[rx_gp_base_regnum_val] = call_used_regs [rx_gp_base_regnum_val] = 1;
1294 if (use_fixed_regs != using_fixed_regs)
1296 static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
1297 static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
1299 if (use_fixed_regs)
1301 unsigned int r;
1303 memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
1304 memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
1306 /* This is for fast interrupt handlers. Any register in
1307 the range r10 to r13 (inclusive) that is currently
1308 marked as fixed is now a viable, call-used register. */
1309 for (r = 10; r <= 13; r++)
1310 if (fixed_regs[r])
1312 fixed_regs[r] = 0;
1313 call_used_regs[r] = 1;
1316 /* Mark r7 as fixed. This is just a hack to avoid
1317 altering the reg_alloc_order array so that the newly
1318 freed r10-r13 registers are the preferred registers. */
1319 fixed_regs[7] = call_used_regs[7] = 1;
1321 else
1323 /* Restore the normal register masks. */
1324 memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
1325 memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
1328 using_fixed_regs = use_fixed_regs;
1332 struct decl_chain
1334 tree fndecl;
1335 struct decl_chain * next;
1338 /* Stack of decls for which we have issued warnings. */
1339 static struct decl_chain * warned_decls = NULL;
1341 static void
1342 add_warned_decl (tree fndecl)
1344 struct decl_chain * warned = (struct decl_chain *) xmalloc (sizeof * warned);
1346 warned->fndecl = fndecl;
1347 warned->next = warned_decls;
1348 warned_decls = warned;
1351 /* Returns TRUE if FNDECL is on our list of warned about decls. */
1353 static bool
1354 already_warned (tree fndecl)
1356 struct decl_chain * warned;
1358 for (warned = warned_decls;
1359 warned != NULL;
1360 warned = warned->next)
1361 if (warned->fndecl == fndecl)
1362 return true;
1364 return false;
1367 /* Perform any actions necessary before starting to compile FNDECL.
1368 For the RX we use this to make sure that we have the correct
1369 set of register masks selected. If FNDECL is NULL then we are
1370 compiling top level things. */
1372 static void
1373 rx_set_current_function (tree fndecl)
1375 /* Remember the last target of rx_set_current_function. */
1376 static tree rx_previous_fndecl;
1377 bool prev_was_fast_interrupt;
1378 bool current_is_fast_interrupt;
1380 /* Only change the context if the function changes. This hook is called
1381 several times in the course of compiling a function, and we don't want
1382 to slow things down too much or call target_reinit when it isn't safe. */
1383 if (fndecl == rx_previous_fndecl)
1384 return;
1386 prev_was_fast_interrupt
1387 = rx_previous_fndecl
1388 ? is_fast_interrupt_func (rx_previous_fndecl) : false;
1390 current_is_fast_interrupt
1391 = fndecl ? is_fast_interrupt_func (fndecl) : false;
1393 if (prev_was_fast_interrupt != current_is_fast_interrupt)
1395 use_fixed_regs = current_is_fast_interrupt;
1396 target_reinit ();
1399 if (current_is_fast_interrupt && rx_warn_multiple_fast_interrupts)
1401 /* We do not warn about the first fast interrupt routine that
1402 we see. Instead we just push it onto the stack. */
1403 if (warned_decls == NULL)
1404 add_warned_decl (fndecl);
1406 /* Otherwise if this fast interrupt is one for which we have
1407 not already issued a warning, generate one and then push
1408 it onto the stack as well. */
1409 else if (! already_warned (fndecl))
1411 warning (0, "multiple fast interrupt routines seen: %qE and %qE",
1412 fndecl, warned_decls->fndecl);
1413 add_warned_decl (fndecl);
1417 rx_previous_fndecl = fndecl;
1420 /* Typical stack layout should looks like this after the function's prologue:
1423 -- ^
1424 | | \ |
1425 | | arguments saved | Increasing
1426 | | on the stack | addresses
1427 PARENT arg pointer -> | | /
1428 -------------------------- ---- -------------------
1429 CHILD |ret | return address
1431 | | \
1432 | | call saved
1433 | | registers
1434 | | /
1436 | | \
1437 | | local
1438 | | variables
1439 frame pointer -> | | /
1441 | | \
1442 | | outgoing | Decreasing
1443 | | arguments | addresses
1444 current stack pointer -> | | / |
1445 -------------------------- ---- ------------------ V
1446 | | */
1448 static unsigned int
1449 bit_count (unsigned int x)
1451 const unsigned int m1 = 0x55555555;
1452 const unsigned int m2 = 0x33333333;
1453 const unsigned int m4 = 0x0f0f0f0f;
1455 x -= (x >> 1) & m1;
1456 x = (x & m2) + ((x >> 2) & m2);
1457 x = (x + (x >> 4)) & m4;
1458 x += x >> 8;
1460 return (x + (x >> 16)) & 0x3f;
1463 #define MUST_SAVE_ACC_REGISTER \
1464 (TARGET_SAVE_ACC_REGISTER \
1465 && (is_interrupt_func (NULL_TREE) \
1466 || is_fast_interrupt_func (NULL_TREE)))
1468 /* Returns either the lowest numbered and highest numbered registers that
1469 occupy the call-saved area of the stack frame, if the registers are
1470 stored as a contiguous block, or else a bitmask of the individual
1471 registers if they are stored piecemeal.
1473 Also computes the size of the frame and the size of the outgoing
1474 arguments block (in bytes). */
1476 static void
1477 rx_get_stack_layout (unsigned int * lowest,
1478 unsigned int * highest,
1479 unsigned int * register_mask,
1480 unsigned int * frame_size,
1481 unsigned int * stack_size)
1483 unsigned int reg;
1484 unsigned int low;
1485 unsigned int high;
1486 unsigned int fixed_reg = 0;
1487 unsigned int save_mask;
1488 unsigned int pushed_mask;
1489 unsigned int unneeded_pushes;
1491 if (is_naked_func (NULL_TREE))
1493 /* Naked functions do not create their own stack frame.
1494 Instead the programmer must do that for us. */
1495 * lowest = 0;
1496 * highest = 0;
1497 * register_mask = 0;
1498 * frame_size = 0;
1499 * stack_size = 0;
1500 return;
1503 for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++)
1505 if ((df_regs_ever_live_p (reg)
1506 /* Always save all call clobbered registers inside non-leaf
1507 interrupt handlers, even if they are not live - they may
1508 be used in (non-interrupt aware) routines called from this one. */
1509 || (call_used_regs[reg]
1510 && is_interrupt_func (NULL_TREE)
1511 && ! crtl->is_leaf))
1512 && (! call_used_regs[reg]
1513 /* Even call clobbered registered must
1514 be pushed inside interrupt handlers. */
1515 || is_interrupt_func (NULL_TREE)
1516 /* Likewise for fast interrupt handlers, except registers r10 -
1517 r13. These are normally call-saved, but may have been set
1518 to call-used by rx_conditional_register_usage. If so then
1519 they can be used in the fast interrupt handler without
1520 saving them on the stack. */
1521 || (is_fast_interrupt_func (NULL_TREE)
1522 && ! IN_RANGE (reg, 10, 13))))
1524 if (low == 0)
1525 low = reg;
1526 high = reg;
1528 save_mask |= 1 << reg;
1531 /* Remember if we see a fixed register
1532 after having found the low register. */
1533 if (low != 0 && fixed_reg == 0 && fixed_regs [reg])
1534 fixed_reg = reg;
1537 /* If we have to save the accumulator register, make sure
1538 that at least two registers are pushed into the frame. */
1539 if (MUST_SAVE_ACC_REGISTER
1540 && bit_count (save_mask) < 2)
1542 save_mask |= (1 << 13) | (1 << 14);
1543 if (low == 0)
1544 low = 13;
1545 if (high == 0 || low == high)
1546 high = low + 1;
1549 /* Decide if it would be faster fill in the call-saved area of the stack
1550 frame using multiple PUSH instructions instead of a single PUSHM
1551 instruction.
1553 SAVE_MASK is a bitmask of the registers that must be stored in the
1554 call-save area. PUSHED_MASK is a bitmask of the registers that would
1555 be pushed into the area if we used a PUSHM instruction. UNNEEDED_PUSHES
1556 is a bitmask of those registers in pushed_mask that are not in
1557 save_mask.
1559 We use a simple heuristic that says that it is better to use
1560 multiple PUSH instructions if the number of unnecessary pushes is
1561 greater than the number of necessary pushes.
1563 We also use multiple PUSH instructions if there are any fixed registers
1564 between LOW and HIGH. The only way that this can happen is if the user
1565 has specified --fixed-<reg-name> on the command line and in such
1566 circumstances we do not want to touch the fixed registers at all.
1568 Note also that the code in the prologue/epilogue handlers will
1569 automatically merge multiple PUSHes of adjacent registers into a single
1570 PUSHM.
1572 FIXME: Is it worth improving this heuristic ? */
1573 pushed_mask = (-1 << low) & ~(-1 << (high + 1));
1574 unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
1576 if ((fixed_reg && fixed_reg <= high)
1577 || (optimize_function_for_speed_p (cfun)
1578 && bit_count (save_mask) < bit_count (unneeded_pushes)))
1580 /* Use multiple pushes. */
1581 * lowest = 0;
1582 * highest = 0;
1583 * register_mask = save_mask;
1585 else
1587 /* Use one push multiple instruction. */
1588 * lowest = low;
1589 * highest = high;
1590 * register_mask = 0;
1593 * frame_size = rx_round_up
1594 (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT);
1596 if (crtl->args.size > 0)
1597 * frame_size += rx_round_up
1598 (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT);
1600 * stack_size = rx_round_up
1601 (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT);
1604 /* Generate a PUSHM instruction that matches the given operands. */
1606 void
1607 rx_emit_stack_pushm (rtx * operands)
1609 HOST_WIDE_INT last_reg;
1610 rtx first_push;
1612 gcc_assert (CONST_INT_P (operands[0]));
1613 last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1;
1615 gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1616 first_push = XVECEXP (operands[1], 0, 1);
1617 gcc_assert (SET_P (first_push));
1618 first_push = SET_SRC (first_push);
1619 gcc_assert (REG_P (first_push));
1621 asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
1622 reg_names [REGNO (first_push) - last_reg],
1623 reg_names [REGNO (first_push)]);
1626 /* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate. */
1628 static rtx
1629 gen_rx_store_vector (unsigned int low, unsigned int high)
1631 unsigned int i;
1632 unsigned int count = (high - low) + 2;
1633 rtx vector;
1635 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1637 XVECEXP (vector, 0, 0) =
1638 gen_rtx_SET (stack_pointer_rtx,
1639 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1640 GEN_INT ((count - 1) * UNITS_PER_WORD)));
1642 for (i = 0; i < count - 1; i++)
1643 XVECEXP (vector, 0, i + 1) =
1644 gen_rtx_SET (gen_rtx_MEM (SImode,
1645 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1646 GEN_INT ((i + 1) * UNITS_PER_WORD))),
1647 gen_rtx_REG (SImode, high - i));
1648 return vector;
1651 /* Mark INSN as being frame related. If it is a PARALLEL
1652 then mark each element as being frame related as well. */
1654 static void
1655 mark_frame_related (rtx insn)
1657 RTX_FRAME_RELATED_P (insn) = 1;
1658 insn = PATTERN (insn);
1660 if (GET_CODE (insn) == PARALLEL)
1662 unsigned int i;
1664 for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
1665 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
1669 static bool
1670 ok_for_max_constant (HOST_WIDE_INT val)
1672 if (rx_max_constant_size == 0 || rx_max_constant_size == 4)
1673 /* If there is no constraint on the size of constants
1674 used as operands, then any value is legitimate. */
1675 return true;
1677 /* rx_max_constant_size specifies the maximum number
1678 of bytes that can be used to hold a signed value. */
1679 return IN_RANGE (val, (-1 << (rx_max_constant_size * 8)),
1680 ( 1 << (rx_max_constant_size * 8)));
1683 /* Generate an ADD of SRC plus VAL into DEST.
1684 Handles the case where VAL is too big for max_constant_value.
1685 Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true. */
1687 static void
1688 gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
1690 rtx insn;
1692 if (val == NULL_RTX || INTVAL (val) == 0)
1694 gcc_assert (dest != src);
1696 insn = emit_move_insn (dest, src);
1698 else if (ok_for_max_constant (INTVAL (val)))
1699 insn = emit_insn (gen_addsi3 (dest, src, val));
1700 else
1702 /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
1703 will not reject it. */
1704 val = gen_rtx_CONST (SImode, gen_rtx_UNSPEC (SImode, gen_rtvec (1, val), UNSPEC_CONST));
1705 insn = emit_insn (gen_addsi3 (dest, src, val));
1707 if (is_frame_related)
1708 /* We have to provide our own frame related note here
1709 as the dwarf2out code cannot be expected to grok
1710 our unspec. */
1711 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1712 gen_rtx_SET (dest, gen_rtx_PLUS (SImode, src, val)));
1713 return;
1716 if (is_frame_related)
1717 RTX_FRAME_RELATED_P (insn) = 1;
1720 static void
1721 push_regs (unsigned int high, unsigned int low)
1723 rtx insn;
1725 if (low == high)
1726 insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
1727 else
1728 insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD),
1729 gen_rx_store_vector (low, high)));
1730 mark_frame_related (insn);
1733 void
1734 rx_expand_prologue (void)
1736 unsigned int stack_size;
1737 unsigned int frame_size;
1738 unsigned int mask;
1739 unsigned int low;
1740 unsigned int high;
1741 unsigned int reg;
1743 /* Naked functions use their own, programmer provided prologues. */
1744 if (is_naked_func (NULL_TREE))
1745 return;
1747 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1749 if (flag_stack_usage_info)
1750 current_function_static_stack_size = frame_size + stack_size;
1752 /* If we use any of the callee-saved registers, save them now. */
1753 if (mask)
1755 /* Push registers in reverse order. */
1756 for (reg = CC_REGNUM; reg --;)
1757 if (mask & (1 << reg))
1759 low = high = reg;
1761 /* Look for a span of registers.
1762 Note - we do not have to worry about -Os and whether
1763 it is better to use a single, longer PUSHM as
1764 rx_get_stack_layout has already done that for us. */
1765 while (reg-- > 0)
1766 if ((mask & (1 << reg)) == 0)
1767 break;
1768 else
1769 --low;
1771 push_regs (high, low);
1772 if (reg == (unsigned) -1)
1773 break;
1776 else if (low)
1777 push_regs (high, low);
1779 if (MUST_SAVE_ACC_REGISTER)
1781 unsigned int acc_high, acc_low;
1783 /* Interrupt handlers have to preserve the accumulator
1784 register if so requested by the user. Use the first
1785 two pushed registers as intermediaries. */
1786 if (mask)
1788 acc_low = acc_high = 0;
1790 for (reg = 1; reg < CC_REGNUM; reg ++)
1791 if (mask & (1 << reg))
1793 if (acc_low == 0)
1794 acc_low = reg;
1795 else
1797 acc_high = reg;
1798 break;
1802 /* We have assumed that there are at least two registers pushed... */
1803 gcc_assert (acc_high != 0);
1805 /* Note - the bottom 16 bits of the accumulator are inaccessible.
1806 We just assume that they are zero. */
1807 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1808 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1809 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low)));
1810 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high)));
1812 else
1814 acc_low = low;
1815 acc_high = low + 1;
1817 /* We have assumed that there are at least two registers pushed... */
1818 gcc_assert (acc_high <= high);
1820 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1821 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1822 emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD),
1823 gen_rx_store_vector (acc_low, acc_high)));
1827 /* If needed, set up the frame pointer. */
1828 if (frame_pointer_needed)
1829 gen_safe_add (frame_pointer_rtx, stack_pointer_rtx,
1830 GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1832 /* Allocate space for the outgoing args.
1833 If the stack frame has not already been set up then handle this as well. */
1834 if (stack_size)
1836 if (frame_size)
1838 if (frame_pointer_needed)
1839 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx,
1840 GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1841 else
1842 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1843 GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)),
1844 true);
1846 else
1847 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1848 GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1850 else if (frame_size)
1852 if (! frame_pointer_needed)
1853 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1854 GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1855 else
1856 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
1857 false /* False because the epilogue will use the FP not the SP. */);
1861 static void
1862 add_vector_labels (FILE *file, const char *aname)
1864 tree vec_attr;
1865 tree val_attr;
1866 const char *vname = "vect";
1867 const char *s;
1868 int vnum;
1870 /* This node is for the vector/interrupt tag itself */
1871 vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl));
1872 if (!vec_attr)
1873 return;
1875 /* Now point it at the first argument */
1876 vec_attr = TREE_VALUE (vec_attr);
1878 /* Iterate through the arguments. */
1879 while (vec_attr)
1881 val_attr = TREE_VALUE (vec_attr);
1882 switch (TREE_CODE (val_attr))
1884 case STRING_CST:
1885 s = TREE_STRING_POINTER (val_attr);
1886 goto string_id_common;
1888 case IDENTIFIER_NODE:
1889 s = IDENTIFIER_POINTER (val_attr);
1891 string_id_common:
1892 if (strcmp (s, "$default") == 0)
1894 fprintf (file, "\t.global\t$tableentry$default$%s\n", vname);
1895 fprintf (file, "$tableentry$default$%s:\n", vname);
1897 else
1898 vname = s;
1899 break;
1901 case INTEGER_CST:
1902 vnum = TREE_INT_CST_LOW (val_attr);
1904 fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname);
1905 fprintf (file, "$tableentry$%d$%s:\n", vnum, vname);
1906 break;
1908 default:
1912 vec_attr = TREE_CHAIN (vec_attr);
1917 static void
1918 rx_output_function_prologue (FILE * file,
1919 HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
1921 add_vector_labels (file, "interrupt");
1922 add_vector_labels (file, "vector");
1924 if (is_fast_interrupt_func (NULL_TREE))
1925 asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
1927 if (is_interrupt_func (NULL_TREE))
1928 asm_fprintf (file, "\t; Note: Interrupt Handler\n");
1930 if (is_naked_func (NULL_TREE))
1931 asm_fprintf (file, "\t; Note: Naked Function\n");
1933 if (cfun->static_chain_decl != NULL)
1934 asm_fprintf (file, "\t; Note: Nested function declared "
1935 "inside another function.\n");
1937 if (crtl->calls_eh_return)
1938 asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n");
1941 /* Generate a POPM or RTSD instruction that matches the given operands. */
1943 void
1944 rx_emit_stack_popm (rtx * operands, bool is_popm)
1946 HOST_WIDE_INT stack_adjust;
1947 HOST_WIDE_INT last_reg;
1948 rtx first_push;
1950 gcc_assert (CONST_INT_P (operands[0]));
1951 stack_adjust = INTVAL (operands[0]);
1953 gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1954 last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3);
1956 first_push = XVECEXP (operands[1], 0, 1);
1957 gcc_assert (SET_P (first_push));
1958 first_push = SET_DEST (first_push);
1959 gcc_assert (REG_P (first_push));
1961 if (is_popm)
1962 asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n",
1963 reg_names [REGNO (first_push)],
1964 reg_names [REGNO (first_push) + last_reg]);
1965 else
1966 asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n",
1967 (int) stack_adjust,
1968 reg_names [REGNO (first_push)],
1969 reg_names [REGNO (first_push) + last_reg]);
1972 /* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate. */
1974 static rtx
1975 gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high)
1977 unsigned int i;
1978 unsigned int bias = 3;
1979 unsigned int count = (high - low) + bias;
1980 rtx vector;
1982 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1984 XVECEXP (vector, 0, 0) =
1985 gen_rtx_SET (stack_pointer_rtx,
1986 plus_constant (Pmode, stack_pointer_rtx, adjust));
1988 for (i = 0; i < count - 2; i++)
1989 XVECEXP (vector, 0, i + 1) =
1990 gen_rtx_SET (gen_rtx_REG (SImode, low + i),
1991 gen_rtx_MEM (SImode,
1992 i == 0 ? stack_pointer_rtx
1993 : plus_constant (Pmode, stack_pointer_rtx,
1994 i * UNITS_PER_WORD)));
1996 XVECEXP (vector, 0, count - 1) = ret_rtx;
1998 return vector;
2001 /* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate. */
2003 static rtx
2004 gen_rx_popm_vector (unsigned int low, unsigned int high)
2006 unsigned int i;
2007 unsigned int count = (high - low) + 2;
2008 rtx vector;
2010 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
2012 XVECEXP (vector, 0, 0) =
2013 gen_rtx_SET (stack_pointer_rtx,
2014 plus_constant (Pmode, stack_pointer_rtx,
2015 (count - 1) * UNITS_PER_WORD));
2017 for (i = 0; i < count - 1; i++)
2018 XVECEXP (vector, 0, i + 1) =
2019 gen_rtx_SET (gen_rtx_REG (SImode, low + i),
2020 gen_rtx_MEM (SImode,
2021 i == 0 ? stack_pointer_rtx
2022 : plus_constant (Pmode, stack_pointer_rtx,
2023 i * UNITS_PER_WORD)));
2025 return vector;
2028 /* Returns true if a simple return insn can be used. */
2030 bool
2031 rx_can_use_simple_return (void)
2033 unsigned int low;
2034 unsigned int high;
2035 unsigned int frame_size;
2036 unsigned int stack_size;
2037 unsigned int register_mask;
2039 if (is_naked_func (NULL_TREE)
2040 || is_fast_interrupt_func (NULL_TREE)
2041 || is_interrupt_func (NULL_TREE))
2042 return false;
2044 rx_get_stack_layout (& low, & high, & register_mask,
2045 & frame_size, & stack_size);
2047 return (register_mask == 0
2048 && (frame_size + stack_size) == 0
2049 && low == 0);
2052 static void
2053 pop_regs (unsigned int high, unsigned int low)
2055 if (high == low)
2056 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
2057 else
2058 emit_insn (gen_stack_popm (GEN_INT (((high - low) + 1) * UNITS_PER_WORD),
2059 gen_rx_popm_vector (low, high)));
2062 void
2063 rx_expand_epilogue (bool is_sibcall)
2065 unsigned int low;
2066 unsigned int high;
2067 unsigned int frame_size;
2068 unsigned int stack_size;
2069 unsigned int register_mask;
2070 unsigned int regs_size;
2071 unsigned int reg;
2072 unsigned HOST_WIDE_INT total_size;
2074 /* FIXME: We do not support indirect sibcalls at the moment becaause we
2075 cannot guarantee that the register holding the function address is a
2076 call-used register. If it is a call-saved register then the stack
2077 pop instructions generated in the epilogue will corrupt the address
2078 before it is used.
2080 Creating a new call-used-only register class works but then the
2081 reload pass gets stuck because it cannot always find a call-used
2082 register for spilling sibcalls.
2084 The other possible solution is for this pass to scan forward for the
2085 sibcall instruction (if it has been generated) and work out if it
2086 is an indirect sibcall using a call-saved register. If it is then
2087 the address can copied into a call-used register in this epilogue
2088 code and the sibcall instruction modified to use that register. */
2090 if (is_naked_func (NULL_TREE))
2092 gcc_assert (! is_sibcall);
2094 /* Naked functions use their own, programmer provided epilogues.
2095 But, in order to keep gcc happy we have to generate some kind of
2096 epilogue RTL. */
2097 emit_jump_insn (gen_naked_return ());
2098 return;
2101 rx_get_stack_layout (& low, & high, & register_mask,
2102 & frame_size, & stack_size);
2104 total_size = frame_size + stack_size;
2105 regs_size = ((high - low) + 1) * UNITS_PER_WORD;
2107 /* See if we are unable to use the special stack frame deconstruct and
2108 return instructions. In most cases we can use them, but the exceptions
2109 are:
2111 - Sibling calling functions deconstruct the frame but do not return to
2112 their caller. Instead they branch to their sibling and allow their
2113 return instruction to return to this function's parent.
2115 - Fast and normal interrupt handling functions have to use special
2116 return instructions.
2118 - Functions where we have pushed a fragmented set of registers into the
2119 call-save area must have the same set of registers popped. */
2120 if (is_sibcall
2121 || is_fast_interrupt_func (NULL_TREE)
2122 || is_interrupt_func (NULL_TREE)
2123 || register_mask)
2125 /* Cannot use the special instructions - deconstruct by hand. */
2126 if (total_size)
2127 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
2128 GEN_INT (total_size), false);
2130 if (MUST_SAVE_ACC_REGISTER)
2132 unsigned int acc_low, acc_high;
2134 /* Reverse the saving of the accumulator register onto the stack.
2135 Note we must adjust the saved "low" accumulator value as it
2136 is really the middle 32-bits of the accumulator. */
2137 if (register_mask)
2139 acc_low = acc_high = 0;
2141 for (reg = 1; reg < CC_REGNUM; reg ++)
2142 if (register_mask & (1 << reg))
2144 if (acc_low == 0)
2145 acc_low = reg;
2146 else
2148 acc_high = reg;
2149 break;
2152 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high)));
2153 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low)));
2155 else
2157 acc_low = low;
2158 acc_high = low + 1;
2159 emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD),
2160 gen_rx_popm_vector (acc_low, acc_high)));
2163 emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low),
2164 gen_rtx_REG (SImode, acc_low),
2165 GEN_INT (16)));
2166 emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low)));
2167 emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high)));
2170 if (register_mask)
2172 for (reg = 0; reg < CC_REGNUM; reg ++)
2173 if (register_mask & (1 << reg))
2175 low = high = reg;
2176 while (register_mask & (1 << high))
2177 high ++;
2178 pop_regs (high - 1, low);
2179 reg = high;
2182 else if (low)
2183 pop_regs (high, low);
2185 if (is_fast_interrupt_func (NULL_TREE))
2187 gcc_assert (! is_sibcall);
2188 emit_jump_insn (gen_fast_interrupt_return ());
2190 else if (is_interrupt_func (NULL_TREE))
2192 gcc_assert (! is_sibcall);
2193 emit_jump_insn (gen_exception_return ());
2195 else if (! is_sibcall)
2196 emit_jump_insn (gen_simple_return ());
2198 return;
2201 /* If we allocated space on the stack, free it now. */
2202 if (total_size)
2204 unsigned HOST_WIDE_INT rtsd_size;
2206 /* See if we can use the RTSD instruction. */
2207 rtsd_size = total_size + regs_size;
2208 if (rtsd_size < 1024 && (rtsd_size % 4) == 0)
2210 if (low)
2211 emit_jump_insn (gen_pop_and_return
2212 (GEN_INT (rtsd_size),
2213 gen_rx_rtsd_vector (rtsd_size, low, high)));
2214 else
2215 emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size)));
2217 return;
2220 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
2221 GEN_INT (total_size), false);
2224 if (low)
2225 emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size),
2226 gen_rx_rtsd_vector (regs_size,
2227 low, high)));
2228 else
2229 emit_jump_insn (gen_simple_return ());
2233 /* Compute the offset (in words) between FROM (arg pointer
2234 or frame pointer) and TO (frame pointer or stack pointer).
2235 See ASCII art comment at the start of rx_expand_prologue
2236 for more information. */
2239 rx_initial_elimination_offset (int from, int to)
2241 unsigned int low;
2242 unsigned int high;
2243 unsigned int frame_size;
2244 unsigned int stack_size;
2245 unsigned int mask;
2247 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
2249 if (from == ARG_POINTER_REGNUM)
2251 /* Extend the computed size of the stack frame to
2252 include the registers pushed in the prologue. */
2253 if (low)
2254 frame_size += ((high - low) + 1) * UNITS_PER_WORD;
2255 else
2256 frame_size += bit_count (mask) * UNITS_PER_WORD;
2258 /* Remember to include the return address. */
2259 frame_size += 1 * UNITS_PER_WORD;
2261 if (to == FRAME_POINTER_REGNUM)
2262 return frame_size;
2264 gcc_assert (to == STACK_POINTER_REGNUM);
2265 return frame_size + stack_size;
2268 gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM);
2269 return stack_size;
2272 /* Decide if a variable should go into one of the small data sections. */
2274 static bool
2275 rx_in_small_data (const_tree decl)
2277 int size;
2278 const char * section;
2280 if (rx_small_data_limit == 0)
2281 return false;
2283 if (TREE_CODE (decl) != VAR_DECL)
2284 return false;
2286 /* We do not put read-only variables into a small data area because
2287 they would be placed with the other read-only sections, far away
2288 from the read-write data sections, and we only have one small
2289 data area pointer.
2290 Similarly commons are placed in the .bss section which might be
2291 far away (and out of alignment with respect to) the .data section. */
2292 if (TREE_READONLY (decl) || DECL_COMMON (decl))
2293 return false;
2295 section = DECL_SECTION_NAME (decl);
2296 if (section)
2297 return (strcmp (section, "D_2") == 0) || (strcmp (section, "B_2") == 0);
2299 size = int_size_in_bytes (TREE_TYPE (decl));
2301 return (size > 0) && (size <= rx_small_data_limit);
2304 /* Return a section for X.
2305 The only special thing we do here is to honor small data. */
2307 static section *
2308 rx_select_rtx_section (machine_mode mode,
2309 rtx x,
2310 unsigned HOST_WIDE_INT align)
2312 if (rx_small_data_limit > 0
2313 && GET_MODE_SIZE (mode) <= rx_small_data_limit
2314 && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
2315 return sdata_section;
2317 return default_elf_select_rtx_section (mode, x, align);
2320 static section *
2321 rx_select_section (tree decl,
2322 int reloc,
2323 unsigned HOST_WIDE_INT align)
2325 if (rx_small_data_limit > 0)
2327 switch (categorize_decl_for_section (decl, reloc))
2329 case SECCAT_SDATA: return sdata_section;
2330 case SECCAT_SBSS: return sbss_section;
2331 case SECCAT_SRODATA:
2332 /* Fall through. We do not put small, read only
2333 data into the C_2 section because we are not
2334 using the C_2 section. We do not use the C_2
2335 section because it is located with the other
2336 read-only data sections, far away from the read-write
2337 data sections and we only have one small data
2338 pointer (r13). */
2339 default:
2340 break;
2344 /* If we are supporting the Renesas assembler
2345 we cannot use mergeable sections. */
2346 if (TARGET_AS100_SYNTAX)
2347 switch (categorize_decl_for_section (decl, reloc))
2349 case SECCAT_RODATA_MERGE_CONST:
2350 case SECCAT_RODATA_MERGE_STR_INIT:
2351 case SECCAT_RODATA_MERGE_STR:
2352 return readonly_data_section;
2354 default:
2355 break;
2358 return default_elf_select_section (decl, reloc, align);
2361 enum rx_builtin
2363 RX_BUILTIN_BRK,
2364 RX_BUILTIN_CLRPSW,
2365 RX_BUILTIN_INT,
2366 RX_BUILTIN_MACHI,
2367 RX_BUILTIN_MACLO,
2368 RX_BUILTIN_MULHI,
2369 RX_BUILTIN_MULLO,
2370 RX_BUILTIN_MVFACHI,
2371 RX_BUILTIN_MVFACMI,
2372 RX_BUILTIN_MVFC,
2373 RX_BUILTIN_MVTACHI,
2374 RX_BUILTIN_MVTACLO,
2375 RX_BUILTIN_MVTC,
2376 RX_BUILTIN_MVTIPL,
2377 RX_BUILTIN_RACW,
2378 RX_BUILTIN_REVW,
2379 RX_BUILTIN_RMPA,
2380 RX_BUILTIN_ROUND,
2381 RX_BUILTIN_SETPSW,
2382 RX_BUILTIN_WAIT,
2383 RX_BUILTIN_max
2386 static GTY(()) tree rx_builtins[(int) RX_BUILTIN_max];
2388 static void
2389 rx_init_builtins (void)
2391 #define ADD_RX_BUILTIN0(UC_NAME, LC_NAME, RET_TYPE) \
2392 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2393 add_builtin_function ("__builtin_rx_" LC_NAME, \
2394 build_function_type_list (RET_TYPE##_type_node, \
2395 NULL_TREE), \
2396 RX_BUILTIN_##UC_NAME, \
2397 BUILT_IN_MD, NULL, NULL_TREE)
2399 #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \
2400 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2401 add_builtin_function ("__builtin_rx_" LC_NAME, \
2402 build_function_type_list (RET_TYPE##_type_node, \
2403 ARG_TYPE##_type_node, \
2404 NULL_TREE), \
2405 RX_BUILTIN_##UC_NAME, \
2406 BUILT_IN_MD, NULL, NULL_TREE)
2408 #define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
2409 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2410 add_builtin_function ("__builtin_rx_" LC_NAME, \
2411 build_function_type_list (RET_TYPE##_type_node, \
2412 ARG_TYPE1##_type_node,\
2413 ARG_TYPE2##_type_node,\
2414 NULL_TREE), \
2415 RX_BUILTIN_##UC_NAME, \
2416 BUILT_IN_MD, NULL, NULL_TREE)
2418 #define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
2419 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2420 add_builtin_function ("__builtin_rx_" LC_NAME, \
2421 build_function_type_list (RET_TYPE##_type_node, \
2422 ARG_TYPE1##_type_node,\
2423 ARG_TYPE2##_type_node,\
2424 ARG_TYPE3##_type_node,\
2425 NULL_TREE), \
2426 RX_BUILTIN_##UC_NAME, \
2427 BUILT_IN_MD, NULL, NULL_TREE)
2429 ADD_RX_BUILTIN0 (BRK, "brk", void);
2430 ADD_RX_BUILTIN1 (CLRPSW, "clrpsw", void, integer);
2431 ADD_RX_BUILTIN1 (SETPSW, "setpsw", void, integer);
2432 ADD_RX_BUILTIN1 (INT, "int", void, integer);
2433 ADD_RX_BUILTIN2 (MACHI, "machi", void, intSI, intSI);
2434 ADD_RX_BUILTIN2 (MACLO, "maclo", void, intSI, intSI);
2435 ADD_RX_BUILTIN2 (MULHI, "mulhi", void, intSI, intSI);
2436 ADD_RX_BUILTIN2 (MULLO, "mullo", void, intSI, intSI);
2437 ADD_RX_BUILTIN0 (MVFACHI, "mvfachi", intSI);
2438 ADD_RX_BUILTIN0 (MVFACMI, "mvfacmi", intSI);
2439 ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void, intSI);
2440 ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void, intSI);
2441 ADD_RX_BUILTIN0 (RMPA, "rmpa", void);
2442 ADD_RX_BUILTIN1 (MVFC, "mvfc", intSI, integer);
2443 ADD_RX_BUILTIN2 (MVTC, "mvtc", void, integer, integer);
2444 ADD_RX_BUILTIN1 (MVTIPL, "mvtipl", void, integer);
2445 ADD_RX_BUILTIN1 (RACW, "racw", void, integer);
2446 ADD_RX_BUILTIN1 (ROUND, "round", intSI, float);
2447 ADD_RX_BUILTIN1 (REVW, "revw", intSI, intSI);
2448 ADD_RX_BUILTIN0 (WAIT, "wait", void);
2451 /* Return the RX builtin for CODE. */
2453 static tree
2454 rx_builtin_decl (unsigned code, bool initialize_p ATTRIBUTE_UNUSED)
2456 if (code >= RX_BUILTIN_max)
2457 return error_mark_node;
2459 return rx_builtins[code];
2462 static rtx
2463 rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
2465 if (reg && ! REG_P (arg))
2466 arg = force_reg (SImode, arg);
2468 emit_insn (gen_func (arg));
2470 return NULL_RTX;
2473 static rtx
2474 rx_expand_builtin_mvtc (tree exp)
2476 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2477 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2479 if (! CONST_INT_P (arg1))
2480 return NULL_RTX;
2482 if (! REG_P (arg2))
2483 arg2 = force_reg (SImode, arg2);
2485 emit_insn (gen_mvtc (arg1, arg2));
2487 return NULL_RTX;
2490 static rtx
2491 rx_expand_builtin_mvfc (tree t_arg, rtx target)
2493 rtx arg = expand_normal (t_arg);
2495 if (! CONST_INT_P (arg))
2496 return NULL_RTX;
2498 if (target == NULL_RTX)
2499 return NULL_RTX;
2501 if (! REG_P (target))
2502 target = force_reg (SImode, target);
2504 emit_insn (gen_mvfc (target, arg));
2506 return target;
2509 static rtx
2510 rx_expand_builtin_mvtipl (rtx arg)
2512 /* The RX610 does not support the MVTIPL instruction. */
2513 if (rx_cpu_type == RX610)
2514 return NULL_RTX;
2516 if (! CONST_INT_P (arg) || ! IN_RANGE (INTVAL (arg), 0, (1 << 4) - 1))
2517 return NULL_RTX;
2519 emit_insn (gen_mvtipl (arg));
2521 return NULL_RTX;
2524 static rtx
2525 rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
2527 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2528 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2530 if (! REG_P (arg1))
2531 arg1 = force_reg (SImode, arg1);
2533 if (! REG_P (arg2))
2534 arg2 = force_reg (SImode, arg2);
2536 emit_insn (gen_func (arg1, arg2));
2538 return NULL_RTX;
2541 static rtx
2542 rx_expand_int_builtin_1_arg (rtx arg,
2543 rtx target,
2544 rtx (* gen_func)(rtx, rtx),
2545 bool mem_ok)
2547 if (! REG_P (arg))
2548 if (!mem_ok || ! MEM_P (arg))
2549 arg = force_reg (SImode, arg);
2551 if (target == NULL_RTX || ! REG_P (target))
2552 target = gen_reg_rtx (SImode);
2554 emit_insn (gen_func (target, arg));
2556 return target;
2559 static rtx
2560 rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx))
2562 if (target == NULL_RTX || ! REG_P (target))
2563 target = gen_reg_rtx (SImode);
2565 emit_insn (gen_func (target));
2567 return target;
2570 static rtx
2571 rx_expand_builtin_round (rtx arg, rtx target)
2573 if ((! REG_P (arg) && ! MEM_P (arg))
2574 || GET_MODE (arg) != SFmode)
2575 arg = force_reg (SFmode, arg);
2577 if (target == NULL_RTX || ! REG_P (target))
2578 target = gen_reg_rtx (SImode);
2580 emit_insn (gen_lrintsf2 (target, arg));
2582 return target;
2585 static int
2586 valid_psw_flag (rtx op, const char *which)
2588 static int mvtc_inform_done = 0;
2590 if (GET_CODE (op) == CONST_INT)
2591 switch (INTVAL (op))
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;
2602 error ("__builtin_rx_%s takes 'C', 'Z', 'S', 'O', 'I', or 'U'", which);
2603 if (!mvtc_inform_done)
2604 error ("use __builtin_rx_mvtc (0, ... ) to write arbitrary values to PSW");
2605 mvtc_inform_done = 1;
2607 return 0;
2610 static rtx
2611 rx_expand_builtin (tree exp,
2612 rtx target,
2613 rtx subtarget ATTRIBUTE_UNUSED,
2614 machine_mode mode ATTRIBUTE_UNUSED,
2615 int ignore ATTRIBUTE_UNUSED)
2617 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2618 tree arg = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
2619 rtx op = arg ? expand_normal (arg) : NULL_RTX;
2620 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2622 switch (fcode)
2624 case RX_BUILTIN_BRK: emit_insn (gen_brk ()); return NULL_RTX;
2625 case RX_BUILTIN_CLRPSW:
2626 if (!valid_psw_flag (op, "clrpsw"))
2627 return NULL_RTX;
2628 return rx_expand_void_builtin_1_arg (op, gen_clrpsw, false);
2629 case RX_BUILTIN_SETPSW:
2630 if (!valid_psw_flag (op, "setpsw"))
2631 return NULL_RTX;
2632 return rx_expand_void_builtin_1_arg (op, gen_setpsw, false);
2633 case RX_BUILTIN_INT: return rx_expand_void_builtin_1_arg
2634 (op, gen_int, false);
2635 case RX_BUILTIN_MACHI: return rx_expand_builtin_mac (exp, gen_machi);
2636 case RX_BUILTIN_MACLO: return rx_expand_builtin_mac (exp, gen_maclo);
2637 case RX_BUILTIN_MULHI: return rx_expand_builtin_mac (exp, gen_mulhi);
2638 case RX_BUILTIN_MULLO: return rx_expand_builtin_mac (exp, gen_mullo);
2639 case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg
2640 (target, gen_mvfachi);
2641 case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg
2642 (target, gen_mvfacmi);
2643 case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg
2644 (op, gen_mvtachi, true);
2645 case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg
2646 (op, gen_mvtaclo, true);
2647 case RX_BUILTIN_RMPA:
2648 if (rx_allow_string_insns)
2649 emit_insn (gen_rmpa ());
2650 else
2651 error ("-mno-allow-string-insns forbids the generation of the RMPA instruction");
2652 return NULL_RTX;
2653 case RX_BUILTIN_MVFC: return rx_expand_builtin_mvfc (arg, target);
2654 case RX_BUILTIN_MVTC: return rx_expand_builtin_mvtc (exp);
2655 case RX_BUILTIN_MVTIPL: return rx_expand_builtin_mvtipl (op);
2656 case RX_BUILTIN_RACW: return rx_expand_void_builtin_1_arg
2657 (op, gen_racw, false);
2658 case RX_BUILTIN_ROUND: return rx_expand_builtin_round (op, target);
2659 case RX_BUILTIN_REVW: return rx_expand_int_builtin_1_arg
2660 (op, target, gen_revw, false);
2661 case RX_BUILTIN_WAIT: emit_insn (gen_wait ()); return NULL_RTX;
2663 default:
2664 internal_error ("bad builtin code");
2665 break;
2668 return NULL_RTX;
2671 /* Place an element into a constructor or destructor section.
2672 Like default_ctor_section_asm_out_constructor in varasm.c
2673 except that it uses .init_array (or .fini_array) and it
2674 handles constructor priorities. */
2676 static void
2677 rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
2679 section * s;
2681 if (priority != DEFAULT_INIT_PRIORITY)
2683 char buf[18];
2685 sprintf (buf, "%s.%.5u",
2686 is_ctor ? ".init_array" : ".fini_array",
2687 priority);
2688 s = get_section (buf, SECTION_WRITE, NULL_TREE);
2690 else if (is_ctor)
2691 s = ctors_section;
2692 else
2693 s = dtors_section;
2695 switch_to_section (s);
2696 assemble_align (POINTER_SIZE);
2697 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2700 static void
2701 rx_elf_asm_constructor (rtx symbol, int priority)
2703 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true);
2706 static void
2707 rx_elf_asm_destructor (rtx symbol, int priority)
2709 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
2712 /* Check "fast_interrupt", "interrupt" and "naked" attributes. */
2714 static tree
2715 rx_handle_func_attribute (tree * node,
2716 tree name,
2717 tree args ATTRIBUTE_UNUSED,
2718 int flags ATTRIBUTE_UNUSED,
2719 bool * no_add_attrs)
2721 gcc_assert (DECL_P (* node));
2723 if (TREE_CODE (* node) != FUNCTION_DECL)
2725 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2726 name);
2727 * no_add_attrs = true;
2730 /* FIXME: We ought to check for conflicting attributes. */
2732 /* FIXME: We ought to check that the interrupt and exception
2733 handler attributes have been applied to void functions. */
2734 return NULL_TREE;
2737 /* Check "vector" attribute. */
2739 static tree
2740 rx_handle_vector_attribute (tree * node,
2741 tree name,
2742 tree args,
2743 int flags ATTRIBUTE_UNUSED,
2744 bool * no_add_attrs)
2746 gcc_assert (DECL_P (* node));
2747 gcc_assert (args != NULL_TREE);
2749 if (TREE_CODE (* node) != FUNCTION_DECL)
2751 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2752 name);
2753 * no_add_attrs = true;
2756 return NULL_TREE;
2759 /* Table of RX specific attributes. */
2760 const struct attribute_spec rx_attribute_table[] =
2762 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
2763 affects_type_identity. */
2764 { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute,
2765 false },
2766 { "interrupt", 0, -1, true, false, false, rx_handle_func_attribute,
2767 false },
2768 { "naked", 0, 0, true, false, false, rx_handle_func_attribute,
2769 false },
2770 { "vector", 1, -1, true, false, false, rx_handle_vector_attribute,
2771 false },
2772 { NULL, 0, 0, false, false, false, NULL, false }
2775 /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */
2777 static void
2778 rx_override_options_after_change (void)
2780 static bool first_time = TRUE;
2782 if (first_time)
2784 /* If this is the first time through and the user has not disabled
2785 the use of RX FPU hardware then enable -ffinite-math-only,
2786 since the FPU instructions do not support NaNs and infinities. */
2787 if (TARGET_USE_FPU)
2788 flag_finite_math_only = 1;
2790 first_time = FALSE;
2792 else
2794 /* Alert the user if they are changing the optimization options
2795 to use IEEE compliant floating point arithmetic with RX FPU insns. */
2796 if (TARGET_USE_FPU
2797 && !flag_finite_math_only)
2798 warning (0, "RX FPU instructions do not support NaNs and infinities");
2802 static void
2803 rx_option_override (void)
2805 unsigned int i;
2806 cl_deferred_option *opt;
2807 vec<cl_deferred_option> *v = (vec<cl_deferred_option> *) rx_deferred_options;
2809 if (v)
2810 FOR_EACH_VEC_ELT (*v, i, opt)
2812 switch (opt->opt_index)
2814 case OPT_mint_register_:
2815 switch (opt->value)
2817 case 4:
2818 fixed_regs[10] = call_used_regs [10] = 1;
2819 /* Fall through. */
2820 case 3:
2821 fixed_regs[11] = call_used_regs [11] = 1;
2822 /* Fall through. */
2823 case 2:
2824 fixed_regs[12] = call_used_regs [12] = 1;
2825 /* Fall through. */
2826 case 1:
2827 fixed_regs[13] = call_used_regs [13] = 1;
2828 /* Fall through. */
2829 case 0:
2830 rx_num_interrupt_regs = opt->value;
2831 break;
2832 default:
2833 rx_num_interrupt_regs = 0;
2834 /* Error message already given because rx_handle_option
2835 returned false. */
2836 break;
2838 break;
2840 default:
2841 gcc_unreachable ();
2845 /* This target defaults to strict volatile bitfields. */
2846 if (flag_strict_volatile_bitfields < 0 && abi_version_at_least(2))
2847 flag_strict_volatile_bitfields = 1;
2849 rx_override_options_after_change ();
2851 /* These values are bytes, not log. */
2852 if (align_jumps == 0 && ! optimize_size)
2853 align_jumps = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 4 : 8);
2854 if (align_loops == 0 && ! optimize_size)
2855 align_loops = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 4 : 8);
2856 if (align_labels == 0 && ! optimize_size)
2857 align_labels = ((rx_cpu_type == RX100 || rx_cpu_type == RX200) ? 4 : 8);
2861 static bool
2862 rx_allocate_stack_slots_for_args (void)
2864 /* Naked functions should not allocate stack slots for arguments. */
2865 return ! is_naked_func (NULL_TREE);
2868 static bool
2869 rx_func_attr_inlinable (const_tree decl)
2871 return ! is_fast_interrupt_func (decl)
2872 && ! is_interrupt_func (decl)
2873 && ! is_naked_func (decl);
2876 static bool
2877 rx_warn_func_return (tree decl)
2879 /* Naked functions are implemented entirely in assembly, including the
2880 return sequence, so suppress warnings about this. */
2881 return !is_naked_func (decl);
2884 /* Return nonzero if it is ok to make a tail-call to DECL,
2885 a function_decl or NULL if this is an indirect call, using EXP */
2887 static bool
2888 rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
2890 /* Do not allow indirect tailcalls. The
2891 sibcall patterns do not support them. */
2892 if (decl == NULL)
2893 return false;
2895 /* Never tailcall from inside interrupt handlers or naked functions. */
2896 if (is_fast_interrupt_func (NULL_TREE)
2897 || is_interrupt_func (NULL_TREE)
2898 || is_naked_func (NULL_TREE))
2899 return false;
2901 return true;
2904 static void
2905 rx_file_start (void)
2907 if (! TARGET_AS100_SYNTAX)
2908 default_file_start ();
2911 static bool
2912 rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
2914 /* The packed attribute overrides the MS behaviour. */
2915 return ! TYPE_PACKED (record_type);
2918 /* Returns true if X a legitimate constant for an immediate
2919 operand on the RX. X is already known to satisfy CONSTANT_P. */
2921 bool
2922 rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2924 switch (GET_CODE (x))
2926 case CONST:
2927 x = XEXP (x, 0);
2929 if (GET_CODE (x) == PLUS)
2931 if (! CONST_INT_P (XEXP (x, 1)))
2932 return false;
2934 /* GCC would not pass us CONST_INT + CONST_INT so we
2935 know that we have {SYMBOL|LABEL} + CONST_INT. */
2936 x = XEXP (x, 0);
2937 gcc_assert (! CONST_INT_P (x));
2940 switch (GET_CODE (x))
2942 case LABEL_REF:
2943 case SYMBOL_REF:
2944 return true;
2946 case UNSPEC:
2947 return XINT (x, 1) == UNSPEC_CONST || XINT (x, 1) == UNSPEC_PID_ADDR;
2949 default:
2950 /* FIXME: Can this ever happen ? */
2951 gcc_unreachable ();
2953 break;
2955 case LABEL_REF:
2956 case SYMBOL_REF:
2957 return true;
2958 case CONST_DOUBLE:
2959 return (rx_max_constant_size == 0 || rx_max_constant_size == 4);
2960 case CONST_VECTOR:
2961 return false;
2962 default:
2963 gcc_assert (CONST_INT_P (x));
2964 break;
2967 return ok_for_max_constant (INTVAL (x));
2970 static int
2971 rx_address_cost (rtx addr, machine_mode mode ATTRIBUTE_UNUSED,
2972 addr_space_t as ATTRIBUTE_UNUSED, bool speed)
2974 rtx a, b;
2976 if (GET_CODE (addr) != PLUS)
2977 return COSTS_N_INSNS (1);
2979 a = XEXP (addr, 0);
2980 b = XEXP (addr, 1);
2982 if (REG_P (a) && REG_P (b))
2983 /* Try to discourage REG+REG addressing as it keeps two registers live. */
2984 return COSTS_N_INSNS (4);
2986 if (speed)
2987 /* [REG+OFF] is just as fast as [REG]. */
2988 return COSTS_N_INSNS (1);
2990 if (CONST_INT_P (b)
2991 && ((INTVAL (b) > 128) || INTVAL (b) < -127))
2992 /* Try to discourage REG + <large OFF> when optimizing for size. */
2993 return COSTS_N_INSNS (2);
2995 return COSTS_N_INSNS (1);
2998 static bool
2999 rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
3001 /* We can always eliminate to the frame pointer.
3002 We can eliminate to the stack pointer unless a frame
3003 pointer is needed. */
3005 return to == FRAME_POINTER_REGNUM
3006 || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed);
3010 static void
3011 rx_trampoline_template (FILE * file)
3013 /* Output assembler code for a block containing the constant
3014 part of a trampoline, leaving space for the variable parts.
3016 On the RX, (where r8 is the static chain regnum) the trampoline
3017 looks like:
3019 mov #<static chain value>, r8
3020 mov #<function's address>, r9
3021 jmp r9
3023 In big-endian-data-mode however instructions are read into the CPU
3024 4 bytes at a time. These bytes are then swapped around before being
3025 passed to the decoder. So...we must partition our trampoline into
3026 4 byte packets and swap these packets around so that the instruction
3027 reader will reverse the process. But, in order to avoid splitting
3028 the 32-bit constants across these packet boundaries, (making inserting
3029 them into the constructed trampoline very difficult) we have to pad the
3030 instruction sequence with NOP insns. ie:
3034 mov.l #<...>, r8
3037 mov.l #<...>, r9
3038 jmp r9
3040 nop */
3042 if (! TARGET_BIG_ENDIAN_DATA)
3044 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM);
3045 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM);
3046 asm_fprintf (file, "\tjmp\tr%d\n", TRAMPOLINE_TEMP_REGNUM);
3048 else
3050 char r8 = '0' + STATIC_CHAIN_REGNUM;
3051 char r9 = '0' + TRAMPOLINE_TEMP_REGNUM;
3053 if (TARGET_AS100_SYNTAX)
3055 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r8);
3056 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
3057 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r9);
3058 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
3059 asm_fprintf (file, "\t.BYTE 003H, 003H, 00%cH, 07fH\n", r9);
3061 else
3063 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r8);
3064 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
3065 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r9);
3066 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
3067 asm_fprintf (file, "\t.byte 0x03, 0x03, 0x0%c, 0x7f\n", r9);
3072 static void
3073 rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
3075 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3077 emit_block_move (tramp, assemble_trampoline_template (),
3078 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3080 if (TARGET_BIG_ENDIAN_DATA)
3082 emit_move_insn (adjust_address (tramp, SImode, 4), chain);
3083 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
3085 else
3087 emit_move_insn (adjust_address (tramp, SImode, 2), chain);
3088 emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr);
3092 static int
3093 rx_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3094 reg_class_t regclass ATTRIBUTE_UNUSED,
3095 bool in)
3097 return (in ? 2 : 0) + REGISTER_MOVE_COST (mode, regclass, regclass);
3100 /* Convert a CC_MODE to the set of flags that it represents. */
3102 static unsigned int
3103 flags_from_mode (machine_mode mode)
3105 switch (mode)
3107 case CC_ZSmode:
3108 return CC_FLAG_S | CC_FLAG_Z;
3109 case CC_ZSOmode:
3110 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
3111 case CC_ZSCmode:
3112 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C;
3113 case CCmode:
3114 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C;
3115 case CC_Fmode:
3116 return CC_FLAG_FP;
3117 default:
3118 gcc_unreachable ();
3122 /* Convert a set of flags to a CC_MODE that can implement it. */
3124 static machine_mode
3125 mode_from_flags (unsigned int f)
3127 if (f & CC_FLAG_FP)
3128 return CC_Fmode;
3129 if (f & CC_FLAG_O)
3131 if (f & CC_FLAG_C)
3132 return CCmode;
3133 else
3134 return CC_ZSOmode;
3136 else if (f & CC_FLAG_C)
3137 return CC_ZSCmode;
3138 else
3139 return CC_ZSmode;
3142 /* Convert an RTX_CODE to the set of flags needed to implement it.
3143 This assumes an integer comparison. */
3145 static unsigned int
3146 flags_from_code (enum rtx_code code)
3148 switch (code)
3150 case LT:
3151 case GE:
3152 return CC_FLAG_S;
3153 case GT:
3154 case LE:
3155 return CC_FLAG_S | CC_FLAG_O | CC_FLAG_Z;
3156 case GEU:
3157 case LTU:
3158 return CC_FLAG_C;
3159 case GTU:
3160 case LEU:
3161 return CC_FLAG_C | CC_FLAG_Z;
3162 case EQ:
3163 case NE:
3164 return CC_FLAG_Z;
3165 default:
3166 gcc_unreachable ();
3170 /* Return a CC_MODE of which both M1 and M2 are subsets. */
3172 static machine_mode
3173 rx_cc_modes_compatible (machine_mode m1, machine_mode m2)
3175 unsigned f;
3177 /* Early out for identical modes. */
3178 if (m1 == m2)
3179 return m1;
3181 /* There's no valid combination for FP vs non-FP. */
3182 f = flags_from_mode (m1) | flags_from_mode (m2);
3183 if (f & CC_FLAG_FP)
3184 return VOIDmode;
3186 /* Otherwise, see what mode can implement all the flags. */
3187 return mode_from_flags (f);
3190 /* Return the minimal CC mode needed to implement (CMP_CODE X Y). */
3192 machine_mode
3193 rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y)
3195 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
3196 return CC_Fmode;
3198 if (y != const0_rtx)
3199 return CCmode;
3201 return mode_from_flags (flags_from_code (cmp_code));
3204 /* Split the conditional branch. Emit (COMPARE C1 C2) into CC_REG with
3205 CC_MODE, and use that in branches based on that compare. */
3207 void
3208 rx_split_cbranch (machine_mode cc_mode, enum rtx_code cmp1,
3209 rtx c1, rtx c2, rtx label)
3211 rtx flags, x;
3213 flags = gen_rtx_REG (cc_mode, CC_REG);
3214 x = gen_rtx_COMPARE (cc_mode, c1, c2);
3215 x = gen_rtx_SET (flags, x);
3216 emit_insn (x);
3218 x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
3219 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
3220 x = gen_rtx_SET (pc_rtx, x);
3221 emit_jump_insn (x);
3224 /* A helper function for matching parallels that set the flags. */
3226 bool
3227 rx_match_ccmode (rtx insn, machine_mode cc_mode)
3229 rtx op1, flags;
3230 machine_mode flags_mode;
3232 gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2);
3234 op1 = XVECEXP (PATTERN (insn), 0, 1);
3235 gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE);
3237 flags = SET_DEST (op1);
3238 flags_mode = GET_MODE (flags);
3240 if (GET_MODE (SET_SRC (op1)) != flags_mode)
3241 return false;
3242 if (GET_MODE_CLASS (flags_mode) != MODE_CC)
3243 return false;
3245 /* Ensure that the mode of FLAGS is compatible with CC_MODE. */
3246 if (flags_from_mode (flags_mode) & ~flags_from_mode (cc_mode))
3247 return false;
3249 return true;
3253 rx_align_for_label (rtx lab, int uses_threshold)
3255 /* This is a simple heuristic to guess when an alignment would not be useful
3256 because the delay due to the inserted NOPs would be greater than the delay
3257 due to the misaligned branch. If uses_threshold is zero then the alignment
3258 is always useful. */
3259 if (LABEL_P (lab) && LABEL_NUSES (lab) < uses_threshold)
3260 return 0;
3262 if (optimize_size)
3263 return 0;
3264 /* These values are log, not bytes. */
3265 if (rx_cpu_type == RX100 || rx_cpu_type == RX200)
3266 return 2; /* 4 bytes */
3267 return 3; /* 8 bytes */
3270 static int
3271 rx_max_skip_for_label (rtx_insn *lab)
3273 int opsize;
3274 rtx_insn *op;
3276 if (optimize_size)
3277 return 0;
3279 if (lab == NULL)
3280 return 0;
3282 op = lab;
3285 op = next_nonnote_nondebug_insn (op);
3287 while (op && (LABEL_P (op)
3288 || (INSN_P (op) && GET_CODE (PATTERN (op)) == USE)));
3289 if (!op)
3290 return 0;
3292 opsize = get_attr_length (op);
3293 if (opsize >= 0 && opsize < 8)
3294 return opsize - 1;
3295 return 0;
3298 /* Compute the real length of the extending load-and-op instructions. */
3301 rx_adjust_insn_length (rtx_insn *insn, int current_length)
3303 rtx extend, mem, offset;
3304 bool zero;
3305 int factor;
3307 if (!INSN_P (insn))
3308 return current_length;
3310 switch (INSN_CODE (insn))
3312 default:
3313 return current_length;
3315 case CODE_FOR_plussi3_zero_extendhi:
3316 case CODE_FOR_andsi3_zero_extendhi:
3317 case CODE_FOR_iorsi3_zero_extendhi:
3318 case CODE_FOR_xorsi3_zero_extendhi:
3319 case CODE_FOR_divsi3_zero_extendhi:
3320 case CODE_FOR_udivsi3_zero_extendhi:
3321 case CODE_FOR_minussi3_zero_extendhi:
3322 case CODE_FOR_smaxsi3_zero_extendhi:
3323 case CODE_FOR_sminsi3_zero_extendhi:
3324 case CODE_FOR_multsi3_zero_extendhi:
3325 case CODE_FOR_comparesi3_zero_extendhi:
3326 zero = true;
3327 factor = 2;
3328 break;
3330 case CODE_FOR_plussi3_sign_extendhi:
3331 case CODE_FOR_andsi3_sign_extendhi:
3332 case CODE_FOR_iorsi3_sign_extendhi:
3333 case CODE_FOR_xorsi3_sign_extendhi:
3334 case CODE_FOR_divsi3_sign_extendhi:
3335 case CODE_FOR_udivsi3_sign_extendhi:
3336 case CODE_FOR_minussi3_sign_extendhi:
3337 case CODE_FOR_smaxsi3_sign_extendhi:
3338 case CODE_FOR_sminsi3_sign_extendhi:
3339 case CODE_FOR_multsi3_sign_extendhi:
3340 case CODE_FOR_comparesi3_sign_extendhi:
3341 zero = false;
3342 factor = 2;
3343 break;
3345 case CODE_FOR_plussi3_zero_extendqi:
3346 case CODE_FOR_andsi3_zero_extendqi:
3347 case CODE_FOR_iorsi3_zero_extendqi:
3348 case CODE_FOR_xorsi3_zero_extendqi:
3349 case CODE_FOR_divsi3_zero_extendqi:
3350 case CODE_FOR_udivsi3_zero_extendqi:
3351 case CODE_FOR_minussi3_zero_extendqi:
3352 case CODE_FOR_smaxsi3_zero_extendqi:
3353 case CODE_FOR_sminsi3_zero_extendqi:
3354 case CODE_FOR_multsi3_zero_extendqi:
3355 case CODE_FOR_comparesi3_zero_extendqi:
3356 zero = true;
3357 factor = 1;
3358 break;
3360 case CODE_FOR_plussi3_sign_extendqi:
3361 case CODE_FOR_andsi3_sign_extendqi:
3362 case CODE_FOR_iorsi3_sign_extendqi:
3363 case CODE_FOR_xorsi3_sign_extendqi:
3364 case CODE_FOR_divsi3_sign_extendqi:
3365 case CODE_FOR_udivsi3_sign_extendqi:
3366 case CODE_FOR_minussi3_sign_extendqi:
3367 case CODE_FOR_smaxsi3_sign_extendqi:
3368 case CODE_FOR_sminsi3_sign_extendqi:
3369 case CODE_FOR_multsi3_sign_extendqi:
3370 case CODE_FOR_comparesi3_sign_extendqi:
3371 zero = false;
3372 factor = 1;
3373 break;
3376 /* We are expecting: (SET (REG) (<OP> (REG) (<EXTEND> (MEM)))). */
3377 extend = single_set (insn);
3378 gcc_assert (extend != NULL_RTX);
3380 extend = SET_SRC (extend);
3381 if (GET_CODE (XEXP (extend, 0)) == ZERO_EXTEND
3382 || GET_CODE (XEXP (extend, 0)) == SIGN_EXTEND)
3383 extend = XEXP (extend, 0);
3384 else
3385 extend = XEXP (extend, 1);
3387 gcc_assert ((zero && (GET_CODE (extend) == ZERO_EXTEND))
3388 || (! zero && (GET_CODE (extend) == SIGN_EXTEND)));
3390 mem = XEXP (extend, 0);
3391 gcc_checking_assert (MEM_P (mem));
3392 if (REG_P (XEXP (mem, 0)))
3393 return (zero && factor == 1) ? 2 : 3;
3395 /* We are expecting: (MEM (PLUS (REG) (CONST_INT))). */
3396 gcc_checking_assert (GET_CODE (XEXP (mem, 0)) == PLUS);
3397 gcc_checking_assert (REG_P (XEXP (XEXP (mem, 0), 0)));
3399 offset = XEXP (XEXP (mem, 0), 1);
3400 gcc_checking_assert (GET_CODE (offset) == CONST_INT);
3402 if (IN_RANGE (INTVAL (offset), 0, 255 * factor))
3403 return (zero && factor == 1) ? 3 : 4;
3405 return (zero && factor == 1) ? 4 : 5;
3408 static bool
3409 rx_narrow_volatile_bitfield (void)
3411 return true;
3414 static bool
3415 rx_ok_to_inline (tree caller, tree callee)
3417 /* Do not inline functions with local variables
3418 into a naked CALLER - naked function have no stack frame and
3419 locals need a frame in order to have somewhere to live.
3421 Unfortunately we have no way to determine the presence of
3422 local variables in CALLEE, so we have to be cautious and
3423 assume that there might be some there.
3425 We do allow inlining when CALLEE has the "inline" type
3426 modifier or the "always_inline" or "gnu_inline" attributes. */
3427 return lookup_attribute ("naked", DECL_ATTRIBUTES (caller)) == NULL_TREE
3428 || DECL_DECLARED_INLINE_P (callee)
3429 || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE
3430 || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee)) != NULL_TREE;
3433 static bool
3434 rx_enable_lra (void)
3436 return TARGET_ENABLE_LRA;
3440 #undef TARGET_NARROW_VOLATILE_BITFIELD
3441 #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
3443 #undef TARGET_CAN_INLINE_P
3444 #define TARGET_CAN_INLINE_P rx_ok_to_inline
3446 #undef TARGET_ASM_JUMP_ALIGN_MAX_SKIP
3447 #define TARGET_ASM_JUMP_ALIGN_MAX_SKIP rx_max_skip_for_label
3448 #undef TARGET_ASM_LOOP_ALIGN_MAX_SKIP
3449 #define TARGET_ASM_LOOP_ALIGN_MAX_SKIP rx_max_skip_for_label
3450 #undef TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP
3451 #define TARGET_LABEL_ALIGN_AFTER_BARRIER_MAX_SKIP rx_max_skip_for_label
3452 #undef TARGET_ASM_LABEL_ALIGN_MAX_SKIP
3453 #define TARGET_ASM_LABEL_ALIGN_MAX_SKIP rx_max_skip_for_label
3455 #undef TARGET_FUNCTION_VALUE
3456 #define TARGET_FUNCTION_VALUE rx_function_value
3458 #undef TARGET_RETURN_IN_MSB
3459 #define TARGET_RETURN_IN_MSB rx_return_in_msb
3461 #undef TARGET_IN_SMALL_DATA_P
3462 #define TARGET_IN_SMALL_DATA_P rx_in_small_data
3464 #undef TARGET_RETURN_IN_MEMORY
3465 #define TARGET_RETURN_IN_MEMORY rx_return_in_memory
3467 #undef TARGET_HAVE_SRODATA_SECTION
3468 #define TARGET_HAVE_SRODATA_SECTION true
3470 #undef TARGET_ASM_SELECT_RTX_SECTION
3471 #define TARGET_ASM_SELECT_RTX_SECTION rx_select_rtx_section
3473 #undef TARGET_ASM_SELECT_SECTION
3474 #define TARGET_ASM_SELECT_SECTION rx_select_section
3476 #undef TARGET_INIT_BUILTINS
3477 #define TARGET_INIT_BUILTINS rx_init_builtins
3479 #undef TARGET_BUILTIN_DECL
3480 #define TARGET_BUILTIN_DECL rx_builtin_decl
3482 #undef TARGET_EXPAND_BUILTIN
3483 #define TARGET_EXPAND_BUILTIN rx_expand_builtin
3485 #undef TARGET_ASM_CONSTRUCTOR
3486 #define TARGET_ASM_CONSTRUCTOR rx_elf_asm_constructor
3488 #undef TARGET_ASM_DESTRUCTOR
3489 #define TARGET_ASM_DESTRUCTOR rx_elf_asm_destructor
3491 #undef TARGET_STRUCT_VALUE_RTX
3492 #define TARGET_STRUCT_VALUE_RTX rx_struct_value_rtx
3494 #undef TARGET_ATTRIBUTE_TABLE
3495 #define TARGET_ATTRIBUTE_TABLE rx_attribute_table
3497 #undef TARGET_ASM_FILE_START
3498 #define TARGET_ASM_FILE_START rx_file_start
3500 #undef TARGET_MS_BITFIELD_LAYOUT_P
3501 #define TARGET_MS_BITFIELD_LAYOUT_P rx_is_ms_bitfield_layout
3503 #undef TARGET_LEGITIMATE_ADDRESS_P
3504 #define TARGET_LEGITIMATE_ADDRESS_P rx_is_legitimate_address
3506 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
3507 #define TARGET_MODE_DEPENDENT_ADDRESS_P rx_mode_dependent_address_p
3509 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
3510 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS rx_allocate_stack_slots_for_args
3512 #undef TARGET_ASM_FUNCTION_PROLOGUE
3513 #define TARGET_ASM_FUNCTION_PROLOGUE rx_output_function_prologue
3515 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
3516 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable
3518 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
3519 #define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall
3521 #undef TARGET_FUNCTION_ARG
3522 #define TARGET_FUNCTION_ARG rx_function_arg
3524 #undef TARGET_FUNCTION_ARG_ADVANCE
3525 #define TARGET_FUNCTION_ARG_ADVANCE rx_function_arg_advance
3527 #undef TARGET_FUNCTION_ARG_BOUNDARY
3528 #define TARGET_FUNCTION_ARG_BOUNDARY rx_function_arg_boundary
3530 #undef TARGET_SET_CURRENT_FUNCTION
3531 #define TARGET_SET_CURRENT_FUNCTION rx_set_current_function
3533 #undef TARGET_ASM_INTEGER
3534 #define TARGET_ASM_INTEGER rx_assemble_integer
3536 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
3537 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
3539 #undef TARGET_MAX_ANCHOR_OFFSET
3540 #define TARGET_MAX_ANCHOR_OFFSET 32
3542 #undef TARGET_ADDRESS_COST
3543 #define TARGET_ADDRESS_COST rx_address_cost
3545 #undef TARGET_CAN_ELIMINATE
3546 #define TARGET_CAN_ELIMINATE rx_can_eliminate
3548 #undef TARGET_CONDITIONAL_REGISTER_USAGE
3549 #define TARGET_CONDITIONAL_REGISTER_USAGE rx_conditional_register_usage
3551 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3552 #define TARGET_ASM_TRAMPOLINE_TEMPLATE rx_trampoline_template
3554 #undef TARGET_TRAMPOLINE_INIT
3555 #define TARGET_TRAMPOLINE_INIT rx_trampoline_init
3557 #undef TARGET_PRINT_OPERAND
3558 #define TARGET_PRINT_OPERAND rx_print_operand
3560 #undef TARGET_PRINT_OPERAND_ADDRESS
3561 #define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address
3563 #undef TARGET_CC_MODES_COMPATIBLE
3564 #define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible
3566 #undef TARGET_MEMORY_MOVE_COST
3567 #define TARGET_MEMORY_MOVE_COST rx_memory_move_cost
3569 #undef TARGET_OPTION_OVERRIDE
3570 #define TARGET_OPTION_OVERRIDE rx_option_override
3572 #undef TARGET_PROMOTE_FUNCTION_MODE
3573 #define TARGET_PROMOTE_FUNCTION_MODE rx_promote_function_mode
3575 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
3576 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rx_override_options_after_change
3578 #undef TARGET_FLAGS_REGNUM
3579 #define TARGET_FLAGS_REGNUM CC_REG
3581 #undef TARGET_LEGITIMATE_CONSTANT_P
3582 #define TARGET_LEGITIMATE_CONSTANT_P rx_is_legitimate_constant
3584 #undef TARGET_LEGITIMIZE_ADDRESS
3585 #define TARGET_LEGITIMIZE_ADDRESS rx_legitimize_address
3587 #undef TARGET_WARN_FUNC_RETURN
3588 #define TARGET_WARN_FUNC_RETURN rx_warn_func_return
3590 #undef TARGET_LRA_P
3591 #define TARGET_LRA_P rx_enable_lra
3593 struct gcc_target targetm = TARGET_INITIALIZER;
3595 #include "gt-rx.h"