1 /* Subroutines used for code generation on Renesas RX processors.
2 Copyright (C) 2008-2024 Free Software Foundation, Inc.
3 Contributed by Red Hat.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GCC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
23 * Re-enable memory-to-memory copies and fix up reload. */
25 #define IN_TARGET_CODE 1
29 #include "coretypes.h"
34 #include "stringpool.h"
42 #include "diagnostic-core.h"
44 #include "stor-layout.h"
51 #include "langhooks.h"
55 /* This file should be included last. */
56 #include "target-def.h"
58 static unsigned int rx_gp_base_regnum_val
= INVALID_REGNUM
;
59 static unsigned int rx_pid_base_regnum_val
= INVALID_REGNUM
;
60 static unsigned int rx_num_interrupt_regs
;
63 rx_gp_base_regnum (void)
65 if (rx_gp_base_regnum_val
== INVALID_REGNUM
)
67 return rx_gp_base_regnum_val
;
71 rx_pid_base_regnum (void)
73 if (rx_pid_base_regnum_val
== INVALID_REGNUM
)
75 return rx_pid_base_regnum_val
;
78 /* Find a SYMBOL_REF in a "standard" MEM address and return its decl. */
81 rx_decl_for_addr (rtx op
)
83 if (GET_CODE (op
) == MEM
)
85 if (GET_CODE (op
) == CONST
)
87 while (GET_CODE (op
) == PLUS
)
89 if (GET_CODE (op
) == SYMBOL_REF
)
90 return SYMBOL_REF_DECL (op
);
94 static void rx_print_operand (FILE *, rtx
, int);
96 #define CC_FLAG_S (1 << 0)
97 #define CC_FLAG_Z (1 << 1)
98 #define CC_FLAG_O (1 << 2)
99 #define CC_FLAG_C (1 << 3)
100 #define CC_FLAG_FP (1 << 4) /* Fake, to differentiate CC_Fmode. */
102 static unsigned int flags_from_mode (machine_mode mode
);
103 static unsigned int flags_from_code (enum rtx_code code
);
105 /* Return true if OP is a reference to an object in a PID data area. */
109 PID_NOT_PID
= 0, /* The object is not in the PID data area. */
110 PID_ENCODED
, /* The object is in the PID data area. */
111 PID_UNENCODED
/* The object will be placed in the PID data area, but it has not been placed there yet. */
115 rx_pid_data_operand (rtx op
)
122 if (GET_CODE (op
) == PLUS
123 && GET_CODE (XEXP (op
, 0)) == REG
124 && GET_CODE (XEXP (op
, 1)) == CONST
125 && GET_CODE (XEXP (XEXP (op
, 1), 0)) == UNSPEC
)
128 op_decl
= rx_decl_for_addr (op
);
132 if (TREE_READONLY (op_decl
))
133 return PID_UNENCODED
;
137 /* Sigh, some special cases. */
138 if (GET_CODE (op
) == SYMBOL_REF
139 || GET_CODE (op
) == LABEL_REF
)
140 return PID_UNENCODED
;
147 rx_legitimize_address (rtx x
,
148 rtx oldx ATTRIBUTE_UNUSED
,
149 machine_mode mode ATTRIBUTE_UNUSED
)
151 if (rx_pid_data_operand (x
) == PID_UNENCODED
)
153 rtx rv
= gen_pid_addr (gen_rtx_REG (SImode
, rx_pid_base_regnum ()), x
);
157 if (GET_CODE (x
) == PLUS
158 && GET_CODE (XEXP (x
, 0)) == PLUS
159 && REG_P (XEXP (XEXP (x
, 0), 0))
160 && REG_P (XEXP (x
, 1)))
161 return force_reg (SImode
, x
);
166 /* Return true if OP is a reference to an object in a small data area. */
169 rx_small_data_operand (rtx op
)
171 if (rx_small_data_limit
== 0)
174 if (GET_CODE (op
) == SYMBOL_REF
)
175 return SYMBOL_REF_SMALL_P (op
);
181 rx_is_legitimate_address (machine_mode mode
, rtx x
,
182 bool strict ATTRIBUTE_UNUSED
,
183 code_helper
= ERROR_MARK
)
185 if (RTX_OK_FOR_BASE (x
, strict
))
186 /* Register Indirect. */
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
);
197 switch (rx_pid_data_operand (x
))
207 if (GET_CODE (x
) == PLUS
)
209 rtx arg1
= XEXP (x
, 0);
210 rtx arg2
= XEXP (x
, 1);
211 rtx index
= NULL_RTX
;
213 if (REG_P (arg1
) && RTX_OK_FOR_BASE (arg1
, strict
))
215 else if (REG_P (arg2
) && RTX_OK_FOR_BASE (arg2
, strict
))
220 switch (GET_CODE (index
))
224 /* Register Relative: REG + INT.
225 Only positive, mode-aligned, mode-sized
226 displacements are allowed. */
227 HOST_WIDE_INT val
= INTVAL (index
);
233 switch (GET_MODE_SIZE (mode
))
236 case 4: factor
= 4; break;
237 case 2: factor
= 2; break;
238 case 1: factor
= 1; break;
241 if (val
> (65535 * factor
))
243 return (val
% factor
) == 0;
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
);
253 /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
254 Factor has to equal the mode size, REG has to be valid. */
257 factor
= XEXP (index
, 1);
258 index
= XEXP (index
, 0);
261 && RTX_OK_FOR_BASE (index
, strict
)
262 && CONST_INT_P (factor
)
263 && GET_MODE_SIZE (mode
) == INTVAL (factor
);
271 /* Small data area accesses turn into register relative offsets. */
272 return rx_small_data_operand (x
);
275 /* Returns TRUE for simple memory addresses, ie ones
276 that do not involve register indirect addressing
277 or pre/post increment/decrement. */
280 rx_is_restricted_memory_address (rtx mem
, machine_mode mode
)
282 if (! rx_is_legitimate_address
283 (mode
, mem
, reload_in_progress
|| reload_completed
))
286 switch (GET_CODE (mem
))
289 /* Simple memory addresses are OK. */
293 return RX_REG_P (SUBREG_REG (mem
));
303 /* Only allow REG+INT addressing. */
304 base
= XEXP (mem
, 0);
305 index
= XEXP (mem
, 1);
307 if (! RX_REG_P (base
) || ! CONST_INT_P (index
))
310 return IN_RANGE (INTVAL (index
), 0, (0x10000 * GET_MODE_SIZE (mode
)) - 1);
314 /* Can happen when small data is being supported.
315 Assume that it will be resolved into GP+INT. */
323 /* Implement TARGET_MODE_DEPENDENT_ADDRESS_P. */
326 rx_mode_dependent_address_p (const_rtx addr
, addr_space_t as ATTRIBUTE_UNUSED
)
328 if (GET_CODE (addr
) == CONST
)
329 addr
= XEXP (addr
, 0);
331 switch (GET_CODE (addr
))
333 /* --REG and REG++ only work in SImode. */
340 if (! REG_P (XEXP (addr
, 0)))
343 addr
= XEXP (addr
, 1);
345 switch (GET_CODE (addr
))
348 /* REG+REG only works in SImode. */
352 /* REG+INT is only mode independent if INT is a
353 multiple of 4, positive and will fit into 16-bits. */
354 if (((INTVAL (addr
) & 3) == 0)
355 && IN_RANGE (INTVAL (addr
), 4, 0xfffc))
364 /* REG+REG*SCALE is always mode dependent. */
368 /* Not recognized, so treat as mode dependent. */
376 /* These are all mode independent. */
380 /* Everything else is unrecognized,
381 so treat as mode dependent. */
386 /* A C compound statement to output to stdio stream FILE the
387 assembler syntax for an instruction operand that is a memory
388 reference whose address is ADDR. */
391 rx_print_operand_address (FILE * file
, machine_mode
/*mode*/, rtx addr
)
393 switch (GET_CODE (addr
))
397 rx_print_operand (file
, addr
, 0);
402 fprintf (file
, "[-");
403 rx_print_operand (file
, XEXP (addr
, 0), 0);
409 rx_print_operand (file
, XEXP (addr
, 0), 0);
410 fprintf (file
, "+]");
415 rtx arg1
= XEXP (addr
, 0);
416 rtx arg2
= XEXP (addr
, 1);
419 if (REG_P (arg1
) && RTX_OK_FOR_BASE (arg1
, true))
420 base
= arg1
, index
= arg2
;
421 else if (REG_P (arg2
) && RTX_OK_FOR_BASE (arg2
, true))
422 base
= arg2
, index
= arg1
;
425 rx_print_operand (file
, arg1
, 0);
426 fprintf (file
, " + ");
427 rx_print_operand (file
, arg2
, 0);
431 if (REG_P (index
) || GET_CODE (index
) == MULT
)
434 rx_print_operand (file
, index
, 'A');
437 else /* GET_CODE (index) == CONST_INT */
439 rx_print_operand (file
, index
, 'A');
442 rx_print_operand (file
, base
, 0);
448 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
450 addr
= XEXP (addr
, 0);
451 gcc_assert (XINT (addr
, 1) == UNSPEC_CONST
);
453 addr
= XVECEXP (addr
, 0, 0);
454 gcc_assert (CONST_INT_P (addr
));
456 output_addr_const (file
, addr
);
460 output_addr_const (file
, XEXP (addr
, 0));
464 addr
= XVECEXP (addr
, 0, 0);
471 output_addr_const (file
, addr
);
477 rx_print_integer (FILE * file
, HOST_WIDE_INT val
)
480 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, val
);
484 ? "0%" HOST_WIDE_INT_PRINT
"xH" : HOST_WIDE_INT_PRINT_HEX
,
489 rx_assemble_integer (rtx x
, unsigned int size
, int is_aligned
)
491 const char * op
= integer_asm_op (size
, is_aligned
);
493 if (! CONST_INT_P (x
))
494 return default_assemble_integer (x
, size
, is_aligned
);
498 fputs (op
, asm_out_file
);
500 rx_print_integer (asm_out_file
, INTVAL (x
));
501 fputc ('\n', asm_out_file
);
506 /* Handles the insertion of a single operand into the assembler output.
507 The %<letter> directives supported are:
509 %A Print an operand without a leading # character.
510 %B Print an integer comparison name.
511 %C Print a control register name.
512 %F Print a condition code flag name.
513 %G Register used for small-data-area addressing
514 %H Print high part of a DImode register, integer or address.
515 %L Print low part of a DImode register, integer or address.
516 %N Print the negation of the immediate value.
517 %P Register used for PID addressing
518 %Q If the operand is a MEM, then correctly generate
519 register indirect or register relative addressing.
520 %R Like %Q but for zero-extending loads. */
523 rx_print_operand (FILE * file
, rtx op
, int letter
)
525 bool unsigned_load
= false;
526 bool print_hash
= true;
529 && ((GET_CODE (op
) == CONST
530 && GET_CODE (XEXP (op
, 0)) == UNSPEC
)
531 || GET_CODE (op
) == UNSPEC
))
540 /* Print an operand without a leading #. */
544 switch (GET_CODE (op
))
548 output_addr_const (file
, op
);
551 fprintf (file
, "%ld", (long) INTVAL (op
));
554 rx_print_operand (file
, op
, 0);
561 enum rtx_code code
= GET_CODE (op
);
562 machine_mode mode
= GET_MODE (XEXP (op
, 0));
565 if (mode
== CC_Fmode
)
567 /* C flag is undefined, and O flag carries unordered. None of the
568 branch combinations that include O use it helpfully. */
595 unsigned int flags
= flags_from_mode (mode
);
600 ret
= (flags
& CC_FLAG_O
? "lt" : "n");
603 ret
= (flags
& CC_FLAG_O
? "ge" : "pz");
632 gcc_checking_assert ((flags_from_code (code
) & ~flags
) == 0);
639 gcc_assert (CONST_INT_P (op
));
642 case CTRLREG_PSW
: fprintf (file
, "psw"); break;
643 case CTRLREG_PC
: fprintf (file
, "pc"); break;
644 case CTRLREG_USP
: fprintf (file
, "usp"); break;
645 case CTRLREG_FPSW
: fprintf (file
, "fpsw"); break;
646 case CTRLREG_BPSW
: fprintf (file
, "bpsw"); break;
647 case CTRLREG_BPC
: fprintf (file
, "bpc"); break;
648 case CTRLREG_ISP
: fprintf (file
, "isp"); break;
649 case CTRLREG_FINTV
: fprintf (file
, "fintv"); break;
650 case CTRLREG_INTB
: fprintf (file
, "intb"); break;
652 warning (0, "unrecognized control register number: %d"
653 " - using %<psw%>", (int) INTVAL (op
));
654 fprintf (file
, "psw");
660 gcc_assert (CONST_INT_P (op
));
663 case 0: case 'c': case 'C': fprintf (file
, "C"); break;
664 case 1: case 'z': case 'Z': fprintf (file
, "Z"); break;
665 case 2: case 's': case 'S': fprintf (file
, "S"); break;
666 case 3: case 'o': case 'O': fprintf (file
, "O"); break;
667 case 8: case 'i': case 'I': fprintf (file
, "I"); break;
668 case 9: case 'u': case 'U': fprintf (file
, "U"); break;
675 fprintf (file
, "%s", reg_names
[rx_gp_base_regnum ()]);
679 switch (GET_CODE (op
))
682 fprintf (file
, "%s", reg_names
[REGNO (op
) + (WORDS_BIG_ENDIAN
? 0 : 1)]);
686 HOST_WIDE_INT v
= INTVAL (op
);
689 /* Trickery to avoid problems with shifting 32 bits at a time. */
692 rx_print_integer (file
, v
);
697 rx_print_integer (file
, CONST_DOUBLE_HIGH (op
));
700 if (! WORDS_BIG_ENDIAN
)
701 op
= adjust_address (op
, SImode
, 4);
702 output_address (GET_MODE (op
), XEXP (op
, 0));
710 switch (GET_CODE (op
))
713 fprintf (file
, "%s", reg_names
[REGNO (op
) + (WORDS_BIG_ENDIAN
? 1 : 0)]);
717 rx_print_integer (file
, INTVAL (op
) & 0xffffffff);
721 rx_print_integer (file
, CONST_DOUBLE_LOW (op
));
724 if (WORDS_BIG_ENDIAN
)
725 op
= adjust_address (op
, SImode
, 4);
726 output_address (GET_MODE (op
), XEXP (op
, 0));
734 gcc_assert (CONST_INT_P (op
));
736 rx_print_integer (file
, - INTVAL (op
));
740 fprintf (file
, "%s", reg_names
[rx_pid_base_regnum ()]);
744 gcc_assert (GET_MODE_SIZE (GET_MODE (op
)) <= 4);
745 unsigned_load
= true;
750 HOST_WIDE_INT offset
;
757 else if (GET_CODE (op
) == PLUS
)
761 if (REG_P (XEXP (op
, 0)))
763 displacement
= XEXP (op
, 1);
768 displacement
= XEXP (op
, 0);
770 gcc_assert (REG_P (op
));
773 gcc_assert (CONST_INT_P (displacement
));
774 offset
= INTVAL (displacement
);
775 gcc_assert (offset
>= 0);
777 fprintf (file
, "%ld", offset
);
783 rx_print_operand (file
, op
, 0);
784 fprintf (file
, "].");
786 switch (GET_MODE_SIZE (GET_MODE (mem
)))
789 gcc_assert (offset
<= 65535 * 1);
790 fprintf (file
, unsigned_load
? "UB" : "B");
793 gcc_assert (offset
% 2 == 0);
794 gcc_assert (offset
<= 65535 * 2);
795 fprintf (file
, unsigned_load
? "UW" : "W");
798 gcc_assert (offset
% 4 == 0);
799 gcc_assert (offset
<= 65535 * 4);
811 if (GET_CODE (op
) == CONST
812 && GET_CODE (XEXP (op
, 0)) == UNSPEC
)
814 else if (GET_CODE (op
) == CONST
815 && GET_CODE (XEXP (op
, 0)) == PLUS
816 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == UNSPEC
817 && GET_CODE (XEXP (XEXP (op
, 0), 1)) == CONST_INT
)
822 rx_print_operand (file
, XEXP (XEXP (op
, 0), 0), 'A');
823 fprintf (file
, " + ");
824 output_addr_const (file
, XEXP (XEXP (op
, 0), 1));
829 switch (GET_CODE (op
))
832 /* Should be the scaled part of an
833 indexed register indirect address. */
835 rtx base
= XEXP (op
, 0);
836 rtx index
= XEXP (op
, 1);
838 /* Check for a swaped index register and scaling factor.
839 Not sure if this can happen, but be prepared to handle it. */
840 if (CONST_INT_P (base
) && REG_P (index
))
847 gcc_assert (REG_P (base
));
848 gcc_assert (REGNO (base
) < FIRST_PSEUDO_REGISTER
);
849 gcc_assert (CONST_INT_P (index
));
850 /* Do not try to verify the value of the scalar as it is based
851 on the mode of the MEM not the mode of the MULT. (Which
852 will always be SImode). */
853 fprintf (file
, "%s", reg_names
[REGNO (base
)]);
858 output_address (GET_MODE (op
), XEXP (op
, 0));
862 output_address (VOIDmode
, op
);
866 gcc_assert (REGNO (op
) < FIRST_PSEUDO_REGISTER
);
867 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
871 gcc_assert (subreg_regno (op
) < FIRST_PSEUDO_REGISTER
);
872 fprintf (file
, "%s", reg_names
[subreg_regno (op
)]);
875 /* This will only be single precision.... */
880 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (op
), val
);
883 fprintf (file
, TARGET_AS100_SYNTAX
? "0%lxH" : "0x%lx", val
);
890 rx_print_integer (file
, INTVAL (op
));
894 switch (XINT (op
, 1))
896 case UNSPEC_PID_ADDR
:
902 sym
= XVECEXP (op
, 0, 0);
905 if (GET_CODE (sym
) == PLUS
)
910 output_addr_const (file
, sym
);
914 output_addr_const (file
, add
);
916 fprintf (file
, "-__pid_base");
927 rx_print_operand_address (file
, VOIDmode
, op
);
937 /* Maybe convert an operand into its PID format. */
940 rx_maybe_pidify_operand (rtx op
, int copy_to_reg
)
942 if (rx_pid_data_operand (op
) == PID_UNENCODED
)
944 if (GET_CODE (op
) == MEM
)
946 rtx a
= gen_pid_addr (gen_rtx_REG (SImode
, rx_pid_base_regnum ()), XEXP (op
, 0));
947 op
= replace_equiv_address (op
, a
);
951 op
= gen_pid_addr (gen_rtx_REG (SImode
, rx_pid_base_regnum ()), op
);
955 op
= copy_to_mode_reg (GET_MODE (op
), op
);
960 /* Returns an assembler template for a move instruction. */
963 rx_gen_move_template (rtx
* operands
, bool is_movu
)
965 static char out_template
[64];
966 const char * extension
= TARGET_AS100_SYNTAX
? ".L" : "";
967 const char * src_template
;
968 const char * dst_template
;
969 rtx dest
= operands
[0];
970 rtx src
= operands
[1];
972 /* Decide which extension, if any, should be given to the move instruction. */
973 switch (CONST_INT_P (src
) ? GET_MODE (dest
) : GET_MODE (src
))
976 /* The .B extension is not valid when
977 loading an immediate into a register. */
978 if (! REG_P (dest
) || ! CONST_INT_P (src
))
982 if (! REG_P (dest
) || ! CONST_INT_P (src
))
983 /* The .W extension is not valid when
984 loading an immediate into a register. */
994 /* This mode is used by constants. */
1001 if (MEM_P (src
) && rx_pid_data_operand (XEXP (src
, 0)) == PID_UNENCODED
)
1003 gcc_assert (GET_MODE (src
) != DImode
);
1004 gcc_assert (GET_MODE (src
) != DFmode
);
1006 src_template
= "(%A1 - __pid_base)[%P1]";
1008 else if (MEM_P (src
) && rx_small_data_operand (XEXP (src
, 0)))
1010 gcc_assert (GET_MODE (src
) != DImode
);
1011 gcc_assert (GET_MODE (src
) != DFmode
);
1013 src_template
= "%%gp(%A1)[%G1]";
1016 src_template
= "%1";
1018 if (MEM_P (dest
) && rx_small_data_operand (XEXP (dest
, 0)))
1020 gcc_assert (GET_MODE (dest
) != DImode
);
1021 gcc_assert (GET_MODE (dest
) != DFmode
);
1023 dst_template
= "%%gp(%A0)[%G0]";
1026 dst_template
= "%0";
1028 if (GET_MODE (dest
) == DImode
|| GET_MODE (dest
) == DFmode
)
1030 gcc_assert (! is_movu
);
1032 if (REG_P (src
) && REG_P (dest
) && (REGNO (dest
) == REGNO (src
) + 1))
1033 sprintf (out_template
, "mov.L\t%%H1, %%H0 ! mov.L\t%%1, %%0");
1035 sprintf (out_template
, "mov.L\t%%1, %%0 ! mov.L\t%%H1, %%H0");
1038 sprintf (out_template
, "%s%s\t%s, %s", is_movu
? "movu" : "mov",
1039 extension
, src_template
, dst_template
);
1040 return out_template
;
1043 /* Return VALUE rounded up to the next ALIGNMENT boundary. */
1045 static inline unsigned int
1046 rx_round_up (unsigned int value
, unsigned int alignment
)
1049 return (value
+ alignment
) & (~ alignment
);
1052 /* Return the number of bytes in the argument registers
1053 occupied by an argument of type TYPE and mode MODE. */
1056 rx_function_arg_size (machine_mode mode
, const_tree type
)
1058 unsigned int num_bytes
;
1060 num_bytes
= (mode
== BLKmode
)
1061 ? int_size_in_bytes (type
) : GET_MODE_SIZE (mode
);
1062 return rx_round_up (num_bytes
, UNITS_PER_WORD
);
1065 #define NUM_ARG_REGS 4
1066 #define MAX_NUM_ARG_BYTES (NUM_ARG_REGS * UNITS_PER_WORD)
1068 /* Return an RTL expression describing the register holding function
1069 argument ARG or NULL_RTX if the parameter should be passed on the
1070 stack. CUM describes the previous parameters to the function. */
1073 rx_function_arg (cumulative_args_t cum
, const function_arg_info
&arg
)
1075 unsigned int next_reg
;
1076 unsigned int bytes_so_far
= *get_cumulative_args (cum
);
1078 unsigned int rounded_size
;
1080 size
= arg
.promoted_size_in_bytes ();
1081 /* If the size is not known it cannot be passed in registers. */
1085 rounded_size
= rx_round_up (size
, UNITS_PER_WORD
);
1087 /* Don't pass this arg via registers if there
1088 are insufficient registers to hold all of it. */
1089 if (rounded_size
+ bytes_so_far
> MAX_NUM_ARG_BYTES
)
1092 /* Unnamed arguments and the last named argument in a
1093 variadic function are always passed on the stack. */
1097 /* Structures must occupy an exact number of registers,
1098 otherwise they are passed on the stack. */
1099 if ((arg
.type
== NULL
|| AGGREGATE_TYPE_P (arg
.type
))
1100 && (size
% UNITS_PER_WORD
) != 0)
1103 next_reg
= (bytes_so_far
/ UNITS_PER_WORD
) + 1;
1105 return gen_rtx_REG (arg
.mode
, next_reg
);
1109 rx_function_arg_advance (cumulative_args_t cum
,
1110 const function_arg_info
&arg
)
1112 *get_cumulative_args (cum
) += rx_function_arg_size (arg
.mode
, arg
.type
);
1116 rx_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED
,
1117 const_tree type ATTRIBUTE_UNUSED
)
1119 /* Older versions of the RX backend aligned all on-stack arguments
1120 to 32-bits. The RX C ABI however says that they should be
1121 aligned to their natural alignment. (See section 5.2.2 of the ABI). */
1123 return STACK_BOUNDARY
;
1128 return DECL_ALIGN (type
);
1129 return TYPE_ALIGN (type
);
1132 return PARM_BOUNDARY
;
1135 /* Return an RTL describing where a function return value of type RET_TYPE
1139 rx_function_value (const_tree ret_type
,
1140 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
1141 bool outgoing ATTRIBUTE_UNUSED
)
1143 machine_mode mode
= TYPE_MODE (ret_type
);
1145 /* RX ABI specifies that small integer types are
1146 promoted to int when returned by a function. */
1147 if (GET_MODE_SIZE (mode
) > 0
1148 && GET_MODE_SIZE (mode
) < 4
1149 && ! COMPLEX_MODE_P (mode
)
1150 && ! VECTOR_TYPE_P (ret_type
)
1151 && ! VECTOR_MODE_P (mode
)
1153 return gen_rtx_REG (SImode
, FUNC_RETURN_REGNUM
);
1155 return gen_rtx_REG (mode
, FUNC_RETURN_REGNUM
);
1158 /* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
1159 regard to function returns as does TARGET_FUNCTION_VALUE. */
1162 rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED
,
1164 int * punsignedp ATTRIBUTE_UNUSED
,
1165 const_tree funtype ATTRIBUTE_UNUSED
,
1169 || GET_MODE_SIZE (mode
) >= 4
1170 || COMPLEX_MODE_P (mode
)
1171 || VECTOR_MODE_P (mode
)
1172 || VECTOR_TYPE_P (type
)
1173 || GET_MODE_SIZE (mode
) < 1)
1180 rx_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
1184 if (TYPE_MODE (type
) != BLKmode
1185 && ! AGGREGATE_TYPE_P (type
))
1188 size
= int_size_in_bytes (type
);
1189 /* Large structs and those whose size is not an
1190 exact multiple of 4 are returned in memory. */
1193 || (size
% UNITS_PER_WORD
) != 0;
1197 rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED
,
1198 int incoming ATTRIBUTE_UNUSED
)
1200 return gen_rtx_REG (Pmode
, STRUCT_VAL_REGNUM
);
1204 rx_return_in_msb (const_tree valtype
)
1206 return TARGET_BIG_ENDIAN_DATA
1207 && (AGGREGATE_TYPE_P (valtype
) || TREE_CODE (valtype
) == COMPLEX_TYPE
);
1210 /* Returns true if the provided function has the specified attribute. */
1213 has_func_attr (const_tree decl
, const char * func_attr
)
1215 if (decl
== NULL_TREE
)
1216 decl
= current_function_decl
;
1218 return lookup_attribute (func_attr
, DECL_ATTRIBUTES (decl
)) != NULL_TREE
;
1221 /* Returns true if the provided function has the "fast_interrupt" attribute. */
1224 is_fast_interrupt_func (const_tree decl
)
1226 return has_func_attr (decl
, "fast_interrupt");
1229 /* Returns true if the provided function has the "interrupt" attribute. */
1232 is_interrupt_func (const_tree decl
)
1234 return has_func_attr (decl
, "interrupt");
1237 /* Returns true if the provided function has the "naked" attribute. */
1240 is_naked_func (const_tree decl
)
1242 return has_func_attr (decl
, "naked");
1245 static bool use_fixed_regs
= false;
1248 rx_conditional_register_usage (void)
1250 static bool using_fixed_regs
= false;
1254 rx_pid_base_regnum_val
= GP_BASE_REGNUM
- rx_num_interrupt_regs
;
1255 fixed_regs
[rx_pid_base_regnum_val
] = call_used_regs
[rx_pid_base_regnum_val
] = 1;
1258 if (rx_small_data_limit
> 0)
1261 rx_gp_base_regnum_val
= rx_pid_base_regnum_val
- 1;
1263 rx_gp_base_regnum_val
= GP_BASE_REGNUM
- rx_num_interrupt_regs
;
1265 fixed_regs
[rx_gp_base_regnum_val
] = call_used_regs
[rx_gp_base_regnum_val
] = 1;
1268 if (use_fixed_regs
!= using_fixed_regs
)
1270 static char saved_fixed_regs
[FIRST_PSEUDO_REGISTER
];
1271 static char saved_call_used_regs
[FIRST_PSEUDO_REGISTER
];
1277 memcpy (saved_fixed_regs
, fixed_regs
, sizeof fixed_regs
);
1278 memcpy (saved_call_used_regs
, call_used_regs
, sizeof call_used_regs
);
1280 /* This is for fast interrupt handlers. Any register in
1281 the range r10 to r13 (inclusive) that is currently
1282 marked as fixed is now a viable, call-used register. */
1283 for (r
= 10; r
<= 13; r
++)
1287 call_used_regs
[r
] = 1;
1290 /* Mark r7 as fixed. This is just a hack to avoid
1291 altering the reg_alloc_order array so that the newly
1292 freed r10-r13 registers are the preferred registers. */
1293 fixed_regs
[7] = call_used_regs
[7] = 1;
1297 /* Restore the normal register masks. */
1298 memcpy (fixed_regs
, saved_fixed_regs
, sizeof fixed_regs
);
1299 memcpy (call_used_regs
, saved_call_used_regs
, sizeof call_used_regs
);
1302 using_fixed_regs
= use_fixed_regs
;
1309 struct decl_chain
* next
;
1312 /* Stack of decls for which we have issued warnings. */
1313 static struct decl_chain
* warned_decls
= NULL
;
1316 add_warned_decl (tree fndecl
)
1318 struct decl_chain
* warned
= (struct decl_chain
*) xmalloc (sizeof * warned
);
1320 warned
->fndecl
= fndecl
;
1321 warned
->next
= warned_decls
;
1322 warned_decls
= warned
;
1325 /* Returns TRUE if FNDECL is on our list of warned about decls. */
1328 already_warned (tree fndecl
)
1330 struct decl_chain
* warned
;
1332 for (warned
= warned_decls
;
1334 warned
= warned
->next
)
1335 if (warned
->fndecl
== fndecl
)
1341 /* Perform any actions necessary before starting to compile FNDECL.
1342 For the RX we use this to make sure that we have the correct
1343 set of register masks selected. If FNDECL is NULL then we are
1344 compiling top level things. */
1347 rx_set_current_function (tree fndecl
)
1349 /* Remember the last target of rx_set_current_function. */
1350 static tree rx_previous_fndecl
;
1351 bool prev_was_fast_interrupt
;
1352 bool current_is_fast_interrupt
;
1354 /* Only change the context if the function changes. This hook is called
1355 several times in the course of compiling a function, and we don't want
1356 to slow things down too much or call target_reinit when it isn't safe. */
1357 if (fndecl
== rx_previous_fndecl
)
1360 prev_was_fast_interrupt
1361 = rx_previous_fndecl
1362 ? is_fast_interrupt_func (rx_previous_fndecl
) : false;
1364 current_is_fast_interrupt
1365 = fndecl
? is_fast_interrupt_func (fndecl
) : false;
1367 if (prev_was_fast_interrupt
!= current_is_fast_interrupt
)
1369 use_fixed_regs
= current_is_fast_interrupt
;
1373 if (current_is_fast_interrupt
&& rx_warn_multiple_fast_interrupts
)
1375 /* We do not warn about the first fast interrupt routine that
1376 we see. Instead we just push it onto the stack. */
1377 if (warned_decls
== NULL
)
1378 add_warned_decl (fndecl
);
1380 /* Otherwise if this fast interrupt is one for which we have
1381 not already issued a warning, generate one and then push
1382 it onto the stack as well. */
1383 else if (! already_warned (fndecl
))
1385 warning (0, "multiple fast interrupt routines seen: %qE and %qE",
1386 fndecl
, warned_decls
->fndecl
);
1387 add_warned_decl (fndecl
);
1391 rx_previous_fndecl
= fndecl
;
1394 /* Typical stack layout should looks like this after the function's prologue:
1399 | | arguments saved | Increasing
1400 | | on the stack | addresses
1401 PARENT arg pointer -> | | /
1402 -------------------------- ---- -------------------
1403 CHILD |ret | return address
1413 frame pointer -> | | /
1416 | | outgoing | Decreasing
1417 | | arguments | addresses
1418 current stack pointer -> | | / |
1419 -------------------------- ---- ------------------ V
1423 bit_count (unsigned int x
)
1425 const unsigned int m1
= 0x55555555;
1426 const unsigned int m2
= 0x33333333;
1427 const unsigned int m4
= 0x0f0f0f0f;
1430 x
= (x
& m2
) + ((x
>> 2) & m2
);
1431 x
= (x
+ (x
>> 4)) & m4
;
1434 return (x
+ (x
>> 16)) & 0x3f;
1437 #if defined(TARGET_SAVE_ACC_REGISTER)
1438 #define MUST_SAVE_ACC_REGISTER \
1439 (TARGET_SAVE_ACC_REGISTER \
1440 && (is_interrupt_func (NULL_TREE) \
1441 || is_fast_interrupt_func (NULL_TREE)))
1443 #define MUST_SAVE_ACC_REGISTER 0
1446 /* Returns either the lowest numbered and highest numbered registers that
1447 occupy the call-saved area of the stack frame, if the registers are
1448 stored as a contiguous block, or else a bitmask of the individual
1449 registers if they are stored piecemeal.
1451 Also computes the size of the frame and the size of the outgoing
1452 arguments block (in bytes). */
1455 rx_get_stack_layout (unsigned int * lowest
,
1456 unsigned int * highest
,
1457 unsigned int * register_mask
,
1458 unsigned int * frame_size
,
1459 unsigned int * stack_size
)
1464 unsigned int fixed_reg
= 0;
1465 unsigned int save_mask
;
1466 unsigned int pushed_mask
;
1467 unsigned int unneeded_pushes
;
1469 if (is_naked_func (NULL_TREE
))
1471 /* Naked functions do not create their own stack frame.
1472 Instead the programmer must do that for us. */
1475 * register_mask
= 0;
1481 for (save_mask
= high
= low
= 0, reg
= 1; reg
< CC_REGNUM
; reg
++)
1483 if ((df_regs_ever_live_p (reg
)
1484 /* Always save all call clobbered registers inside non-leaf
1485 interrupt handlers, even if they are not live - they may
1486 be used in (non-interrupt aware) routines called from this one. */
1487 || (call_used_or_fixed_reg_p (reg
)
1488 && is_interrupt_func (NULL_TREE
)
1489 && ! crtl
->is_leaf
))
1490 && (! call_used_or_fixed_reg_p (reg
)
1491 /* Even call clobbered registered must
1492 be pushed inside interrupt handlers. */
1493 || is_interrupt_func (NULL_TREE
)
1494 /* Likewise for fast interrupt handlers, except registers r10 -
1495 r13. These are normally call-saved, but may have been set
1496 to call-used by rx_conditional_register_usage. If so then
1497 they can be used in the fast interrupt handler without
1498 saving them on the stack. */
1499 || (is_fast_interrupt_func (NULL_TREE
)
1500 && ! IN_RANGE (reg
, 10, 13))))
1506 save_mask
|= 1 << reg
;
1509 /* Remember if we see a fixed register
1510 after having found the low register. */
1511 if (low
!= 0 && fixed_reg
== 0 && fixed_regs
[reg
])
1515 /* If we have to save the accumulator register, make sure
1516 that at least two registers are pushed into the frame. */
1517 if (MUST_SAVE_ACC_REGISTER
1518 && bit_count (save_mask
) < 2)
1520 save_mask
|= (1 << 13) | (1 << 14);
1523 if (high
== 0 || low
== high
)
1527 /* Decide if it would be faster fill in the call-saved area of the stack
1528 frame using multiple PUSH instructions instead of a single PUSHM
1531 SAVE_MASK is a bitmask of the registers that must be stored in the
1532 call-save area. PUSHED_MASK is a bitmask of the registers that would
1533 be pushed into the area if we used a PUSHM instruction. UNNEEDED_PUSHES
1534 is a bitmask of those registers in pushed_mask that are not in
1537 We use a simple heuristic that says that it is better to use
1538 multiple PUSH instructions if the number of unnecessary pushes is
1539 greater than the number of necessary pushes.
1541 We also use multiple PUSH instructions if there are any fixed registers
1542 between LOW and HIGH. The only way that this can happen is if the user
1543 has specified --fixed-<reg-name> on the command line and in such
1544 circumstances we do not want to touch the fixed registers at all.
1546 Note also that the code in the prologue/epilogue handlers will
1547 automatically merge multiple PUSHes of adjacent registers into a single
1550 FIXME: Is it worth improving this heuristic ? */
1551 pushed_mask
= (HOST_WIDE_INT_M1U
<< low
) & ~(HOST_WIDE_INT_M1U
<< (high
+ 1));
1552 unneeded_pushes
= (pushed_mask
& (~ save_mask
)) & pushed_mask
;
1554 if ((fixed_reg
&& fixed_reg
<= high
)
1555 || (optimize_function_for_speed_p (cfun
)
1556 && bit_count (save_mask
) < bit_count (unneeded_pushes
)))
1558 /* Use multiple pushes. */
1561 * register_mask
= save_mask
;
1565 /* Use one push multiple instruction. */
1568 * register_mask
= 0;
1571 * frame_size
= rx_round_up
1572 (get_frame_size (), STACK_BOUNDARY
/ BITS_PER_UNIT
);
1574 if (crtl
->args
.size
> 0)
1575 * frame_size
+= rx_round_up
1576 (crtl
->args
.size
, STACK_BOUNDARY
/ BITS_PER_UNIT
);
1578 * stack_size
= rx_round_up
1579 (crtl
->outgoing_args_size
, STACK_BOUNDARY
/ BITS_PER_UNIT
);
1582 /* Generate a PUSHM instruction that matches the given operands. */
1585 rx_emit_stack_pushm (rtx
* operands
)
1587 HOST_WIDE_INT last_reg
;
1590 gcc_assert (CONST_INT_P (operands
[0]));
1591 last_reg
= (INTVAL (operands
[0]) / UNITS_PER_WORD
) - 1;
1593 gcc_assert (GET_CODE (operands
[1]) == PARALLEL
);
1594 first_push
= XVECEXP (operands
[1], 0, 1);
1595 gcc_assert (SET_P (first_push
));
1596 first_push
= SET_SRC (first_push
);
1597 gcc_assert (REG_P (first_push
));
1599 asm_fprintf (asm_out_file
, "\tpushm\t%s-%s\n",
1600 reg_names
[REGNO (first_push
) - last_reg
],
1601 reg_names
[REGNO (first_push
)]);
1604 /* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate. */
1607 gen_rx_store_vector (unsigned int low
, unsigned int high
)
1610 unsigned int count
= (high
- low
) + 2;
1613 vector
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
1615 XVECEXP (vector
, 0, 0) =
1616 gen_rtx_SET (stack_pointer_rtx
,
1617 gen_rtx_MINUS (SImode
, stack_pointer_rtx
,
1618 GEN_INT ((count
- 1) * UNITS_PER_WORD
)));
1620 for (i
= 0; i
< count
- 1; i
++)
1621 XVECEXP (vector
, 0, i
+ 1) =
1622 gen_rtx_SET (gen_rtx_MEM (SImode
,
1623 gen_rtx_MINUS (SImode
, stack_pointer_rtx
,
1624 GEN_INT ((i
+ 1) * UNITS_PER_WORD
))),
1625 gen_rtx_REG (SImode
, high
- i
));
1629 /* Mark INSN as being frame related. If it is a PARALLEL
1630 then mark each element as being frame related as well. */
1633 mark_frame_related (rtx insn
)
1635 RTX_FRAME_RELATED_P (insn
) = 1;
1636 insn
= PATTERN (insn
);
1638 if (GET_CODE (insn
) == PARALLEL
)
1642 for (i
= 0; i
< (unsigned) XVECLEN (insn
, 0); i
++)
1643 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, i
)) = 1;
1647 /* Create CFI notes for register pops. */
1649 add_pop_cfi_notes (rtx_insn
*insn
, unsigned int high
, unsigned int low
)
1651 rtx t
= plus_constant (Pmode
, stack_pointer_rtx
,
1652 (high
- low
+ 1) * UNITS_PER_WORD
);
1653 t
= gen_rtx_SET (stack_pointer_rtx
, t
);
1654 add_reg_note (insn
, REG_CFA_ADJUST_CFA
, t
);
1655 RTX_FRAME_RELATED_P (insn
) = 1;
1656 for (unsigned int i
= low
; i
<= high
; i
++)
1657 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (word_mode
, i
));
1662 ok_for_max_constant (HOST_WIDE_INT val
)
1664 if (rx_max_constant_size
== 0 || rx_max_constant_size
== 4)
1665 /* If there is no constraint on the size of constants
1666 used as operands, then any value is legitimate. */
1669 /* rx_max_constant_size specifies the maximum number
1670 of bytes that can be used to hold a signed value. */
1671 return IN_RANGE (val
, (HOST_WIDE_INT_M1U
<< (rx_max_constant_size
* 8)),
1672 ( 1 << (rx_max_constant_size
* 8)));
1675 /* Generate an ADD of SRC plus VAL into DEST.
1676 Handles the case where VAL is too big for max_constant_value.
1677 Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true. */
1680 gen_safe_add (rtx dest
, rtx src
, rtx val
, bool is_frame_related
)
1684 if (val
== NULL_RTX
|| INTVAL (val
) == 0)
1686 gcc_assert (dest
!= src
);
1688 insn
= emit_move_insn (dest
, src
);
1690 else if (ok_for_max_constant (INTVAL (val
)))
1691 insn
= emit_insn (gen_addsi3 (dest
, src
, val
));
1694 /* Wrap VAL in an UNSPEC so that rx_is_legitimate_constant
1695 will not reject it. */
1696 val
= gen_rtx_CONST (SImode
, gen_rtx_UNSPEC (SImode
, gen_rtvec (1, val
), UNSPEC_CONST
));
1697 insn
= emit_insn (gen_addsi3 (dest
, src
, val
));
1699 if (is_frame_related
)
1700 /* We have to provide our own frame related note here
1701 as the dwarf2out code cannot be expected to grok
1703 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
1704 gen_rtx_SET (dest
, gen_rtx_PLUS (SImode
, src
, val
)));
1708 if (is_frame_related
)
1709 RTX_FRAME_RELATED_P (insn
) = 1;
1713 push_regs (unsigned int high
, unsigned int low
)
1718 insn
= emit_insn (gen_stack_push (gen_rtx_REG (SImode
, low
)));
1720 insn
= emit_insn (gen_stack_pushm (GEN_INT (((high
- low
) + 1) * UNITS_PER_WORD
),
1721 gen_rx_store_vector (low
, high
)));
1722 mark_frame_related (insn
);
1726 rx_expand_prologue (void)
1728 unsigned int stack_size
;
1729 unsigned int frame_size
;
1735 /* Naked functions use their own, programmer provided prologues. */
1736 if (is_naked_func (NULL_TREE
))
1739 rx_get_stack_layout (& low
, & high
, & mask
, & frame_size
, & stack_size
);
1741 if (flag_stack_usage_info
)
1742 current_function_static_stack_size
= frame_size
+ stack_size
;
1744 /* If we use any of the callee-saved registers, save them now. */
1747 /* Push registers in reverse order. */
1748 for (reg
= CC_REGNUM
; reg
--;)
1749 if (mask
& (1 << reg
))
1753 /* Look for a span of registers.
1754 Note - we do not have to worry about -Os and whether
1755 it is better to use a single, longer PUSHM as
1756 rx_get_stack_layout has already done that for us. */
1758 if ((mask
& (1 << reg
)) == 0)
1763 push_regs (high
, low
);
1764 if (reg
== (unsigned) -1)
1769 push_regs (high
, low
);
1771 if (MUST_SAVE_ACC_REGISTER
)
1773 unsigned int acc_high
, acc_low
;
1775 /* Interrupt handlers have to preserve the accumulator
1776 register if so requested by the user. Use the first
1777 two pushed registers as intermediaries. */
1780 acc_low
= acc_high
= 0;
1782 for (reg
= 1; reg
< CC_REGNUM
; reg
++)
1783 if (mask
& (1 << reg
))
1794 /* We have assumed that there are at least two registers pushed... */
1795 gcc_assert (acc_high
!= 0);
1797 /* Note - the bottom 16 bits of the accumulator are inaccessible.
1798 We just assume that they are zero. */
1799 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode
, acc_low
)));
1800 emit_insn (gen_mvfachi (gen_rtx_REG (SImode
, acc_high
)));
1801 emit_insn (gen_stack_push (gen_rtx_REG (SImode
, acc_low
)));
1802 emit_insn (gen_stack_push (gen_rtx_REG (SImode
, acc_high
)));
1809 /* We have assumed that there are at least two registers pushed... */
1810 gcc_assert (acc_high
<= high
);
1812 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode
, acc_low
)));
1813 emit_insn (gen_mvfachi (gen_rtx_REG (SImode
, acc_high
)));
1814 emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD
),
1815 gen_rx_store_vector (acc_low
, acc_high
)));
1819 /* If needed, set up the frame pointer. */
1820 if (frame_pointer_needed
)
1821 gen_safe_add (frame_pointer_rtx
, stack_pointer_rtx
,
1822 GEN_INT (- (HOST_WIDE_INT
) frame_size
), true);
1824 /* Allocate space for the outgoing args.
1825 If the stack frame has not already been set up then handle this as well. */
1830 if (frame_pointer_needed
)
1831 gen_safe_add (stack_pointer_rtx
, frame_pointer_rtx
,
1832 GEN_INT (- (HOST_WIDE_INT
) stack_size
), true);
1834 gen_safe_add (stack_pointer_rtx
, stack_pointer_rtx
,
1835 GEN_INT (- (HOST_WIDE_INT
) (frame_size
+ stack_size
)),
1839 gen_safe_add (stack_pointer_rtx
, stack_pointer_rtx
,
1840 GEN_INT (- (HOST_WIDE_INT
) stack_size
), true);
1842 else if (frame_size
)
1844 if (! frame_pointer_needed
)
1845 gen_safe_add (stack_pointer_rtx
, stack_pointer_rtx
,
1846 GEN_INT (- (HOST_WIDE_INT
) frame_size
), true);
1848 gen_safe_add (stack_pointer_rtx
, frame_pointer_rtx
, NULL_RTX
, true);
1853 add_vector_labels (FILE *file
, const char *aname
)
1857 const char *vname
= "vect";
1861 /* This node is for the vector/interrupt tag itself */
1862 vec_attr
= lookup_attribute (aname
, DECL_ATTRIBUTES (current_function_decl
));
1866 /* Now point it at the first argument */
1867 vec_attr
= TREE_VALUE (vec_attr
);
1869 /* Iterate through the arguments. */
1872 val_attr
= TREE_VALUE (vec_attr
);
1873 switch (TREE_CODE (val_attr
))
1876 s
= TREE_STRING_POINTER (val_attr
);
1877 goto string_id_common
;
1879 case IDENTIFIER_NODE
:
1880 s
= IDENTIFIER_POINTER (val_attr
);
1883 if (strcmp (s
, "$default") == 0)
1885 fprintf (file
, "\t.global\t$tableentry$default$%s\n", vname
);
1886 fprintf (file
, "$tableentry$default$%s:\n", vname
);
1893 vnum
= TREE_INT_CST_LOW (val_attr
);
1895 fprintf (file
, "\t.global\t$tableentry$%d$%s\n", vnum
, vname
);
1896 fprintf (file
, "$tableentry$%d$%s:\n", vnum
, vname
);
1903 vec_attr
= TREE_CHAIN (vec_attr
);
1909 rx_output_function_prologue (FILE * file
)
1911 add_vector_labels (file
, "interrupt");
1912 add_vector_labels (file
, "vector");
1914 if (is_fast_interrupt_func (NULL_TREE
))
1915 asm_fprintf (file
, "\t; Note: Fast Interrupt Handler\n");
1917 if (is_interrupt_func (NULL_TREE
))
1918 asm_fprintf (file
, "\t; Note: Interrupt Handler\n");
1920 if (is_naked_func (NULL_TREE
))
1921 asm_fprintf (file
, "\t; Note: Naked Function\n");
1923 if (cfun
->static_chain_decl
!= NULL
)
1924 asm_fprintf (file
, "\t; Note: Nested function declared "
1925 "inside another function.\n");
1927 if (crtl
->calls_eh_return
)
1928 asm_fprintf (file
, "\t; Note: Calls __builtin_eh_return.\n");
1931 /* Generate a POPM or RTSD instruction that matches the given operands. */
1934 rx_emit_stack_popm (rtx
* operands
, bool is_popm
)
1936 HOST_WIDE_INT stack_adjust
;
1937 HOST_WIDE_INT last_reg
;
1940 gcc_assert (CONST_INT_P (operands
[0]));
1941 stack_adjust
= INTVAL (operands
[0]);
1943 gcc_assert (GET_CODE (operands
[1]) == PARALLEL
);
1944 last_reg
= XVECLEN (operands
[1], 0) - (is_popm
? 2 : 3);
1946 first_push
= XVECEXP (operands
[1], 0, 1);
1947 gcc_assert (SET_P (first_push
));
1948 first_push
= SET_DEST (first_push
);
1949 gcc_assert (REG_P (first_push
));
1952 asm_fprintf (asm_out_file
, "\tpopm\t%s-%s\n",
1953 reg_names
[REGNO (first_push
)],
1954 reg_names
[REGNO (first_push
) + last_reg
]);
1956 asm_fprintf (asm_out_file
, "\trtsd\t#%d, %s-%s\n",
1958 reg_names
[REGNO (first_push
)],
1959 reg_names
[REGNO (first_push
) + last_reg
]);
1962 /* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate. */
1965 gen_rx_rtsd_vector (unsigned int adjust
, unsigned int low
, unsigned int high
)
1968 unsigned int bias
= 3;
1969 unsigned int count
= (high
- low
) + bias
;
1972 vector
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
1974 XVECEXP (vector
, 0, 0) =
1975 gen_rtx_SET (stack_pointer_rtx
,
1976 plus_constant (Pmode
, stack_pointer_rtx
, adjust
));
1978 for (i
= 0; i
< count
- 2; i
++)
1979 XVECEXP (vector
, 0, i
+ 1) =
1980 gen_rtx_SET (gen_rtx_REG (SImode
, low
+ i
),
1981 gen_rtx_MEM (SImode
,
1982 i
== 0 ? stack_pointer_rtx
1983 : plus_constant (Pmode
, stack_pointer_rtx
,
1984 i
* UNITS_PER_WORD
)));
1986 XVECEXP (vector
, 0, count
- 1) = ret_rtx
;
1991 /* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate. */
1994 gen_rx_popm_vector (unsigned int low
, unsigned int high
)
1997 unsigned int count
= (high
- low
) + 2;
2000 vector
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (count
));
2002 XVECEXP (vector
, 0, 0) =
2003 gen_rtx_SET (stack_pointer_rtx
,
2004 plus_constant (Pmode
, stack_pointer_rtx
,
2005 (count
- 1) * UNITS_PER_WORD
));
2007 for (i
= 0; i
< count
- 1; i
++)
2008 XVECEXP (vector
, 0, i
+ 1) =
2009 gen_rtx_SET (gen_rtx_REG (SImode
, low
+ i
),
2010 gen_rtx_MEM (SImode
,
2011 i
== 0 ? stack_pointer_rtx
2012 : plus_constant (Pmode
, stack_pointer_rtx
,
2013 i
* UNITS_PER_WORD
)));
2018 /* Returns true if a simple return insn can be used. */
2021 rx_can_use_simple_return (void)
2025 unsigned int frame_size
;
2026 unsigned int stack_size
;
2027 unsigned int register_mask
;
2029 if (is_naked_func (NULL_TREE
)
2030 || is_fast_interrupt_func (NULL_TREE
)
2031 || is_interrupt_func (NULL_TREE
))
2034 rx_get_stack_layout (& low
, & high
, & register_mask
,
2035 & frame_size
, & stack_size
);
2037 return (register_mask
== 0
2038 && (frame_size
+ stack_size
) == 0
2043 pop_regs (unsigned int high
, unsigned int low
)
2047 insn
= emit_insn (gen_stack_pop (gen_rtx_REG (SImode
, low
)));
2049 insn
= emit_insn (gen_stack_popm (GEN_INT (((high
- low
) + 1)
2051 gen_rx_popm_vector (low
, high
)));
2052 add_pop_cfi_notes (insn
, high
, low
);
2056 rx_expand_epilogue (bool is_sibcall
)
2060 unsigned int frame_size
;
2061 unsigned int stack_size
;
2062 unsigned int register_mask
;
2063 unsigned int regs_size
;
2065 unsigned HOST_WIDE_INT total_size
;
2067 /* FIXME: We do not support indirect sibcalls at the moment becaause we
2068 cannot guarantee that the register holding the function address is a
2069 call-used register. If it is a call-saved register then the stack
2070 pop instructions generated in the epilogue will corrupt the address
2073 Creating a new call-used-only register class works but then the
2074 reload pass gets stuck because it cannot always find a call-used
2075 register for spilling sibcalls.
2077 The other possible solution is for this pass to scan forward for the
2078 sibcall instruction (if it has been generated) and work out if it
2079 is an indirect sibcall using a call-saved register. If it is then
2080 the address can copied into a call-used register in this epilogue
2081 code and the sibcall instruction modified to use that register. */
2083 if (is_naked_func (NULL_TREE
))
2085 gcc_assert (! is_sibcall
);
2087 /* Naked functions use their own, programmer provided epilogues.
2088 But, in order to keep gcc happy we have to generate some kind of
2090 emit_jump_insn (gen_naked_return ());
2094 rx_get_stack_layout (& low
, & high
, & register_mask
,
2095 & frame_size
, & stack_size
);
2097 total_size
= frame_size
+ stack_size
;
2098 regs_size
= ((high
- low
) + 1) * UNITS_PER_WORD
;
2100 /* See if we are unable to use the special stack frame deconstruct and
2101 return instructions. In most cases we can use them, but the exceptions
2104 - Sibling calling functions deconstruct the frame but do not return to
2105 their caller. Instead they branch to their sibling and allow their
2106 return instruction to return to this function's parent.
2108 - Fast and normal interrupt handling functions have to use special
2109 return instructions.
2111 - Functions where we have pushed a fragmented set of registers into the
2112 call-save area must have the same set of registers popped. */
2114 || is_fast_interrupt_func (NULL_TREE
)
2115 || is_interrupt_func (NULL_TREE
)
2118 /* Cannot use the special instructions - deconstruct by hand. */
2120 gen_safe_add (stack_pointer_rtx
, stack_pointer_rtx
,
2121 GEN_INT (total_size
), true);
2123 if (MUST_SAVE_ACC_REGISTER
)
2125 unsigned int acc_low
, acc_high
;
2127 /* Reverse the saving of the accumulator register onto the stack.
2128 Note we must adjust the saved "low" accumulator value as it
2129 is really the middle 32-bits of the accumulator. */
2132 acc_low
= acc_high
= 0;
2134 for (reg
= 1; reg
< CC_REGNUM
; reg
++)
2135 if (register_mask
& (1 << reg
))
2145 emit_insn (gen_stack_pop (gen_rtx_REG (SImode
, acc_high
)));
2146 emit_insn (gen_stack_pop (gen_rtx_REG (SImode
, acc_low
)));
2152 emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD
),
2153 gen_rx_popm_vector (acc_low
, acc_high
)));
2156 emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode
, acc_low
),
2157 gen_rtx_REG (SImode
, acc_low
),
2159 emit_insn (gen_mvtaclo (gen_rtx_REG (SImode
, acc_low
)));
2160 emit_insn (gen_mvtachi (gen_rtx_REG (SImode
, acc_high
)));
2165 for (reg
= 0; reg
< CC_REGNUM
; reg
++)
2166 if (register_mask
& (1 << reg
))
2169 while (register_mask
& (1 << high
))
2171 pop_regs (high
- 1, low
);
2176 pop_regs (high
, low
);
2178 if (is_fast_interrupt_func (NULL_TREE
))
2180 gcc_assert (! is_sibcall
);
2181 emit_jump_insn (gen_fast_interrupt_return ());
2183 else if (is_interrupt_func (NULL_TREE
))
2185 gcc_assert (! is_sibcall
);
2186 emit_jump_insn (gen_exception_return ());
2188 else if (! is_sibcall
)
2189 emit_jump_insn (gen_simple_return ());
2194 /* If we allocated space on the stack, free it now. */
2197 unsigned HOST_WIDE_INT rtsd_size
;
2199 /* See if we can use the RTSD instruction. */
2200 rtsd_size
= total_size
+ regs_size
;
2201 if (rtsd_size
< 1024 && (rtsd_size
% 4) == 0)
2204 emit_jump_insn (gen_pop_and_return
2205 (GEN_INT (rtsd_size
),
2206 gen_rx_rtsd_vector (rtsd_size
, low
, high
)));
2208 emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size
)));
2213 gen_safe_add (stack_pointer_rtx
, stack_pointer_rtx
,
2214 GEN_INT (total_size
), false);
2218 emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size
),
2219 gen_rx_rtsd_vector (regs_size
,
2222 emit_jump_insn (gen_simple_return ());
2226 /* Compute the offset (in words) between FROM (arg pointer
2227 or frame pointer) and TO (frame pointer or stack pointer).
2228 See ASCII art comment at the start of rx_expand_prologue
2229 for more information. */
2232 rx_initial_elimination_offset (int from
, int to
)
2236 unsigned int frame_size
;
2237 unsigned int stack_size
;
2240 rx_get_stack_layout (& low
, & high
, & mask
, & frame_size
, & stack_size
);
2242 if (from
== ARG_POINTER_REGNUM
)
2244 /* Extend the computed size of the stack frame to
2245 include the registers pushed in the prologue. */
2247 frame_size
+= ((high
- low
) + 1) * UNITS_PER_WORD
;
2249 frame_size
+= bit_count (mask
) * UNITS_PER_WORD
;
2251 /* Remember to include the return address. */
2252 frame_size
+= 1 * UNITS_PER_WORD
;
2254 if (to
== FRAME_POINTER_REGNUM
)
2257 gcc_assert (to
== STACK_POINTER_REGNUM
);
2258 return frame_size
+ stack_size
;
2261 gcc_assert (from
== FRAME_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
);
2265 /* Decide if a variable should go into one of the small data sections. */
2268 rx_in_small_data (const_tree decl
)
2271 const char * section
;
2273 if (rx_small_data_limit
== 0)
2276 if (TREE_CODE (decl
) != VAR_DECL
)
2279 /* We do not put read-only variables into a small data area because
2280 they would be placed with the other read-only sections, far away
2281 from the read-write data sections, and we only have one small
2283 Similarly commons are placed in the .bss section which might be
2284 far away (and out of alignment with respect to) the .data section. */
2285 if (TREE_READONLY (decl
) || DECL_COMMON (decl
))
2288 section
= DECL_SECTION_NAME (decl
);
2290 return (strcmp (section
, "D_2") == 0) || (strcmp (section
, "B_2") == 0);
2292 size
= int_size_in_bytes (TREE_TYPE (decl
));
2294 return (size
> 0) && (size
<= rx_small_data_limit
);
2297 /* Return a section for X.
2298 The only special thing we do here is to honor small data. */
2301 rx_select_rtx_section (machine_mode mode
,
2303 unsigned HOST_WIDE_INT align
)
2305 if (rx_small_data_limit
> 0
2306 && GET_MODE_SIZE (mode
) <= rx_small_data_limit
2307 && align
<= (unsigned HOST_WIDE_INT
) rx_small_data_limit
* BITS_PER_UNIT
)
2308 return sdata_section
;
2310 return default_elf_select_rtx_section (mode
, x
, align
);
2314 rx_select_section (tree decl
,
2316 unsigned HOST_WIDE_INT align
)
2318 if (rx_small_data_limit
> 0)
2320 switch (categorize_decl_for_section (decl
, reloc
))
2322 case SECCAT_SDATA
: return sdata_section
;
2323 case SECCAT_SBSS
: return sbss_section
;
2324 case SECCAT_SRODATA
:
2325 /* Fall through. We do not put small, read only
2326 data into the C_2 section because we are not
2327 using the C_2 section. We do not use the C_2
2328 section because it is located with the other
2329 read-only data sections, far away from the read-write
2330 data sections and we only have one small data
2337 /* If we are supporting the Renesas assembler
2338 we cannot use mergeable sections. */
2339 if (TARGET_AS100_SYNTAX
)
2340 switch (categorize_decl_for_section (decl
, reloc
))
2342 case SECCAT_RODATA_MERGE_CONST
:
2343 case SECCAT_RODATA_MERGE_STR_INIT
:
2344 case SECCAT_RODATA_MERGE_STR
:
2345 return readonly_data_section
;
2351 return default_elf_select_section (decl
, reloc
, align
);
2379 static GTY(()) tree rx_builtins
[(int) RX_BUILTIN_max
];
2382 rx_init_builtins (void)
2384 #define ADD_RX_BUILTIN0(UC_NAME, LC_NAME, RET_TYPE) \
2385 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2386 add_builtin_function ("__builtin_rx_" LC_NAME, \
2387 build_function_type_list (RET_TYPE##_type_node, \
2389 RX_BUILTIN_##UC_NAME, \
2390 BUILT_IN_MD, NULL, NULL_TREE)
2392 #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \
2393 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2394 add_builtin_function ("__builtin_rx_" LC_NAME, \
2395 build_function_type_list (RET_TYPE##_type_node, \
2396 ARG_TYPE##_type_node, \
2398 RX_BUILTIN_##UC_NAME, \
2399 BUILT_IN_MD, NULL, NULL_TREE)
2401 #define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
2402 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2403 add_builtin_function ("__builtin_rx_" LC_NAME, \
2404 build_function_type_list (RET_TYPE##_type_node, \
2405 ARG_TYPE1##_type_node,\
2406 ARG_TYPE2##_type_node,\
2408 RX_BUILTIN_##UC_NAME, \
2409 BUILT_IN_MD, NULL, NULL_TREE)
2411 #define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
2412 rx_builtins[RX_BUILTIN_##UC_NAME] = \
2413 add_builtin_function ("__builtin_rx_" LC_NAME, \
2414 build_function_type_list (RET_TYPE##_type_node, \
2415 ARG_TYPE1##_type_node,\
2416 ARG_TYPE2##_type_node,\
2417 ARG_TYPE3##_type_node,\
2419 RX_BUILTIN_##UC_NAME, \
2420 BUILT_IN_MD, NULL, NULL_TREE)
2422 ADD_RX_BUILTIN0 (BRK
, "brk", void);
2423 ADD_RX_BUILTIN1 (CLRPSW
, "clrpsw", void, integer
);
2424 ADD_RX_BUILTIN1 (SETPSW
, "setpsw", void, integer
);
2425 ADD_RX_BUILTIN1 (INT
, "int", void, integer
);
2426 ADD_RX_BUILTIN2 (MACHI
, "machi", void, intSI
, intSI
);
2427 ADD_RX_BUILTIN2 (MACLO
, "maclo", void, intSI
, intSI
);
2428 ADD_RX_BUILTIN2 (MULHI
, "mulhi", void, intSI
, intSI
);
2429 ADD_RX_BUILTIN2 (MULLO
, "mullo", void, intSI
, intSI
);
2430 ADD_RX_BUILTIN0 (MVFACHI
, "mvfachi", intSI
);
2431 ADD_RX_BUILTIN0 (MVFACMI
, "mvfacmi", intSI
);
2432 ADD_RX_BUILTIN1 (MVTACHI
, "mvtachi", void, intSI
);
2433 ADD_RX_BUILTIN1 (MVTACLO
, "mvtaclo", void, intSI
);
2434 ADD_RX_BUILTIN0 (RMPA
, "rmpa", void);
2435 ADD_RX_BUILTIN1 (MVFC
, "mvfc", intSI
, integer
);
2436 ADD_RX_BUILTIN2 (MVTC
, "mvtc", void, integer
, integer
);
2437 ADD_RX_BUILTIN1 (MVTIPL
, "mvtipl", void, integer
);
2438 ADD_RX_BUILTIN1 (RACW
, "racw", void, integer
);
2439 ADD_RX_BUILTIN1 (ROUND
, "round", intSI
, float);
2440 ADD_RX_BUILTIN1 (REVW
, "revw", intSI
, intSI
);
2441 ADD_RX_BUILTIN0 (WAIT
, "wait", void);
2444 /* Return the RX builtin for CODE. */
2447 rx_builtin_decl (unsigned code
, bool initialize_p ATTRIBUTE_UNUSED
)
2449 if (code
>= RX_BUILTIN_max
)
2450 return error_mark_node
;
2452 return rx_builtins
[code
];
2456 rx_expand_void_builtin_1_arg (rtx arg
, rtx (* gen_func
)(rtx
), bool reg
)
2458 if (reg
&& ! REG_P (arg
))
2459 arg
= force_reg (SImode
, arg
);
2461 emit_insn (gen_func (arg
));
2467 rx_expand_builtin_mvtc (tree exp
)
2469 rtx arg1
= expand_normal (CALL_EXPR_ARG (exp
, 0));
2470 rtx arg2
= expand_normal (CALL_EXPR_ARG (exp
, 1));
2472 if (! CONST_INT_P (arg1
))
2476 arg2
= force_reg (SImode
, arg2
);
2478 if (INTVAL (arg1
) == 1)
2480 warning (0, "invalid control register %d for mvtc; using %<psw%>",
2481 (int) INTVAL (arg1
));
2485 emit_insn (gen_mvtc (arg1
, arg2
));
2491 rx_expand_builtin_mvfc (tree t_arg
, rtx target
)
2493 rtx arg
= expand_normal (t_arg
);
2495 if (! CONST_INT_P (arg
))
2498 if (target
== NULL_RTX
)
2501 if (! REG_P (target
))
2502 target
= force_reg (SImode
, target
);
2504 emit_insn (gen_mvfc (target
, arg
));
2510 rx_expand_builtin_mvtipl (rtx arg
)
2512 /* The RX610 does not support the MVTIPL instruction. */
2513 if (rx_cpu_type
== RX610
)
2516 if (! CONST_INT_P (arg
) || ! IN_RANGE (INTVAL (arg
), 0, (1 << 4) - 1))
2519 emit_insn (gen_mvtipl (arg
));
2525 rx_expand_builtin_mac (tree exp
, rtx (* gen_func
)(rtx
, rtx
))
2527 rtx arg1
= expand_normal (CALL_EXPR_ARG (exp
, 0));
2528 rtx arg2
= expand_normal (CALL_EXPR_ARG (exp
, 1));
2531 arg1
= force_reg (SImode
, arg1
);
2534 arg2
= force_reg (SImode
, arg2
);
2536 emit_insn (gen_func (arg1
, arg2
));
2542 rx_expand_int_builtin_1_arg (rtx arg
,
2544 rtx (* gen_func
)(rtx
, rtx
),
2548 if (!mem_ok
|| ! MEM_P (arg
))
2549 arg
= force_reg (SImode
, arg
);
2551 if (target
== NULL_RTX
|| ! REG_P (target
))
2552 target
= gen_reg_rtx (SImode
);
2554 emit_insn (gen_func (target
, arg
));
2560 rx_expand_int_builtin_0_arg (rtx target
, rtx (* gen_func
)(rtx
))
2562 if (target
== NULL_RTX
|| ! REG_P (target
))
2563 target
= gen_reg_rtx (SImode
);
2565 emit_insn (gen_func (target
));
2571 rx_expand_builtin_round (rtx arg
, rtx target
)
2573 if ((! REG_P (arg
) && ! MEM_P (arg
))
2574 || GET_MODE (arg
) != SFmode
)
2575 arg
= force_reg (SFmode
, arg
);
2577 if (target
== NULL_RTX
|| ! REG_P (target
))
2578 target
= gen_reg_rtx (SImode
);
2580 emit_insn (gen_lrintsf2 (target
, arg
));
2586 valid_psw_flag (rtx op
, const char *which
)
2588 static int mvtc_inform_done
= 0;
2590 if (GET_CODE (op
) == CONST_INT
)
2591 switch (INTVAL (op
))
2593 case 0: case 'c': case 'C':
2594 case 1: case 'z': case 'Z':
2595 case 2: case 's': case 'S':
2596 case 3: case 'o': case 'O':
2597 case 8: case 'i': case 'I':
2598 case 9: case 'u': case 'U':
2602 error ("%<__builtin_rx_%s%> takes %<C%>, %<Z%>, %<S%>, %<O%>, %<I%>, "
2604 if (!mvtc_inform_done
)
2605 error ("use %<__builtin_rx_mvtc (0, ... )%> to write arbitrary values to PSW");
2606 mvtc_inform_done
= 1;
2612 rx_expand_builtin (tree exp
,
2614 rtx subtarget ATTRIBUTE_UNUSED
,
2615 machine_mode mode ATTRIBUTE_UNUSED
,
2616 int ignore ATTRIBUTE_UNUSED
)
2618 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
2619 tree arg
= call_expr_nargs (exp
) >= 1 ? CALL_EXPR_ARG (exp
, 0) : NULL_TREE
;
2620 rtx op
= arg
? expand_normal (arg
) : NULL_RTX
;
2621 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
2625 case RX_BUILTIN_BRK
: emit_insn (gen_brk ()); return NULL_RTX
;
2626 case RX_BUILTIN_CLRPSW
:
2627 if (!valid_psw_flag (op
, "clrpsw"))
2629 return rx_expand_void_builtin_1_arg (op
, gen_clrpsw
, false);
2630 case RX_BUILTIN_SETPSW
:
2631 if (!valid_psw_flag (op
, "setpsw"))
2633 return rx_expand_void_builtin_1_arg (op
, gen_setpsw
, false);
2634 case RX_BUILTIN_INT
: return rx_expand_void_builtin_1_arg
2635 (op
, gen_int
, false);
2636 case RX_BUILTIN_MACHI
: return rx_expand_builtin_mac (exp
, gen_machi
);
2637 case RX_BUILTIN_MACLO
: return rx_expand_builtin_mac (exp
, gen_maclo
);
2638 case RX_BUILTIN_MULHI
: return rx_expand_builtin_mac (exp
, gen_mulhi
);
2639 case RX_BUILTIN_MULLO
: return rx_expand_builtin_mac (exp
, gen_mullo
);
2640 case RX_BUILTIN_MVFACHI
: return rx_expand_int_builtin_0_arg
2641 (target
, gen_mvfachi
);
2642 case RX_BUILTIN_MVFACMI
: return rx_expand_int_builtin_0_arg
2643 (target
, gen_mvfacmi
);
2644 case RX_BUILTIN_MVTACHI
: return rx_expand_void_builtin_1_arg
2645 (op
, gen_mvtachi
, true);
2646 case RX_BUILTIN_MVTACLO
: return rx_expand_void_builtin_1_arg
2647 (op
, gen_mvtaclo
, true);
2648 case RX_BUILTIN_RMPA
:
2649 if (rx_allow_string_insns
)
2650 emit_insn (gen_rmpa ());
2652 error ("%<-mno-allow-string-insns%> forbids the generation "
2653 "of the RMPA instruction");
2655 case RX_BUILTIN_MVFC
: return rx_expand_builtin_mvfc (arg
, target
);
2656 case RX_BUILTIN_MVTC
: return rx_expand_builtin_mvtc (exp
);
2657 case RX_BUILTIN_MVTIPL
: return rx_expand_builtin_mvtipl (op
);
2658 case RX_BUILTIN_RACW
: return rx_expand_void_builtin_1_arg
2659 (op
, gen_racw
, false);
2660 case RX_BUILTIN_ROUND
: return rx_expand_builtin_round (op
, target
);
2661 case RX_BUILTIN_REVW
: return rx_expand_int_builtin_1_arg
2662 (op
, target
, gen_revw
, false);
2663 case RX_BUILTIN_WAIT
: emit_insn (gen_wait ()); return NULL_RTX
;
2666 internal_error ("bad builtin code");
2673 /* Place an element into a constructor or destructor section.
2674 Like default_ctor_section_asm_out_constructor in varasm.cc
2675 except that it uses .init_array (or .fini_array) and it
2676 handles constructor priorities. */
2679 rx_elf_asm_cdtor (rtx symbol
, int priority
, bool is_ctor
)
2683 if (priority
!= DEFAULT_INIT_PRIORITY
)
2687 sprintf (buf
, "%s.%.5u",
2688 is_ctor
? ".init_array" : ".fini_array",
2690 s
= get_section (buf
, SECTION_WRITE
, NULL_TREE
);
2697 switch_to_section (s
);
2698 assemble_align (POINTER_SIZE
);
2699 assemble_integer (symbol
, POINTER_SIZE
/ BITS_PER_UNIT
, POINTER_SIZE
, 1);
2703 rx_elf_asm_constructor (rtx symbol
, int priority
)
2705 rx_elf_asm_cdtor (symbol
, priority
, /* is_ctor= */true);
2709 rx_elf_asm_destructor (rtx symbol
, int priority
)
2711 rx_elf_asm_cdtor (symbol
, priority
, /* is_ctor= */false);
2714 /* Check "fast_interrupt", "interrupt" and "naked" attributes. */
2717 rx_handle_func_attribute (tree
* node
,
2719 tree args ATTRIBUTE_UNUSED
,
2720 int flags ATTRIBUTE_UNUSED
,
2721 bool * no_add_attrs
)
2723 gcc_assert (DECL_P (* node
));
2725 if (TREE_CODE (* node
) != FUNCTION_DECL
)
2727 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2729 * no_add_attrs
= true;
2732 /* FIXME: We ought to check for conflicting attributes. */
2734 /* FIXME: We ought to check that the interrupt and exception
2735 handler attributes have been applied to void functions. */
2739 /* Check "vector" attribute. */
2742 rx_handle_vector_attribute (tree
* node
,
2745 int flags ATTRIBUTE_UNUSED
,
2746 bool * no_add_attrs
)
2748 gcc_assert (DECL_P (* node
));
2749 gcc_assert (args
!= NULL_TREE
);
2751 if (TREE_CODE (* node
) != FUNCTION_DECL
)
2753 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2755 * no_add_attrs
= true;
2761 /* Table of RX specific attributes. */
2762 TARGET_GNU_ATTRIBUTES (rx_attribute_table
,
2764 /* Name, min_len, max_len, decl_req, type_req, fn_type_req,
2765 affects_type_identity, handler, exclude. */
2766 { "fast_interrupt", 0, 0, true, false, false, false,
2767 rx_handle_func_attribute
, NULL
},
2768 { "interrupt", 0, -1, true, false, false, false,
2769 rx_handle_func_attribute
, NULL
},
2770 { "naked", 0, 0, true, false, false, false,
2771 rx_handle_func_attribute
, NULL
},
2772 { "vector", 1, -1, true, false, false, false,
2773 rx_handle_vector_attribute
, NULL
}
2776 /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */
2779 rx_override_options_after_change (void)
2781 static bool first_time
= TRUE
;
2785 /* If this is the first time through and the user has not disabled
2786 the use of RX FPU hardware then enable -ffinite-math-only,
2787 since the FPU instructions do not support NaNs and infinities. */
2789 flag_finite_math_only
= 1;
2795 /* Alert the user if they are changing the optimization options
2796 to use IEEE compliant floating point arithmetic with RX FPU insns. */
2798 && !flag_finite_math_only
)
2799 warning (0, "RX FPU instructions do not support NaNs and infinities");
2804 rx_option_override (void)
2807 cl_deferred_option
*opt
;
2808 vec
<cl_deferred_option
> *v
= (vec
<cl_deferred_option
> *) rx_deferred_options
;
2811 FOR_EACH_VEC_ELT (*v
, i
, opt
)
2813 switch (opt
->opt_index
)
2815 case OPT_mint_register_
:
2819 fixed_regs
[10] = call_used_regs
[10] = 1;
2822 fixed_regs
[11] = call_used_regs
[11] = 1;
2825 fixed_regs
[12] = call_used_regs
[12] = 1;
2828 fixed_regs
[13] = call_used_regs
[13] = 1;
2831 rx_num_interrupt_regs
= opt
->value
;
2834 rx_num_interrupt_regs
= 0;
2835 /* Error message already given because rx_handle_option
2846 /* This target defaults to strict volatile bitfields. */
2847 if (flag_strict_volatile_bitfields
< 0 && abi_version_at_least(2))
2848 flag_strict_volatile_bitfields
= 1;
2850 rx_override_options_after_change ();
2852 /* These values are bytes, not log. */
2853 if (! optimize_size
)
2855 if (flag_align_jumps
&& !str_align_jumps
)
2856 str_align_jumps
= ((rx_cpu_type
== RX100
2857 || rx_cpu_type
== RX200
) ? "4" : "8");
2858 if (flag_align_loops
&& !str_align_loops
)
2859 str_align_loops
= ((rx_cpu_type
== RX100
2860 || rx_cpu_type
== RX200
) ? "4" : "8");
2861 if (flag_align_labels
&& !str_align_labels
)
2862 str_align_labels
= ((rx_cpu_type
== RX100
2863 || rx_cpu_type
== RX200
) ? "4" : "8");
2869 rx_allocate_stack_slots_for_args (void)
2871 /* Naked functions should not allocate stack slots for arguments. */
2872 return ! is_naked_func (NULL_TREE
);
2876 rx_func_attr_inlinable (const_tree decl
)
2878 return ! is_fast_interrupt_func (decl
)
2879 && ! is_interrupt_func (decl
)
2880 && ! is_naked_func (decl
);
2884 rx_warn_func_return (tree decl
)
2886 /* Naked functions are implemented entirely in assembly, including the
2887 return sequence, so suppress warnings about this. */
2888 return !is_naked_func (decl
);
2891 /* Return nonzero if it is ok to make a tail-call to DECL,
2892 a function_decl or NULL if this is an indirect call, using EXP */
2895 rx_function_ok_for_sibcall (tree decl
, tree exp ATTRIBUTE_UNUSED
)
2900 /* Do not allow indirect tailcalls. The
2901 sibcall patterns do not support them. */
2905 /* Never tailcall from inside interrupt handlers or naked functions. */
2906 if (is_fast_interrupt_func (NULL_TREE
)
2907 || is_interrupt_func (NULL_TREE
)
2908 || is_naked_func (NULL_TREE
))
2915 rx_file_start (void)
2917 if (! TARGET_AS100_SYNTAX
)
2918 default_file_start ();
2922 rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED
)
2924 /* The packed attribute overrides the MS behavior. */
2925 return ! TYPE_PACKED (record_type
);
2928 /* Returns true if X a legitimate constant for an immediate
2929 operand on the RX. X is already known to satisfy CONSTANT_P. */
2932 rx_is_legitimate_constant (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2934 switch (GET_CODE (x
))
2939 if (GET_CODE (x
) == PLUS
)
2941 if (! CONST_INT_P (XEXP (x
, 1)))
2944 /* GCC would not pass us CONST_INT + CONST_INT so we
2945 know that we have {SYMBOL|LABEL} + CONST_INT. */
2947 gcc_assert (! CONST_INT_P (x
));
2950 switch (GET_CODE (x
))
2957 return XINT (x
, 1) == UNSPEC_CONST
|| XINT (x
, 1) == UNSPEC_PID_ADDR
;
2960 /* FIXME: Can this ever happen ? */
2969 return (rx_max_constant_size
== 0 || rx_max_constant_size
== 4);
2973 gcc_assert (CONST_INT_P (x
));
2977 return ok_for_max_constant (INTVAL (x
));
2981 rx_address_cost (rtx addr
, machine_mode mode ATTRIBUTE_UNUSED
,
2982 addr_space_t as ATTRIBUTE_UNUSED
, bool speed
)
2986 if (GET_CODE (addr
) != PLUS
)
2987 return COSTS_N_INSNS (1);
2992 if (REG_P (a
) && REG_P (b
))
2993 /* Try to discourage REG+REG addressing as it keeps two registers live. */
2994 return COSTS_N_INSNS (4);
2997 /* [REG+OFF] is just as fast as [REG]. */
2998 return COSTS_N_INSNS (1);
3001 && ((INTVAL (b
) > 128) || INTVAL (b
) < -127))
3002 /* Try to discourage REG + <large OFF> when optimizing for size. */
3003 return COSTS_N_INSNS (2);
3005 return COSTS_N_INSNS (1);
3009 rx_rtx_costs (rtx x
, machine_mode mode
, int outer_code ATTRIBUTE_UNUSED
,
3010 int opno ATTRIBUTE_UNUSED
, int* total
, bool speed
)
3012 if (x
== const0_rtx
)
3018 switch (GET_CODE (x
))
3023 *total
= COSTS_N_INSNS (2);
3034 *total
= COSTS_N_INSNS (1);
3039 /* This is the worst case for a division. Pessimize divisions when
3040 not optimizing for size and allow reciprocal optimizations which
3041 produce bigger code. */
3042 *total
= COSTS_N_INSNS (20);
3044 *total
= COSTS_N_INSNS (3);
3049 /* This is the worst case for a division. Pessimize divisions when
3050 not optimizing for size and allow reciprocal optimizations which
3051 produce bigger code. */
3052 *total
= COSTS_N_INSNS (18);
3054 *total
= COSTS_N_INSNS (3);
3065 rx_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
3067 /* We can always eliminate to the frame pointer.
3068 We can eliminate to the stack pointer unless a frame
3069 pointer is needed. */
3071 return to
== FRAME_POINTER_REGNUM
3072 || ( to
== STACK_POINTER_REGNUM
&& ! frame_pointer_needed
);
3077 rx_trampoline_template (FILE * file
)
3079 /* Output assembler code for a block containing the constant
3080 part of a trampoline, leaving space for the variable parts.
3082 On the RX, (where r8 is the static chain regnum) the trampoline
3085 mov #<static chain value>, r8
3086 mov #<function's address>, r9
3089 In big-endian-data-mode however instructions are read into the CPU
3090 4 bytes at a time. These bytes are then swapped around before being
3091 passed to the decoder. So...we must partition our trampoline into
3092 4 byte packets and swap these packets around so that the instruction
3093 reader will reverse the process. But, in order to avoid splitting
3094 the 32-bit constants across these packet boundaries, (making inserting
3095 them into the constructed trampoline very difficult) we have to pad the
3096 instruction sequence with NOP insns. ie:
3108 if (! TARGET_BIG_ENDIAN_DATA
)
3110 asm_fprintf (file
, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM
);
3111 asm_fprintf (file
, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM
);
3112 asm_fprintf (file
, "\tjmp\tr%d\n", TRAMPOLINE_TEMP_REGNUM
);
3116 char r8
= '0' + STATIC_CHAIN_REGNUM
;
3117 char r9
= '0' + TRAMPOLINE_TEMP_REGNUM
;
3119 if (TARGET_AS100_SYNTAX
)
3121 asm_fprintf (file
, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r8
);
3122 asm_fprintf (file
, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
3123 asm_fprintf (file
, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r9
);
3124 asm_fprintf (file
, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
3125 asm_fprintf (file
, "\t.BYTE 003H, 003H, 00%cH, 07fH\n", r9
);
3129 asm_fprintf (file
, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r8
);
3130 asm_fprintf (file
, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
3131 asm_fprintf (file
, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r9
);
3132 asm_fprintf (file
, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
3133 asm_fprintf (file
, "\t.byte 0x03, 0x03, 0x0%c, 0x7f\n", r9
);
3139 rx_trampoline_init (rtx tramp
, tree fndecl
, rtx chain
)
3141 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3143 emit_block_move (tramp
, assemble_trampoline_template (),
3144 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3146 if (TARGET_BIG_ENDIAN_DATA
)
3148 emit_move_insn (adjust_address (tramp
, SImode
, 4), chain
);
3149 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
3153 emit_move_insn (adjust_address (tramp
, SImode
, 2), chain
);
3154 emit_move_insn (adjust_address (tramp
, SImode
, 6 + 2), fnaddr
);
3159 rx_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3160 reg_class_t regclass ATTRIBUTE_UNUSED
,
3163 return (in
? 2 : 0) + REGISTER_MOVE_COST (mode
, regclass
, regclass
);
3166 /* Convert a CC_MODE to the set of flags that it represents. */
3169 flags_from_mode (machine_mode mode
)
3174 return CC_FLAG_S
| CC_FLAG_Z
;
3176 return CC_FLAG_S
| CC_FLAG_Z
| CC_FLAG_O
;
3178 return CC_FLAG_S
| CC_FLAG_Z
| CC_FLAG_C
;
3180 return CC_FLAG_S
| CC_FLAG_Z
| CC_FLAG_O
| CC_FLAG_C
;
3188 /* Convert a set of flags to a CC_MODE that can implement it. */
3191 mode_from_flags (unsigned int f
)
3202 else if (f
& CC_FLAG_C
)
3208 /* Convert an RTX_CODE to the set of flags needed to implement it.
3209 This assumes an integer comparison. */
3212 flags_from_code (enum rtx_code code
)
3221 return CC_FLAG_S
| CC_FLAG_O
| CC_FLAG_Z
;
3227 return CC_FLAG_C
| CC_FLAG_Z
;
3236 /* Return a CC_MODE of which both M1 and M2 are subsets. */
3239 rx_cc_modes_compatible (machine_mode m1
, machine_mode m2
)
3243 /* Early out for identical modes. */
3247 /* There's no valid combination for FP vs non-FP. */
3248 f
= flags_from_mode (m1
) | flags_from_mode (m2
);
3252 /* Otherwise, see what mode can implement all the flags. */
3253 return mode_from_flags (f
);
3256 /* Return the minimal CC mode needed to implement (CMP_CODE X Y). */
3259 rx_select_cc_mode (enum rtx_code cmp_code
, rtx x
, rtx y
)
3261 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
)
3264 if (y
!= const0_rtx
)
3267 return mode_from_flags (flags_from_code (cmp_code
));
3270 /* Split the conditional branch. Emit (COMPARE C1 C2) into CC_REG with
3271 CC_MODE, and use that in branches based on that compare. */
3274 rx_split_cbranch (machine_mode cc_mode
, enum rtx_code cmp1
,
3275 rtx c1
, rtx c2
, rtx label
)
3279 flags
= gen_rtx_REG (cc_mode
, CC_REG
);
3280 x
= gen_rtx_COMPARE (cc_mode
, c1
, c2
);
3281 x
= gen_rtx_SET (flags
, x
);
3284 x
= gen_rtx_fmt_ee (cmp1
, VOIDmode
, flags
, const0_rtx
);
3285 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
, label
, pc_rtx
);
3286 x
= gen_rtx_SET (pc_rtx
, x
);
3290 /* A helper function for matching parallels that set the flags. */
3293 rx_match_ccmode (rtx insn
, machine_mode cc_mode
)
3296 machine_mode flags_mode
;
3298 gcc_checking_assert (XVECLEN (PATTERN (insn
), 0) == 2);
3300 op1
= XVECEXP (PATTERN (insn
), 0, 0);
3301 gcc_checking_assert (GET_CODE (SET_SRC (op1
)) == COMPARE
);
3303 flags
= SET_DEST (op1
);
3304 flags_mode
= GET_MODE (flags
);
3306 if (GET_MODE (SET_SRC (op1
)) != flags_mode
)
3308 if (GET_MODE_CLASS (flags_mode
) != MODE_CC
)
3311 /* Ensure that the mode of FLAGS is compatible with CC_MODE. */
3312 if (flags_from_mode (flags_mode
) & ~flags_from_mode (cc_mode
))
3320 rx_max_skip_for_label (rtx_insn
*lab
)
3334 op
= next_nonnote_nondebug_insn (op
);
3336 while (op
&& (LABEL_P (op
)
3337 || (INSN_P (op
) && GET_CODE (PATTERN (op
)) == USE
)));
3341 opsize
= get_attr_length (op
);
3342 if (opsize
>= 0 && opsize
< 8)
3343 return MAX (0, opsize
- 1);
3348 rx_align_log_for_label (rtx_insn
*lab
, int uses_threshold
)
3350 /* This is a simple heuristic to guess when an alignment would not be useful
3351 because the delay due to the inserted NOPs would be greater than the delay
3352 due to the misaligned branch. If uses_threshold is zero then the alignment
3353 is always useful. */
3354 if (LABEL_P (lab
) && LABEL_NUSES (lab
) < uses_threshold
)
3360 /* Return zero if max_skip not a positive number. */
3361 int max_skip
= rx_max_skip_for_label (lab
);
3365 /* These values are log, not bytes. */
3366 if (rx_cpu_type
== RX100
|| rx_cpu_type
== RX200
)
3367 return 2; /* 4 bytes */
3368 return 3; /* 8 bytes */
3372 rx_align_for_label (rtx_insn
*lab
, int uses_threshold
)
3374 return align_flags (rx_align_log_for_label (lab
, uses_threshold
),
3375 rx_max_skip_for_label (lab
));
3378 /* Compute the real length of the extending load-and-op instructions. */
3381 rx_adjust_insn_length (rtx_insn
*insn
, int current_length
)
3383 rtx extend
, mem
, offset
;
3388 return current_length
;
3390 switch (INSN_CODE (insn
))
3393 return current_length
;
3395 case CODE_FOR_plussi3_zero_extendhi
:
3396 case CODE_FOR_andsi3_zero_extendhi
:
3397 case CODE_FOR_iorsi3_zero_extendhi
:
3398 case CODE_FOR_xorsi3_zero_extendhi
:
3399 case CODE_FOR_divsi3_zero_extendhi
:
3400 case CODE_FOR_udivsi3_zero_extendhi
:
3401 case CODE_FOR_minussi3_zero_extendhi
:
3402 case CODE_FOR_smaxsi3_zero_extendhi
:
3403 case CODE_FOR_sminsi3_zero_extendhi
:
3404 case CODE_FOR_multsi3_zero_extendhi
:
3405 case CODE_FOR_comparesi3_zero_extendhi
:
3410 case CODE_FOR_plussi3_sign_extendhi
:
3411 case CODE_FOR_andsi3_sign_extendhi
:
3412 case CODE_FOR_iorsi3_sign_extendhi
:
3413 case CODE_FOR_xorsi3_sign_extendhi
:
3414 case CODE_FOR_divsi3_sign_extendhi
:
3415 case CODE_FOR_udivsi3_sign_extendhi
:
3416 case CODE_FOR_minussi3_sign_extendhi
:
3417 case CODE_FOR_smaxsi3_sign_extendhi
:
3418 case CODE_FOR_sminsi3_sign_extendhi
:
3419 case CODE_FOR_multsi3_sign_extendhi
:
3420 case CODE_FOR_comparesi3_sign_extendhi
:
3425 case CODE_FOR_plussi3_zero_extendqi
:
3426 case CODE_FOR_andsi3_zero_extendqi
:
3427 case CODE_FOR_iorsi3_zero_extendqi
:
3428 case CODE_FOR_xorsi3_zero_extendqi
:
3429 case CODE_FOR_divsi3_zero_extendqi
:
3430 case CODE_FOR_udivsi3_zero_extendqi
:
3431 case CODE_FOR_minussi3_zero_extendqi
:
3432 case CODE_FOR_smaxsi3_zero_extendqi
:
3433 case CODE_FOR_sminsi3_zero_extendqi
:
3434 case CODE_FOR_multsi3_zero_extendqi
:
3435 case CODE_FOR_comparesi3_zero_extendqi
:
3440 case CODE_FOR_plussi3_sign_extendqi
:
3441 case CODE_FOR_andsi3_sign_extendqi
:
3442 case CODE_FOR_iorsi3_sign_extendqi
:
3443 case CODE_FOR_xorsi3_sign_extendqi
:
3444 case CODE_FOR_divsi3_sign_extendqi
:
3445 case CODE_FOR_udivsi3_sign_extendqi
:
3446 case CODE_FOR_minussi3_sign_extendqi
:
3447 case CODE_FOR_smaxsi3_sign_extendqi
:
3448 case CODE_FOR_sminsi3_sign_extendqi
:
3449 case CODE_FOR_multsi3_sign_extendqi
:
3450 case CODE_FOR_comparesi3_sign_extendqi
:
3456 /* We are expecting: (SET (REG) (<OP> (REG) (<EXTEND> (MEM)))). */
3457 extend
= single_set (insn
);
3458 gcc_assert (extend
!= NULL_RTX
);
3460 extend
= SET_SRC (extend
);
3461 if (GET_CODE (XEXP (extend
, 0)) == ZERO_EXTEND
3462 || GET_CODE (XEXP (extend
, 0)) == SIGN_EXTEND
)
3463 extend
= XEXP (extend
, 0);
3465 extend
= XEXP (extend
, 1);
3467 gcc_assert ((zero
&& (GET_CODE (extend
) == ZERO_EXTEND
))
3468 || (! zero
&& (GET_CODE (extend
) == SIGN_EXTEND
)));
3470 mem
= XEXP (extend
, 0);
3471 gcc_checking_assert (MEM_P (mem
));
3472 if (REG_P (XEXP (mem
, 0)))
3473 return (zero
&& factor
== 1) ? 2 : 3;
3475 /* We are expecting: (MEM (PLUS (REG) (CONST_INT))). */
3476 gcc_checking_assert (GET_CODE (XEXP (mem
, 0)) == PLUS
);
3477 gcc_checking_assert (REG_P (XEXP (XEXP (mem
, 0), 0)));
3479 offset
= XEXP (XEXP (mem
, 0), 1);
3480 gcc_checking_assert (GET_CODE (offset
) == CONST_INT
);
3482 if (IN_RANGE (INTVAL (offset
), 0, 255 * factor
))
3483 return (zero
&& factor
== 1) ? 3 : 4;
3485 return (zero
&& factor
== 1) ? 4 : 5;
3489 rx_narrow_volatile_bitfield (void)
3495 rx_ok_to_inline (tree caller
, tree callee
)
3497 /* Do not inline functions with local variables
3498 into a naked CALLER - naked function have no stack frame and
3499 locals need a frame in order to have somewhere to live.
3501 Unfortunately we have no way to determine the presence of
3502 local variables in CALLEE, so we have to be cautious and
3503 assume that there might be some there.
3505 We do allow inlining when CALLEE has the "inline" type
3506 modifier or the "always_inline" or "gnu_inline" attributes. */
3507 return lookup_attribute ("naked", DECL_ATTRIBUTES (caller
)) == NULL_TREE
3508 || DECL_DECLARED_INLINE_P (callee
)
3509 || lookup_attribute ("always_inline", DECL_ATTRIBUTES (callee
)) != NULL_TREE
3510 || lookup_attribute ("gnu_inline", DECL_ATTRIBUTES (callee
)) != NULL_TREE
;
3514 rx_enable_lra (void)
3516 return TARGET_ENABLE_LRA
;
3519 rx_atomic_sequence::rx_atomic_sequence (const_tree fun_decl
)
3521 if (is_fast_interrupt_func (fun_decl
) || is_interrupt_func (fun_decl
))
3523 /* If we are inside an interrupt handler, assume that interrupts are
3524 off -- which is the default hardware behavior. In this case, there
3525 is no need to disable the interrupts. */
3526 m_prev_psw_reg
= NULL
;
3530 m_prev_psw_reg
= gen_reg_rtx (SImode
);
3531 emit_insn (gen_mvfc (m_prev_psw_reg
, GEN_INT (CTRLREG_PSW
)));
3532 emit_insn (gen_clrpsw (GEN_INT ('I')));
3536 rx_atomic_sequence::~rx_atomic_sequence (void)
3538 if (m_prev_psw_reg
!= NULL
)
3539 emit_insn (gen_mvtc (GEN_INT (CTRLREG_PSW
), m_prev_psw_reg
));
3542 /* Given an insn and a reg number, tell whether the reg dies or is unused
3545 rx_reg_dead_or_unused_after_insn (const rtx_insn
* i
, int regno
)
3547 return find_regno_note (i
, REG_DEAD
, regno
) != NULL
3548 || find_regno_note (i
, REG_UNUSED
, regno
) != NULL
;
3551 /* Copy dead and unused notes from SRC to DST for the specified REGNO. */
3553 rx_copy_reg_dead_or_unused_notes (rtx reg
, const rtx_insn
* src
, rtx_insn
* dst
)
3555 int regno
= REGNO (SUBREG_P (reg
) ? SUBREG_REG (reg
) : reg
);
3557 if (rtx note
= find_regno_note (src
, REG_DEAD
, regno
))
3558 add_shallow_copy_of_reg_note (dst
, note
);
3560 if (rtx note
= find_regno_note (src
, REG_UNUSED
, regno
))
3561 add_shallow_copy_of_reg_note (dst
, note
);
3564 /* Try to fuse the current bit-operation insn with the surrounding memory load
3567 rx_fuse_in_memory_bitop (rtx
* operands
, rtx_insn
* curr_insn
,
3568 rtx (*gen_insn
)(rtx
, rtx
))
3570 rtx op2_reg
= SUBREG_P (operands
[2]) ? SUBREG_REG (operands
[2]) : operands
[2];
3572 set_of_reg op2_def
= rx_find_set_of_reg (op2_reg
, curr_insn
,
3573 prev_nonnote_nondebug_insn_bb
);
3574 if (op2_def
.set_src
== NULL_RTX
3575 || !MEM_P (op2_def
.set_src
)
3576 || GET_MODE (op2_def
.set_src
) != QImode
3577 || !rx_is_restricted_memory_address (XEXP (op2_def
.set_src
, 0),
3578 GET_MODE (op2_def
.set_src
))
3579 || reg_used_between_p (operands
[2], op2_def
.insn
, curr_insn
)
3580 || !rx_reg_dead_or_unused_after_insn (curr_insn
, REGNO (op2_reg
))
3584 /* The register operand originates from a memory load and the memory load
3585 could be fused with the bitop insn.
3586 Look for the following memory store with the same memory operand. */
3587 rtx mem
= op2_def
.set_src
;
3589 /* If the memory is an auto-mod address, it can't be fused. */
3590 if (GET_CODE (XEXP (mem
, 0)) == POST_INC
3591 || GET_CODE (XEXP (mem
, 0)) == PRE_INC
3592 || GET_CODE (XEXP (mem
, 0)) == POST_DEC
3593 || GET_CODE (XEXP (mem
, 0)) == PRE_DEC
)
3596 rtx_insn
* op0_use
= rx_find_use_of_reg (operands
[0], curr_insn
,
3597 next_nonnote_nondebug_insn_bb
);
3599 || !(GET_CODE (PATTERN (op0_use
)) == SET
3600 && RX_REG_P (XEXP (PATTERN (op0_use
), 1))
3601 && reg_overlap_mentioned_p (operands
[0], XEXP (PATTERN (op0_use
), 1))
3602 && rtx_equal_p (mem
, XEXP (PATTERN (op0_use
), 0)))
3603 || !rx_reg_dead_or_unused_after_insn (op0_use
, REGNO (operands
[0]))
3604 || reg_set_between_p (operands
[2], curr_insn
, op0_use
))
3607 /* If the load-modify-store operation is fused it could potentially modify
3608 load/store ordering if there are other memory accesses between the load
3609 and the store for this insn. If there are volatile mems between the load
3610 and store it's better not to change the ordering. If there is a call
3611 between the load and store, it's also not safe to fuse it. */
3612 for (rtx_insn
* i
= next_nonnote_nondebug_insn_bb (op2_def
.insn
);
3613 i
!= NULL
&& i
!= op0_use
;
3614 i
= next_nonnote_nondebug_insn_bb (i
))
3615 if (volatile_insn_p (PATTERN (i
)) || CALL_P (i
))
3618 emit_insn (gen_insn (mem
, gen_lowpart (QImode
, operands
[1])));
3619 set_insn_deleted (op2_def
.insn
);
3620 set_insn_deleted (op0_use
);
3624 /* Implement TARGET_HARD_REGNO_NREGS. */
3627 rx_hard_regno_nregs (unsigned int, machine_mode mode
)
3629 return CLASS_MAX_NREGS (0, mode
);
3632 /* Implement TARGET_HARD_REGNO_MODE_OK. */
3635 rx_hard_regno_mode_ok (unsigned int regno
, machine_mode
)
3637 return REGNO_REG_CLASS (regno
) == GR_REGS
;
3640 /* Implement TARGET_MODES_TIEABLE_P. */
3643 rx_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
3645 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
3646 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
3647 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
3648 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
3651 /* Implement TARGET_C_MODE_FOR_FLOATING_TYPE. Return SFmode or DFmode
3652 for TI_{LONG_,}DOUBLE_TYPE which is for {long,} double type, go with
3653 the default one for the others. */
3656 rx_c_mode_for_floating_type (enum tree_index ti
)
3658 if (ti
== TI_DOUBLE_TYPE
|| ti
== TI_LONG_DOUBLE_TYPE
)
3659 return TARGET_64BIT_DOUBLES
? DFmode
: SFmode
;
3660 return default_mode_for_floating_type (ti
);
3663 #undef TARGET_NARROW_VOLATILE_BITFIELD
3664 #define TARGET_NARROW_VOLATILE_BITFIELD rx_narrow_volatile_bitfield
3666 #undef TARGET_CAN_INLINE_P
3667 #define TARGET_CAN_INLINE_P rx_ok_to_inline
3669 #undef TARGET_FUNCTION_VALUE
3670 #define TARGET_FUNCTION_VALUE rx_function_value
3672 #undef TARGET_RETURN_IN_MSB
3673 #define TARGET_RETURN_IN_MSB rx_return_in_msb
3675 #undef TARGET_IN_SMALL_DATA_P
3676 #define TARGET_IN_SMALL_DATA_P rx_in_small_data
3678 #undef TARGET_RETURN_IN_MEMORY
3679 #define TARGET_RETURN_IN_MEMORY rx_return_in_memory
3681 #undef TARGET_HAVE_SRODATA_SECTION
3682 #define TARGET_HAVE_SRODATA_SECTION true
3684 #undef TARGET_ASM_SELECT_RTX_SECTION
3685 #define TARGET_ASM_SELECT_RTX_SECTION rx_select_rtx_section
3687 #undef TARGET_ASM_SELECT_SECTION
3688 #define TARGET_ASM_SELECT_SECTION rx_select_section
3690 #undef TARGET_INIT_BUILTINS
3691 #define TARGET_INIT_BUILTINS rx_init_builtins
3693 #undef TARGET_BUILTIN_DECL
3694 #define TARGET_BUILTIN_DECL rx_builtin_decl
3696 #undef TARGET_EXPAND_BUILTIN
3697 #define TARGET_EXPAND_BUILTIN rx_expand_builtin
3699 #undef TARGET_ASM_CONSTRUCTOR
3700 #define TARGET_ASM_CONSTRUCTOR rx_elf_asm_constructor
3702 #undef TARGET_ASM_DESTRUCTOR
3703 #define TARGET_ASM_DESTRUCTOR rx_elf_asm_destructor
3705 #undef TARGET_STRUCT_VALUE_RTX
3706 #define TARGET_STRUCT_VALUE_RTX rx_struct_value_rtx
3708 #undef TARGET_ATTRIBUTE_TABLE
3709 #define TARGET_ATTRIBUTE_TABLE rx_attribute_table
3711 #undef TARGET_ASM_FILE_START
3712 #define TARGET_ASM_FILE_START rx_file_start
3714 #undef TARGET_MS_BITFIELD_LAYOUT_P
3715 #define TARGET_MS_BITFIELD_LAYOUT_P rx_is_ms_bitfield_layout
3717 #undef TARGET_LEGITIMATE_ADDRESS_P
3718 #define TARGET_LEGITIMATE_ADDRESS_P rx_is_legitimate_address
3720 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
3721 #define TARGET_MODE_DEPENDENT_ADDRESS_P rx_mode_dependent_address_p
3723 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
3724 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS rx_allocate_stack_slots_for_args
3726 #undef TARGET_ASM_FUNCTION_PROLOGUE
3727 #define TARGET_ASM_FUNCTION_PROLOGUE rx_output_function_prologue
3729 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
3730 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable
3732 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
3733 #define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall
3735 #undef TARGET_FUNCTION_ARG
3736 #define TARGET_FUNCTION_ARG rx_function_arg
3738 #undef TARGET_FUNCTION_ARG_ADVANCE
3739 #define TARGET_FUNCTION_ARG_ADVANCE rx_function_arg_advance
3741 #undef TARGET_FUNCTION_ARG_BOUNDARY
3742 #define TARGET_FUNCTION_ARG_BOUNDARY rx_function_arg_boundary
3744 #undef TARGET_SET_CURRENT_FUNCTION
3745 #define TARGET_SET_CURRENT_FUNCTION rx_set_current_function
3747 #undef TARGET_ASM_INTEGER
3748 #define TARGET_ASM_INTEGER rx_assemble_integer
3750 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
3751 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
3753 #undef TARGET_MAX_ANCHOR_OFFSET
3754 #define TARGET_MAX_ANCHOR_OFFSET 32
3756 #undef TARGET_ADDRESS_COST
3757 #define TARGET_ADDRESS_COST rx_address_cost
3759 #undef TARGET_CAN_ELIMINATE
3760 #define TARGET_CAN_ELIMINATE rx_can_eliminate
3762 #undef TARGET_CONDITIONAL_REGISTER_USAGE
3763 #define TARGET_CONDITIONAL_REGISTER_USAGE rx_conditional_register_usage
3765 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
3766 #define TARGET_ASM_TRAMPOLINE_TEMPLATE rx_trampoline_template
3768 #undef TARGET_TRAMPOLINE_INIT
3769 #define TARGET_TRAMPOLINE_INIT rx_trampoline_init
3771 #undef TARGET_PRINT_OPERAND
3772 #define TARGET_PRINT_OPERAND rx_print_operand
3774 #undef TARGET_PRINT_OPERAND_ADDRESS
3775 #define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address
3777 #undef TARGET_CC_MODES_COMPATIBLE
3778 #define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible
3780 #undef TARGET_MEMORY_MOVE_COST
3781 #define TARGET_MEMORY_MOVE_COST rx_memory_move_cost
3783 #undef TARGET_OPTION_OVERRIDE
3784 #define TARGET_OPTION_OVERRIDE rx_option_override
3786 #undef TARGET_PROMOTE_FUNCTION_MODE
3787 #define TARGET_PROMOTE_FUNCTION_MODE rx_promote_function_mode
3789 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
3790 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rx_override_options_after_change
3792 #undef TARGET_FLAGS_REGNUM
3793 #define TARGET_FLAGS_REGNUM CC_REG
3795 #undef TARGET_LEGITIMATE_CONSTANT_P
3796 #define TARGET_LEGITIMATE_CONSTANT_P rx_is_legitimate_constant
3798 #undef TARGET_LEGITIMIZE_ADDRESS
3799 #define TARGET_LEGITIMIZE_ADDRESS rx_legitimize_address
3801 #undef TARGET_WARN_FUNC_RETURN
3802 #define TARGET_WARN_FUNC_RETURN rx_warn_func_return
3805 #define TARGET_LRA_P rx_enable_lra
3807 #undef TARGET_HARD_REGNO_NREGS
3808 #define TARGET_HARD_REGNO_NREGS rx_hard_regno_nregs
3809 #undef TARGET_HARD_REGNO_MODE_OK
3810 #define TARGET_HARD_REGNO_MODE_OK rx_hard_regno_mode_ok
3812 #undef TARGET_MODES_TIEABLE_P
3813 #define TARGET_MODES_TIEABLE_P rx_modes_tieable_p
3815 #undef TARGET_RTX_COSTS
3816 #define TARGET_RTX_COSTS rx_rtx_costs
3818 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
3819 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
3821 #undef TARGET_C_MODE_FOR_FLOATING_TYPE
3822 #define TARGET_C_MODE_FOR_FLOATING_TYPE rx_c_mode_for_floating_type
3824 struct gcc_target targetm
= TARGET_INITIALIZER
;