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