1 /* Subroutines used for code generation on Renesas RX processors.
2 Copyright (C) 2008, 2009, 2010, 2011 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. */
27 #include "coretypes.h"
32 #include "hard-reg-set.h"
33 #include "insn-config.h"
34 #include "conditions.h"
36 #include "insn-attr.h"
43 #include "diagnostic-core.h"
51 #include "target-def.h"
52 #include "langhooks.h"
54 static void rx_print_operand (FILE *, rtx, int);
56 #define CC_FLAG_S (1 << 0)
57 #define CC_FLAG_Z (1 << 1)
58 #define CC_FLAG_O (1 << 2)
59 #define CC_FLAG_C (1 << 3)
60 #define CC_FLAG_FP (1 << 4) /* fake, to differentiate CC_Fmode */
62 static unsigned int flags_from_mode (enum machine_mode mode);
63 static unsigned int flags_from_code (enum rtx_code code);
65 enum rx_cpu_types rx_cpu_type = RX600;
67 /* Return true if OP is a reference to an object in a small data area. */
70 rx_small_data_operand (rtx op)
72 if (rx_small_data_limit == 0)
75 if (GET_CODE (op) == SYMBOL_REF)
76 return SYMBOL_REF_SMALL_P (op);
82 rx_is_legitimate_address (Mmode mode, rtx x, bool strict ATTRIBUTE_UNUSED)
84 if (RTX_OK_FOR_BASE (x, strict))
85 /* Register Indirect. */
88 if (GET_MODE_SIZE (mode) == 4
89 && (GET_CODE (x) == PRE_DEC || GET_CODE (x) == POST_INC))
90 /* Pre-decrement Register Indirect or
91 Post-increment Register Indirect. */
92 return RTX_OK_FOR_BASE (XEXP (x, 0), strict);
94 if (GET_CODE (x) == PLUS)
96 rtx arg1 = XEXP (x, 0);
97 rtx arg2 = XEXP (x, 1);
100 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, strict))
102 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, strict))
107 switch (GET_CODE (index))
111 /* Register Relative: REG + INT.
112 Only positive, mode-aligned, mode-sized
113 displacements are allowed. */
114 HOST_WIDE_INT val = INTVAL (index);
120 switch (GET_MODE_SIZE (mode))
123 case 4: factor = 4; break;
124 case 2: factor = 2; break;
125 case 1: factor = 1; break;
128 if (val > (65535 * factor))
130 return (val % factor) == 0;
134 /* Unscaled Indexed Register Indirect: REG + REG
135 Size has to be "QI", REG has to be valid. */
136 return GET_MODE_SIZE (mode) == 1 && RTX_OK_FOR_BASE (index, strict);
140 /* Scaled Indexed Register Indirect: REG + (REG * FACTOR)
141 Factor has to equal the mode size, REG has to be valid. */
144 factor = XEXP (index, 1);
145 index = XEXP (index, 0);
148 && RTX_OK_FOR_BASE (index, strict)
149 && CONST_INT_P (factor)
150 && GET_MODE_SIZE (mode) == INTVAL (factor);
158 /* Small data area accesses turn into register relative offsets. */
159 return rx_small_data_operand (x);
162 /* Returns TRUE for simple memory addreses, ie ones
163 that do not involve register indirect addressing
164 or pre/post increment/decrement. */
167 rx_is_restricted_memory_address (rtx mem, enum machine_mode mode)
171 if (! rx_is_legitimate_address
172 (mode, mem, reload_in_progress || reload_completed))
175 switch (GET_CODE (mem))
178 /* Simple memory addresses are OK. */
186 /* Only allow REG+INT addressing. */
187 base = XEXP (mem, 0);
188 index = XEXP (mem, 1);
190 return RX_REG_P (base) && CONST_INT_P (index);
193 /* Can happen when small data is being supported.
194 Assume that it will be resolved into GP+INT. */
203 rx_is_mode_dependent_addr (rtx addr)
205 if (GET_CODE (addr) == CONST)
206 addr = XEXP (addr, 0);
208 switch (GET_CODE (addr))
210 /* --REG and REG++ only work in SImode. */
217 if (! REG_P (XEXP (addr, 0)))
220 addr = XEXP (addr, 1);
222 switch (GET_CODE (addr))
225 /* REG+REG only works in SImode. */
229 /* REG+INT is only mode independent if INT is a
230 multiple of 4, positive and will fit into 8-bits. */
231 if (((INTVAL (addr) & 3) == 0)
232 && IN_RANGE (INTVAL (addr), 4, 252))
241 gcc_assert (REG_P (XEXP (addr, 0)));
242 gcc_assert (CONST_INT_P (XEXP (addr, 1)));
243 /* REG+REG*SCALE is always mode dependent. */
247 /* Not recognized, so treat as mode dependent. */
255 /* These are all mode independent. */
259 /* Everything else is unrecognized,
260 so treat as mode dependent. */
265 /* A C compound statement to output to stdio stream FILE the
266 assembler syntax for an instruction operand that is a memory
267 reference whose address is ADDR. */
270 rx_print_operand_address (FILE * file, rtx addr)
272 switch (GET_CODE (addr))
276 rx_print_operand (file, addr, 0);
281 fprintf (file, "[-");
282 rx_print_operand (file, XEXP (addr, 0), 0);
288 rx_print_operand (file, XEXP (addr, 0), 0);
289 fprintf (file, "+]");
294 rtx arg1 = XEXP (addr, 0);
295 rtx arg2 = XEXP (addr, 1);
298 if (REG_P (arg1) && RTX_OK_FOR_BASE (arg1, true))
299 base = arg1, index = arg2;
300 else if (REG_P (arg2) && RTX_OK_FOR_BASE (arg2, true))
301 base = arg2, index = arg1;
304 rx_print_operand (file, arg1, 0);
305 fprintf (file, " + ");
306 rx_print_operand (file, arg2, 0);
310 if (REG_P (index) || GET_CODE (index) == MULT)
313 rx_print_operand (file, index, 'A');
316 else /* GET_CODE (index) == CONST_INT */
318 rx_print_operand (file, index, 'A');
321 rx_print_operand (file, base, 0);
327 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
329 addr = XEXP (addr, 0);
330 gcc_assert (XINT (addr, 1) == UNSPEC_CONST);
332 addr = XVECEXP (addr, 0, 0);
333 gcc_assert (CONST_INT_P (addr));
341 output_addr_const (file, addr);
347 rx_print_integer (FILE * file, HOST_WIDE_INT val)
349 if (IN_RANGE (val, -64, 64))
350 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
354 ? "0%" HOST_WIDE_INT_PRINT "xH" : HOST_WIDE_INT_PRINT_HEX,
359 rx_assemble_integer (rtx x, unsigned int size, int is_aligned)
361 const char * op = integer_asm_op (size, is_aligned);
363 if (! CONST_INT_P (x))
364 return default_assemble_integer (x, size, is_aligned);
368 fputs (op, asm_out_file);
370 rx_print_integer (asm_out_file, INTVAL (x));
371 fputc ('\n', asm_out_file);
376 /* Handles the insertion of a single operand into the assembler output.
377 The %<letter> directives supported are:
379 %A Print an operand without a leading # character.
380 %B Print an integer comparison name.
381 %C Print a control register name.
382 %F Print a condition code flag name.
383 %H Print high part of a DImode register, integer or address.
384 %L Print low part of a DImode register, integer or address.
385 %N Print the negation of the immediate value.
386 %Q If the operand is a MEM, then correctly generate
387 register indirect or register relative addressing. */
390 rx_print_operand (FILE * file, rtx op, int letter)
395 /* Print an operand without a leading #. */
399 switch (GET_CODE (op))
403 output_addr_const (file, op);
406 fprintf (file, "%ld", (long) INTVAL (op));
409 rx_print_operand (file, op, 0);
416 enum rtx_code code = GET_CODE (op);
417 enum machine_mode mode = GET_MODE (XEXP (op, 0));
420 if (mode == CC_Fmode)
422 /* C flag is undefined, and O flag carries unordered. None of the
423 branch combinations that include O use it helpfully. */
485 gcc_checking_assert ((flags_from_code (code)
486 & ~flags_from_mode (mode)) == 0);
493 gcc_assert (CONST_INT_P (op));
496 case 0: fprintf (file, "psw"); break;
497 case 2: fprintf (file, "usp"); break;
498 case 3: fprintf (file, "fpsw"); break;
499 case 4: fprintf (file, "cpen"); break;
500 case 8: fprintf (file, "bpsw"); break;
501 case 9: fprintf (file, "bpc"); break;
502 case 0xa: fprintf (file, "isp"); break;
503 case 0xb: fprintf (file, "fintv"); break;
504 case 0xc: fprintf (file, "intb"); break;
506 warning (0, "unreocgnized control register number: %d - using 'psw'",
508 fprintf (file, "psw");
514 gcc_assert (CONST_INT_P (op));
517 case 0: case 'c': case 'C': fprintf (file, "C"); break;
518 case 1: case 'z': case 'Z': fprintf (file, "Z"); break;
519 case 2: case 's': case 'S': fprintf (file, "S"); break;
520 case 3: case 'o': case 'O': fprintf (file, "O"); break;
521 case 8: case 'i': case 'I': fprintf (file, "I"); break;
522 case 9: case 'u': case 'U': fprintf (file, "U"); break;
529 switch (GET_CODE (op))
532 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
536 HOST_WIDE_INT v = INTVAL (op);
539 /* Trickery to avoid problems with shifting 32 bits at a time. */
542 rx_print_integer (file, v);
547 rx_print_integer (file, CONST_DOUBLE_HIGH (op));
550 if (! WORDS_BIG_ENDIAN)
551 op = adjust_address (op, SImode, 4);
552 output_address (XEXP (op, 0));
560 switch (GET_CODE (op))
563 fprintf (file, "%s", reg_names [REGNO (op) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
567 rx_print_integer (file, INTVAL (op) & 0xffffffff);
571 rx_print_integer (file, CONST_DOUBLE_LOW (op));
574 if (WORDS_BIG_ENDIAN)
575 op = adjust_address (op, SImode, 4);
576 output_address (XEXP (op, 0));
584 gcc_assert (CONST_INT_P (op));
586 rx_print_integer (file, - INTVAL (op));
592 HOST_WIDE_INT offset;
598 else if (GET_CODE (op) == PLUS)
602 if (REG_P (XEXP (op, 0)))
604 displacement = XEXP (op, 1);
609 displacement = XEXP (op, 0);
611 gcc_assert (REG_P (op));
614 gcc_assert (CONST_INT_P (displacement));
615 offset = INTVAL (displacement);
616 gcc_assert (offset >= 0);
618 fprintf (file, "%ld", offset);
624 rx_print_operand (file, op, 0);
625 fprintf (file, "].");
627 switch (GET_MODE_SIZE (GET_MODE (op)))
630 gcc_assert (offset < 65535 * 1);
634 gcc_assert (offset % 2 == 0);
635 gcc_assert (offset < 65535 * 2);
639 gcc_assert (offset % 4 == 0);
640 gcc_assert (offset < 65535 * 4);
650 switch (GET_CODE (op))
653 /* Should be the scaled part of an
654 indexed register indirect address. */
656 rtx base = XEXP (op, 0);
657 rtx index = XEXP (op, 1);
659 /* Check for a swaped index register and scaling factor.
660 Not sure if this can happen, but be prepared to handle it. */
661 if (CONST_INT_P (base) && REG_P (index))
668 gcc_assert (REG_P (base));
669 gcc_assert (REGNO (base) < FIRST_PSEUDO_REGISTER);
670 gcc_assert (CONST_INT_P (index));
671 /* Do not try to verify the value of the scalar as it is based
672 on the mode of the MEM not the mode of the MULT. (Which
673 will always be SImode). */
674 fprintf (file, "%s", reg_names [REGNO (base)]);
679 output_address (XEXP (op, 0));
687 gcc_assert (REGNO (op) < FIRST_PSEUDO_REGISTER);
688 fprintf (file, "%s", reg_names [REGNO (op)]);
692 gcc_assert (subreg_regno (op) < FIRST_PSEUDO_REGISTER);
693 fprintf (file, "%s", reg_names [subreg_regno (op)]);
696 /* This will only be single precision.... */
702 REAL_VALUE_FROM_CONST_DOUBLE (rv, op);
703 REAL_VALUE_TO_TARGET_SINGLE (rv, val);
704 fprintf (file, TARGET_AS100_SYNTAX ? "#0%lxH" : "#0x%lx", val);
710 rx_print_integer (file, INTVAL (op));
718 rx_print_operand_address (file, op);
728 /* Returns an assembler template for a move instruction. */
731 rx_gen_move_template (rtx * operands, bool is_movu)
733 static char out_template [64];
734 const char * extension = TARGET_AS100_SYNTAX ? ".L" : "";
735 const char * src_template;
736 const char * dst_template;
737 rtx dest = operands[0];
738 rtx src = operands[1];
740 /* Decide which extension, if any, should be given to the move instruction. */
741 switch (CONST_INT_P (src) ? GET_MODE (dest) : GET_MODE (src))
744 /* The .B extension is not valid when
745 loading an immediate into a register. */
746 if (! REG_P (dest) || ! CONST_INT_P (src))
750 if (! REG_P (dest) || ! CONST_INT_P (src))
751 /* The .W extension is not valid when
752 loading an immediate into a register. */
760 /* This mode is used by constants. */
767 if (MEM_P (src) && rx_small_data_operand (XEXP (src, 0)))
768 src_template = "%%gp(%A1)[r13]";
772 if (MEM_P (dest) && rx_small_data_operand (XEXP (dest, 0)))
773 dst_template = "%%gp(%A0)[r13]";
777 sprintf (out_template, "%s%s\t%s, %s", is_movu ? "movu" : "mov",
778 extension, src_template, dst_template);
782 /* Return VALUE rounded up to the next ALIGNMENT boundary. */
784 static inline unsigned int
785 rx_round_up (unsigned int value, unsigned int alignment)
788 return (value + alignment) & (~ alignment);
791 /* Return the number of bytes in the argument registers
792 occupied by an argument of type TYPE and mode MODE. */
795 rx_function_arg_size (Mmode mode, const_tree type)
797 unsigned int num_bytes;
799 num_bytes = (mode == BLKmode)
800 ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
801 return rx_round_up (num_bytes, UNITS_PER_WORD);
804 #define NUM_ARG_REGS 4
805 #define MAX_NUM_ARG_BYTES (NUM_ARG_REGS * UNITS_PER_WORD)
807 /* Return an RTL expression describing the register holding a function
808 parameter of mode MODE and type TYPE or NULL_RTX if the parameter should
809 be passed on the stack. CUM describes the previous parameters to the
810 function and NAMED is false if the parameter is part of a variable
811 parameter list, or the last named parameter before the start of a
812 variable parameter list. */
815 rx_function_arg (Fargs * cum, Mmode mode, const_tree type, bool named)
817 unsigned int next_reg;
818 unsigned int bytes_so_far = *cum;
820 unsigned int rounded_size;
822 /* An exploded version of rx_function_arg_size. */
823 size = (mode == BLKmode) ? int_size_in_bytes (type) : GET_MODE_SIZE (mode);
824 /* If the size is not known it cannot be passed in registers. */
828 rounded_size = rx_round_up (size, UNITS_PER_WORD);
830 /* Don't pass this arg via registers if there
831 are insufficient registers to hold all of it. */
832 if (rounded_size + bytes_so_far > MAX_NUM_ARG_BYTES)
835 /* Unnamed arguments and the last named argument in a
836 variadic function are always passed on the stack. */
840 /* Structures must occupy an exact number of registers,
841 otherwise they are passed on the stack. */
842 if ((type == NULL || AGGREGATE_TYPE_P (type))
843 && (size % UNITS_PER_WORD) != 0)
846 next_reg = (bytes_so_far / UNITS_PER_WORD) + 1;
848 return gen_rtx_REG (mode, next_reg);
852 rx_function_arg_advance (Fargs * cum, Mmode mode, const_tree type,
853 bool named ATTRIBUTE_UNUSED)
855 *cum += rx_function_arg_size (mode, type);
859 rx_function_arg_boundary (Mmode mode ATTRIBUTE_UNUSED,
860 const_tree type ATTRIBUTE_UNUSED)
865 /* Return an RTL describing where a function return value of type RET_TYPE
869 rx_function_value (const_tree ret_type,
870 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
871 bool outgoing ATTRIBUTE_UNUSED)
873 enum machine_mode mode = TYPE_MODE (ret_type);
875 /* RX ABI specifies that small integer types are
876 promoted to int when returned by a function. */
877 if (GET_MODE_SIZE (mode) > 0 && GET_MODE_SIZE (mode) < 4)
878 return gen_rtx_REG (SImode, FUNC_RETURN_REGNUM);
880 return gen_rtx_REG (mode, FUNC_RETURN_REGNUM);
883 /* TARGET_PROMOTE_FUNCTION_MODE must behave in the same way with
884 regard to function returns as does TARGET_FUNCTION_VALUE. */
886 static enum machine_mode
887 rx_promote_function_mode (const_tree type ATTRIBUTE_UNUSED,
888 enum machine_mode mode,
889 int * punsignedp ATTRIBUTE_UNUSED,
890 const_tree funtype ATTRIBUTE_UNUSED,
894 || GET_MODE_SIZE (mode) >= 4
895 || GET_MODE_SIZE (mode) < 1)
902 rx_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
906 if (TYPE_MODE (type) != BLKmode
907 && ! AGGREGATE_TYPE_P (type))
910 size = int_size_in_bytes (type);
911 /* Large structs and those whose size is not an
912 exact multiple of 4 are returned in memory. */
915 || (size % UNITS_PER_WORD) != 0;
919 rx_struct_value_rtx (tree fndecl ATTRIBUTE_UNUSED,
920 int incoming ATTRIBUTE_UNUSED)
922 return gen_rtx_REG (Pmode, STRUCT_VAL_REGNUM);
926 rx_return_in_msb (const_tree valtype)
928 return TARGET_BIG_ENDIAN_DATA
929 && (AGGREGATE_TYPE_P (valtype) || TREE_CODE (valtype) == COMPLEX_TYPE);
932 /* Returns true if the provided function has the specified attribute. */
935 has_func_attr (const_tree decl, const char * func_attr)
937 if (decl == NULL_TREE)
938 decl = current_function_decl;
940 return lookup_attribute (func_attr, DECL_ATTRIBUTES (decl)) != NULL_TREE;
943 /* Returns true if the provided function has the "fast_interrupt" attribute. */
946 is_fast_interrupt_func (const_tree decl)
948 return has_func_attr (decl, "fast_interrupt");
951 /* Returns true if the provided function has the "interrupt" attribute. */
954 is_interrupt_func (const_tree decl)
956 return has_func_attr (decl, "interrupt");
959 /* Returns true if the provided function has the "naked" attribute. */
962 is_naked_func (const_tree decl)
964 return has_func_attr (decl, "naked");
967 static bool use_fixed_regs = false;
970 rx_conditional_register_usage (void)
972 static bool using_fixed_regs = false;
974 if (rx_small_data_limit > 0)
975 fixed_regs[GP_BASE_REGNUM] = call_used_regs [GP_BASE_REGNUM] = 1;
977 if (use_fixed_regs != using_fixed_regs)
979 static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
980 static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
986 memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
987 memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
989 /* This is for fast interrupt handlers. Any register in
990 the range r10 to r13 (inclusive) that is currently
991 marked as fixed is now a viable, call-used register. */
992 for (r = 10; r <= 13; r++)
996 call_used_regs[r] = 1;
999 /* Mark r7 as fixed. This is just a hack to avoid
1000 altering the reg_alloc_order array so that the newly
1001 freed r10-r13 registers are the preferred registers. */
1002 fixed_regs[7] = call_used_regs[7] = 1;
1006 /* Restore the normal register masks. */
1007 memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
1008 memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
1011 using_fixed_regs = use_fixed_regs;
1015 /* Perform any actions necessary before starting to compile FNDECL.
1016 For the RX we use this to make sure that we have the correct
1017 set of register masks selected. If FNDECL is NULL then we are
1018 compiling top level things. */
1021 rx_set_current_function (tree fndecl)
1023 /* Remember the last target of rx_set_current_function. */
1024 static tree rx_previous_fndecl;
1025 bool prev_was_fast_interrupt;
1026 bool current_is_fast_interrupt;
1028 /* Only change the context if the function changes. This hook is called
1029 several times in the course of compiling a function, and we don't want
1030 to slow things down too much or call target_reinit when it isn't safe. */
1031 if (fndecl == rx_previous_fndecl)
1034 prev_was_fast_interrupt
1035 = rx_previous_fndecl
1036 ? is_fast_interrupt_func (rx_previous_fndecl) : false;
1038 current_is_fast_interrupt
1039 = fndecl ? is_fast_interrupt_func (fndecl) : false;
1041 if (prev_was_fast_interrupt != current_is_fast_interrupt)
1043 use_fixed_regs = current_is_fast_interrupt;
1047 rx_previous_fndecl = fndecl;
1050 /* Typical stack layout should looks like this after the function's prologue:
1055 | | arguments saved | Increasing
1056 | | on the stack | addresses
1057 PARENT arg pointer -> | | /
1058 -------------------------- ---- -------------------
1059 CHILD |ret | return address
1069 frame pointer -> | | /
1072 | | outgoing | Decreasing
1073 | | arguments | addresses
1074 current stack pointer -> | | / |
1075 -------------------------- ---- ------------------ V
1079 bit_count (unsigned int x)
1081 const unsigned int m1 = 0x55555555;
1082 const unsigned int m2 = 0x33333333;
1083 const unsigned int m4 = 0x0f0f0f0f;
1086 x = (x & m2) + ((x >> 2) & m2);
1087 x = (x + (x >> 4)) & m4;
1090 return (x + (x >> 16)) & 0x3f;
1093 #define MUST_SAVE_ACC_REGISTER \
1094 (TARGET_SAVE_ACC_REGISTER \
1095 && (is_interrupt_func (NULL_TREE) \
1096 || is_fast_interrupt_func (NULL_TREE)))
1098 /* Returns either the lowest numbered and highest numbered registers that
1099 occupy the call-saved area of the stack frame, if the registers are
1100 stored as a contiguous block, or else a bitmask of the individual
1101 registers if they are stored piecemeal.
1103 Also computes the size of the frame and the size of the outgoing
1104 arguments block (in bytes). */
1107 rx_get_stack_layout (unsigned int * lowest,
1108 unsigned int * highest,
1109 unsigned int * register_mask,
1110 unsigned int * frame_size,
1111 unsigned int * stack_size)
1116 unsigned int fixed_reg = 0;
1117 unsigned int save_mask;
1118 unsigned int pushed_mask;
1119 unsigned int unneeded_pushes;
1121 if (is_naked_func (NULL_TREE))
1123 /* Naked functions do not create their own stack frame.
1124 Instead the programmer must do that for us. */
1127 * register_mask = 0;
1133 for (save_mask = high = low = 0, reg = 1; reg < CC_REGNUM; reg++)
1135 if ((df_regs_ever_live_p (reg)
1136 /* Always save all call clobbered registers inside interrupt
1137 handlers, even if they are not live - they may be used in
1138 routines called from this one. */
1139 || (call_used_regs[reg] && is_interrupt_func (NULL_TREE)))
1140 && (! call_used_regs[reg]
1141 /* Even call clobbered registered must
1142 be pushed inside interrupt handlers. */
1143 || is_interrupt_func (NULL_TREE)
1144 /* Likewise for fast interrupt handlers, except registers r10 -
1145 r13. These are normally call-saved, but may have been set
1146 to call-used by rx_conditional_register_usage. If so then
1147 they can be used in the fast interrupt handler without
1148 saving them on the stack. */
1149 || (is_fast_interrupt_func (NULL_TREE)
1150 && ! IN_RANGE (reg, 10, 13))))
1156 save_mask |= 1 << reg;
1159 /* Remember if we see a fixed register
1160 after having found the low register. */
1161 if (low != 0 && fixed_reg == 0 && fixed_regs [reg])
1165 /* If we have to save the accumulator register, make sure
1166 that at least two registers are pushed into the frame. */
1167 if (MUST_SAVE_ACC_REGISTER
1168 && bit_count (save_mask) < 2)
1170 save_mask |= (1 << 13) | (1 << 14);
1173 if (high == 0 || low == high)
1177 /* Decide if it would be faster fill in the call-saved area of the stack
1178 frame using multiple PUSH instructions instead of a single PUSHM
1181 SAVE_MASK is a bitmask of the registers that must be stored in the
1182 call-save area. PUSHED_MASK is a bitmask of the registers that would
1183 be pushed into the area if we used a PUSHM instruction. UNNEEDED_PUSHES
1184 is a bitmask of those registers in pushed_mask that are not in
1187 We use a simple heuristic that says that it is better to use
1188 multiple PUSH instructions if the number of unnecessary pushes is
1189 greater than the number of necessary pushes.
1191 We also use multiple PUSH instructions if there are any fixed registers
1192 between LOW and HIGH. The only way that this can happen is if the user
1193 has specified --fixed-<reg-name> on the command line and in such
1194 circumstances we do not want to touch the fixed registers at all.
1196 FIXME: Is it worth improving this heuristic ? */
1197 pushed_mask = (-1 << low) & ~(-1 << (high + 1));
1198 unneeded_pushes = (pushed_mask & (~ save_mask)) & pushed_mask;
1200 if ((fixed_reg && fixed_reg <= high)
1201 || (optimize_function_for_speed_p (cfun)
1202 && bit_count (save_mask) < bit_count (unneeded_pushes)))
1204 /* Use multiple pushes. */
1207 * register_mask = save_mask;
1211 /* Use one push multiple instruction. */
1214 * register_mask = 0;
1217 * frame_size = rx_round_up
1218 (get_frame_size (), STACK_BOUNDARY / BITS_PER_UNIT);
1220 if (crtl->args.size > 0)
1221 * frame_size += rx_round_up
1222 (crtl->args.size, STACK_BOUNDARY / BITS_PER_UNIT);
1224 * stack_size = rx_round_up
1225 (crtl->outgoing_args_size, STACK_BOUNDARY / BITS_PER_UNIT);
1228 /* Generate a PUSHM instruction that matches the given operands. */
1231 rx_emit_stack_pushm (rtx * operands)
1233 HOST_WIDE_INT last_reg;
1236 gcc_assert (CONST_INT_P (operands[0]));
1237 last_reg = (INTVAL (operands[0]) / UNITS_PER_WORD) - 1;
1239 gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1240 first_push = XVECEXP (operands[1], 0, 1);
1241 gcc_assert (SET_P (first_push));
1242 first_push = SET_SRC (first_push);
1243 gcc_assert (REG_P (first_push));
1245 asm_fprintf (asm_out_file, "\tpushm\t%s-%s\n",
1246 reg_names [REGNO (first_push) - last_reg],
1247 reg_names [REGNO (first_push)]);
1250 /* Generate a PARALLEL that will pass the rx_store_multiple_vector predicate. */
1253 gen_rx_store_vector (unsigned int low, unsigned int high)
1256 unsigned int count = (high - low) + 2;
1259 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1261 XVECEXP (vector, 0, 0) =
1262 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1263 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1264 GEN_INT ((count - 1) * UNITS_PER_WORD)));
1266 for (i = 0; i < count - 1; i++)
1267 XVECEXP (vector, 0, i + 1) =
1268 gen_rtx_SET (VOIDmode,
1269 gen_rtx_MEM (SImode,
1270 gen_rtx_MINUS (SImode, stack_pointer_rtx,
1271 GEN_INT ((i + 1) * UNITS_PER_WORD))),
1272 gen_rtx_REG (SImode, high - i));
1276 /* Mark INSN as being frame related. If it is a PARALLEL
1277 then mark each element as being frame related as well. */
1280 mark_frame_related (rtx insn)
1282 RTX_FRAME_RELATED_P (insn) = 1;
1283 insn = PATTERN (insn);
1285 if (GET_CODE (insn) == PARALLEL)
1289 for (i = 0; i < (unsigned) XVECLEN (insn, 0); i++)
1290 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, i)) = 1;
1295 ok_for_max_constant (HOST_WIDE_INT val)
1297 if (rx_max_constant_size == 0 || rx_max_constant_size == 4)
1298 /* If there is no constraint on the size of constants
1299 used as operands, then any value is legitimate. */
1302 /* rx_max_constant_size specifies the maximum number
1303 of bytes that can be used to hold a signed value. */
1304 return IN_RANGE (val, (-1 << (rx_max_constant_size * 8)),
1305 ( 1 << (rx_max_constant_size * 8)));
1308 /* Generate an ADD of SRC plus VAL into DEST.
1309 Handles the case where VAL is too big for max_constant_value.
1310 Sets FRAME_RELATED_P on the insn if IS_FRAME_RELATED is true. */
1313 gen_safe_add (rtx dest, rtx src, rtx val, bool is_frame_related)
1317 if (val == NULL_RTX || INTVAL (val) == 0)
1319 gcc_assert (dest != src);
1321 insn = emit_move_insn (dest, src);
1323 else if (ok_for_max_constant (INTVAL (val)))
1324 insn = emit_insn (gen_addsi3 (dest, src, val));
1327 insn = emit_insn (gen_addsi3_unspec (dest, src, val));
1329 if (is_frame_related)
1330 /* We have to provide our own frame related note here
1331 as the dwarf2out code cannot be expected to grok
1333 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
1334 gen_rtx_SET (SImode, dest,
1335 gen_rtx_PLUS (SImode, src, val)));
1339 if (is_frame_related)
1340 RTX_FRAME_RELATED_P (insn) = 1;
1345 rx_expand_prologue (void)
1347 unsigned int stack_size;
1348 unsigned int frame_size;
1355 /* Naked functions use their own, programmer provided prologues. */
1356 if (is_naked_func (NULL_TREE))
1359 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1361 /* If we use any of the callee-saved registers, save them now. */
1364 /* Push registers in reverse order. */
1365 for (reg = CC_REGNUM; reg --;)
1366 if (mask & (1 << reg))
1368 insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, reg)));
1369 mark_frame_related (insn);
1375 insn = emit_insn (gen_stack_push (gen_rtx_REG (SImode, low)));
1377 insn = emit_insn (gen_stack_pushm (GEN_INT (((high - low) + 1)
1379 gen_rx_store_vector (low, high)));
1380 mark_frame_related (insn);
1383 if (MUST_SAVE_ACC_REGISTER)
1385 unsigned int acc_high, acc_low;
1387 /* Interrupt handlers have to preserve the accumulator
1388 register if so requested by the user. Use the first
1389 two pushed registers as intermediaries. */
1392 acc_low = acc_high = 0;
1394 for (reg = 1; reg < CC_REGNUM; reg ++)
1395 if (mask & (1 << reg))
1406 /* We have assumed that there are at least two registers pushed... */
1407 gcc_assert (acc_high != 0);
1409 /* Note - the bottom 16 bits of the accumulator are inaccessible.
1410 We just assume that they are zero. */
1411 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1412 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1413 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_low)));
1414 emit_insn (gen_stack_push (gen_rtx_REG (SImode, acc_high)));
1421 /* We have assumed that there are at least two registers pushed... */
1422 gcc_assert (acc_high <= high);
1424 emit_insn (gen_mvfacmi (gen_rtx_REG (SImode, acc_low)));
1425 emit_insn (gen_mvfachi (gen_rtx_REG (SImode, acc_high)));
1426 emit_insn (gen_stack_pushm (GEN_INT (2 * UNITS_PER_WORD),
1427 gen_rx_store_vector (acc_low, acc_high)));
1431 /* If needed, set up the frame pointer. */
1432 if (frame_pointer_needed)
1433 gen_safe_add (frame_pointer_rtx, stack_pointer_rtx,
1434 GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1436 /* Allocate space for the outgoing args.
1437 If the stack frame has not already been set up then handle this as well. */
1442 if (frame_pointer_needed)
1443 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx,
1444 GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1446 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1447 GEN_INT (- (HOST_WIDE_INT) (frame_size + stack_size)),
1451 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1452 GEN_INT (- (HOST_WIDE_INT) stack_size), true);
1454 else if (frame_size)
1456 if (! frame_pointer_needed)
1457 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1458 GEN_INT (- (HOST_WIDE_INT) frame_size), true);
1460 gen_safe_add (stack_pointer_rtx, frame_pointer_rtx, NULL_RTX,
1466 rx_output_function_prologue (FILE * file,
1467 HOST_WIDE_INT frame_size ATTRIBUTE_UNUSED)
1469 if (is_fast_interrupt_func (NULL_TREE))
1470 asm_fprintf (file, "\t; Note: Fast Interrupt Handler\n");
1472 if (is_interrupt_func (NULL_TREE))
1473 asm_fprintf (file, "\t; Note: Interrupt Handler\n");
1475 if (is_naked_func (NULL_TREE))
1476 asm_fprintf (file, "\t; Note: Naked Function\n");
1478 if (cfun->static_chain_decl != NULL)
1479 asm_fprintf (file, "\t; Note: Nested function declared "
1480 "inside another function.\n");
1482 if (crtl->calls_eh_return)
1483 asm_fprintf (file, "\t; Note: Calls __builtin_eh_return.\n");
1486 /* Generate a POPM or RTSD instruction that matches the given operands. */
1489 rx_emit_stack_popm (rtx * operands, bool is_popm)
1491 HOST_WIDE_INT stack_adjust;
1492 HOST_WIDE_INT last_reg;
1495 gcc_assert (CONST_INT_P (operands[0]));
1496 stack_adjust = INTVAL (operands[0]);
1498 gcc_assert (GET_CODE (operands[1]) == PARALLEL);
1499 last_reg = XVECLEN (operands[1], 0) - (is_popm ? 2 : 3);
1501 first_push = XVECEXP (operands[1], 0, 1);
1502 gcc_assert (SET_P (first_push));
1503 first_push = SET_DEST (first_push);
1504 gcc_assert (REG_P (first_push));
1507 asm_fprintf (asm_out_file, "\tpopm\t%s-%s\n",
1508 reg_names [REGNO (first_push)],
1509 reg_names [REGNO (first_push) + last_reg]);
1511 asm_fprintf (asm_out_file, "\trtsd\t#%d, %s-%s\n",
1513 reg_names [REGNO (first_push)],
1514 reg_names [REGNO (first_push) + last_reg]);
1517 /* Generate a PARALLEL which will satisfy the rx_rtsd_vector predicate. */
1520 gen_rx_rtsd_vector (unsigned int adjust, unsigned int low, unsigned int high)
1523 unsigned int bias = 3;
1524 unsigned int count = (high - low) + bias;
1527 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1529 XVECEXP (vector, 0, 0) =
1530 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1531 plus_constant (stack_pointer_rtx, adjust));
1533 for (i = 0; i < count - 2; i++)
1534 XVECEXP (vector, 0, i + 1) =
1535 gen_rtx_SET (VOIDmode,
1536 gen_rtx_REG (SImode, low + i),
1537 gen_rtx_MEM (SImode,
1538 i == 0 ? stack_pointer_rtx
1539 : plus_constant (stack_pointer_rtx,
1540 i * UNITS_PER_WORD)));
1542 XVECEXP (vector, 0, count - 1) = gen_rtx_RETURN (VOIDmode);
1547 /* Generate a PARALLEL which will satisfy the rx_load_multiple_vector predicate. */
1550 gen_rx_popm_vector (unsigned int low, unsigned int high)
1553 unsigned int count = (high - low) + 2;
1556 vector = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
1558 XVECEXP (vector, 0, 0) =
1559 gen_rtx_SET (VOIDmode, stack_pointer_rtx,
1560 plus_constant (stack_pointer_rtx,
1561 (count - 1) * UNITS_PER_WORD));
1563 for (i = 0; i < count - 1; i++)
1564 XVECEXP (vector, 0, i + 1) =
1565 gen_rtx_SET (VOIDmode,
1566 gen_rtx_REG (SImode, low + i),
1567 gen_rtx_MEM (SImode,
1568 i == 0 ? stack_pointer_rtx
1569 : plus_constant (stack_pointer_rtx,
1570 i * UNITS_PER_WORD)));
1576 rx_expand_epilogue (bool is_sibcall)
1580 unsigned int frame_size;
1581 unsigned int stack_size;
1582 unsigned int register_mask;
1583 unsigned int regs_size;
1585 unsigned HOST_WIDE_INT total_size;
1587 /* FIXME: We do not support indirect sibcalls at the moment becaause we
1588 cannot guarantee that the register holding the function address is a
1589 call-used register. If it is a call-saved register then the stack
1590 pop instructions generated in the epilogue will corrupt the address
1593 Creating a new call-used-only register class works but then the
1594 reload pass gets stuck because it cannot always find a call-used
1595 register for spilling sibcalls.
1597 The other possible solution is for this pass to scan forward for the
1598 sibcall instruction (if it has been generated) and work out if it
1599 is an indirect sibcall using a call-saved register. If it is then
1600 the address can copied into a call-used register in this epilogue
1601 code and the sibcall instruction modified to use that register. */
1603 if (is_naked_func (NULL_TREE))
1605 gcc_assert (! is_sibcall);
1607 /* Naked functions use their own, programmer provided epilogues.
1608 But, in order to keep gcc happy we have to generate some kind of
1610 emit_jump_insn (gen_naked_return ());
1614 rx_get_stack_layout (& low, & high, & register_mask,
1615 & frame_size, & stack_size);
1617 total_size = frame_size + stack_size;
1618 regs_size = ((high - low) + 1) * UNITS_PER_WORD;
1620 /* See if we are unable to use the special stack frame deconstruct and
1621 return instructions. In most cases we can use them, but the exceptions
1624 - Sibling calling functions deconstruct the frame but do not return to
1625 their caller. Instead they branch to their sibling and allow their
1626 return instruction to return to this function's parent.
1628 - Fast and normal interrupt handling functions have to use special
1629 return instructions.
1631 - Functions where we have pushed a fragmented set of registers into the
1632 call-save area must have the same set of registers popped. */
1634 || is_fast_interrupt_func (NULL_TREE)
1635 || is_interrupt_func (NULL_TREE)
1638 /* Cannot use the special instructions - deconstruct by hand. */
1640 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1641 GEN_INT (total_size), false);
1643 if (MUST_SAVE_ACC_REGISTER)
1645 unsigned int acc_low, acc_high;
1647 /* Reverse the saving of the accumulator register onto the stack.
1648 Note we must adjust the saved "low" accumulator value as it
1649 is really the middle 32-bits of the accumulator. */
1652 acc_low = acc_high = 0;
1654 for (reg = 1; reg < CC_REGNUM; reg ++)
1655 if (register_mask & (1 << reg))
1665 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_high)));
1666 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, acc_low)));
1672 emit_insn (gen_stack_popm (GEN_INT (2 * UNITS_PER_WORD),
1673 gen_rx_popm_vector (acc_low, acc_high)));
1676 emit_insn (gen_ashlsi3 (gen_rtx_REG (SImode, acc_low),
1677 gen_rtx_REG (SImode, acc_low),
1679 emit_insn (gen_mvtaclo (gen_rtx_REG (SImode, acc_low)));
1680 emit_insn (gen_mvtachi (gen_rtx_REG (SImode, acc_high)));
1685 for (reg = 0; reg < CC_REGNUM; reg ++)
1686 if (register_mask & (1 << reg))
1687 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, reg)));
1692 emit_insn (gen_stack_pop (gen_rtx_REG (SImode, low)));
1694 emit_insn (gen_stack_popm (GEN_INT (regs_size),
1695 gen_rx_popm_vector (low, high)));
1698 if (is_fast_interrupt_func (NULL_TREE))
1700 gcc_assert (! is_sibcall);
1701 emit_jump_insn (gen_fast_interrupt_return ());
1703 else if (is_interrupt_func (NULL_TREE))
1705 gcc_assert (! is_sibcall);
1706 emit_jump_insn (gen_exception_return ());
1708 else if (! is_sibcall)
1709 emit_jump_insn (gen_simple_return ());
1714 /* If we allocated space on the stack, free it now. */
1717 unsigned HOST_WIDE_INT rtsd_size;
1719 /* See if we can use the RTSD instruction. */
1720 rtsd_size = total_size + regs_size;
1721 if (rtsd_size < 1024 && (rtsd_size % 4) == 0)
1724 emit_jump_insn (gen_pop_and_return
1725 (GEN_INT (rtsd_size),
1726 gen_rx_rtsd_vector (rtsd_size, low, high)));
1728 emit_jump_insn (gen_deallocate_and_return (GEN_INT (total_size)));
1733 gen_safe_add (stack_pointer_rtx, stack_pointer_rtx,
1734 GEN_INT (total_size), false);
1738 emit_jump_insn (gen_pop_and_return (GEN_INT (regs_size),
1739 gen_rx_rtsd_vector (regs_size,
1742 emit_jump_insn (gen_simple_return ());
1746 /* Compute the offset (in words) between FROM (arg pointer
1747 or frame pointer) and TO (frame pointer or stack pointer).
1748 See ASCII art comment at the start of rx_expand_prologue
1749 for more information. */
1752 rx_initial_elimination_offset (int from, int to)
1756 unsigned int frame_size;
1757 unsigned int stack_size;
1760 rx_get_stack_layout (& low, & high, & mask, & frame_size, & stack_size);
1762 if (from == ARG_POINTER_REGNUM)
1764 /* Extend the computed size of the stack frame to
1765 include the registers pushed in the prologue. */
1767 frame_size += ((high - low) + 1) * UNITS_PER_WORD;
1769 frame_size += bit_count (mask) * UNITS_PER_WORD;
1771 /* Remember to include the return address. */
1772 frame_size += 1 * UNITS_PER_WORD;
1774 if (to == FRAME_POINTER_REGNUM)
1777 gcc_assert (to == STACK_POINTER_REGNUM);
1778 return frame_size + stack_size;
1781 gcc_assert (from == FRAME_POINTER_REGNUM && to == STACK_POINTER_REGNUM);
1785 /* Decide if a variable should go into one of the small data sections. */
1788 rx_in_small_data (const_tree decl)
1793 if (rx_small_data_limit == 0)
1796 if (TREE_CODE (decl) != VAR_DECL)
1799 /* We do not put read-only variables into a small data area because
1800 they would be placed with the other read-only sections, far away
1801 from the read-write data sections, and we only have one small
1803 Similarly commons are placed in the .bss section which might be
1804 far away (and out of alignment with respect to) the .data section. */
1805 if (TREE_READONLY (decl) || DECL_COMMON (decl))
1808 section = DECL_SECTION_NAME (decl);
1811 const char * const name = TREE_STRING_POINTER (section);
1813 return (strcmp (name, "D_2") == 0) || (strcmp (name, "B_2") == 0);
1816 size = int_size_in_bytes (TREE_TYPE (decl));
1818 return (size > 0) && (size <= rx_small_data_limit);
1821 /* Return a section for X.
1822 The only special thing we do here is to honor small data. */
1825 rx_select_rtx_section (enum machine_mode mode,
1827 unsigned HOST_WIDE_INT align)
1829 if (rx_small_data_limit > 0
1830 && GET_MODE_SIZE (mode) <= rx_small_data_limit
1831 && align <= (unsigned HOST_WIDE_INT) rx_small_data_limit * BITS_PER_UNIT)
1832 return sdata_section;
1834 return default_elf_select_rtx_section (mode, x, align);
1838 rx_select_section (tree decl,
1840 unsigned HOST_WIDE_INT align)
1842 if (rx_small_data_limit > 0)
1844 switch (categorize_decl_for_section (decl, reloc))
1846 case SECCAT_SDATA: return sdata_section;
1847 case SECCAT_SBSS: return sbss_section;
1848 case SECCAT_SRODATA:
1849 /* Fall through. We do not put small, read only
1850 data into the C_2 section because we are not
1851 using the C_2 section. We do not use the C_2
1852 section because it is located with the other
1853 read-only data sections, far away from the read-write
1854 data sections and we only have one small data
1861 /* If we are supporting the Renesas assembler
1862 we cannot use mergeable sections. */
1863 if (TARGET_AS100_SYNTAX)
1864 switch (categorize_decl_for_section (decl, reloc))
1866 case SECCAT_RODATA_MERGE_CONST:
1867 case SECCAT_RODATA_MERGE_STR_INIT:
1868 case SECCAT_RODATA_MERGE_STR:
1869 return readonly_data_section;
1875 return default_elf_select_section (decl, reloc, align);
1904 rx_init_builtins (void)
1906 #define ADD_RX_BUILTIN1(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE) \
1907 add_builtin_function ("__builtin_rx_" LC_NAME, \
1908 build_function_type_list (RET_TYPE##_type_node, \
1909 ARG_TYPE##_type_node, \
1911 RX_BUILTIN_##UC_NAME, \
1912 BUILT_IN_MD, NULL, NULL_TREE)
1914 #define ADD_RX_BUILTIN2(UC_NAME, LC_NAME, RET_TYPE, ARG_TYPE1, ARG_TYPE2) \
1915 add_builtin_function ("__builtin_rx_" LC_NAME, \
1916 build_function_type_list (RET_TYPE##_type_node, \
1917 ARG_TYPE1##_type_node,\
1918 ARG_TYPE2##_type_node,\
1920 RX_BUILTIN_##UC_NAME, \
1921 BUILT_IN_MD, NULL, NULL_TREE)
1923 #define ADD_RX_BUILTIN3(UC_NAME,LC_NAME,RET_TYPE,ARG_TYPE1,ARG_TYPE2,ARG_TYPE3) \
1924 add_builtin_function ("__builtin_rx_" LC_NAME, \
1925 build_function_type_list (RET_TYPE##_type_node, \
1926 ARG_TYPE1##_type_node,\
1927 ARG_TYPE2##_type_node,\
1928 ARG_TYPE3##_type_node,\
1930 RX_BUILTIN_##UC_NAME, \
1931 BUILT_IN_MD, NULL, NULL_TREE)
1933 ADD_RX_BUILTIN1 (BRK, "brk", void, void);
1934 ADD_RX_BUILTIN1 (CLRPSW, "clrpsw", void, integer);
1935 ADD_RX_BUILTIN1 (SETPSW, "setpsw", void, integer);
1936 ADD_RX_BUILTIN1 (INT, "int", void, integer);
1937 ADD_RX_BUILTIN2 (MACHI, "machi", void, intSI, intSI);
1938 ADD_RX_BUILTIN2 (MACLO, "maclo", void, intSI, intSI);
1939 ADD_RX_BUILTIN2 (MULHI, "mulhi", void, intSI, intSI);
1940 ADD_RX_BUILTIN2 (MULLO, "mullo", void, intSI, intSI);
1941 ADD_RX_BUILTIN1 (MVFACHI, "mvfachi", intSI, void);
1942 ADD_RX_BUILTIN1 (MVFACMI, "mvfacmi", intSI, void);
1943 ADD_RX_BUILTIN1 (MVTACHI, "mvtachi", void, intSI);
1944 ADD_RX_BUILTIN1 (MVTACLO, "mvtaclo", void, intSI);
1945 ADD_RX_BUILTIN1 (RMPA, "rmpa", void, void);
1946 ADD_RX_BUILTIN1 (MVFC, "mvfc", intSI, integer);
1947 ADD_RX_BUILTIN2 (MVTC, "mvtc", void, integer, integer);
1948 ADD_RX_BUILTIN1 (MVTIPL, "mvtipl", void, integer);
1949 ADD_RX_BUILTIN1 (RACW, "racw", void, integer);
1950 ADD_RX_BUILTIN1 (ROUND, "round", intSI, float);
1951 ADD_RX_BUILTIN1 (REVW, "revw", intSI, intSI);
1952 ADD_RX_BUILTIN1 (WAIT, "wait", void, void);
1956 rx_expand_void_builtin_1_arg (rtx arg, rtx (* gen_func)(rtx), bool reg)
1958 if (reg && ! REG_P (arg))
1959 arg = force_reg (SImode, arg);
1961 emit_insn (gen_func (arg));
1967 rx_expand_builtin_mvtc (tree exp)
1969 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
1970 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
1972 if (! CONST_INT_P (arg1))
1976 arg2 = force_reg (SImode, arg2);
1978 emit_insn (gen_mvtc (arg1, arg2));
1984 rx_expand_builtin_mvfc (tree t_arg, rtx target)
1986 rtx arg = expand_normal (t_arg);
1988 if (! CONST_INT_P (arg))
1991 if (target == NULL_RTX)
1994 if (! REG_P (target))
1995 target = force_reg (SImode, target);
1997 emit_insn (gen_mvfc (target, arg));
2003 rx_expand_builtin_mvtipl (rtx arg)
2005 /* The RX610 does not support the MVTIPL instruction. */
2006 if (rx_cpu_type == RX610)
2009 if (! CONST_INT_P (arg) || ! IN_RANGE (INTVAL (arg), 0, (1 << 4) - 1))
2012 emit_insn (gen_mvtipl (arg));
2018 rx_expand_builtin_mac (tree exp, rtx (* gen_func)(rtx, rtx))
2020 rtx arg1 = expand_normal (CALL_EXPR_ARG (exp, 0));
2021 rtx arg2 = expand_normal (CALL_EXPR_ARG (exp, 1));
2024 arg1 = force_reg (SImode, arg1);
2027 arg2 = force_reg (SImode, arg2);
2029 emit_insn (gen_func (arg1, arg2));
2035 rx_expand_int_builtin_1_arg (rtx arg,
2037 rtx (* gen_func)(rtx, rtx),
2041 if (!mem_ok || ! MEM_P (arg))
2042 arg = force_reg (SImode, arg);
2044 if (target == NULL_RTX || ! REG_P (target))
2045 target = gen_reg_rtx (SImode);
2047 emit_insn (gen_func (target, arg));
2053 rx_expand_int_builtin_0_arg (rtx target, rtx (* gen_func)(rtx))
2055 if (target == NULL_RTX || ! REG_P (target))
2056 target = gen_reg_rtx (SImode);
2058 emit_insn (gen_func (target));
2064 rx_expand_builtin_round (rtx arg, rtx target)
2066 if ((! REG_P (arg) && ! MEM_P (arg))
2067 || GET_MODE (arg) != SFmode)
2068 arg = force_reg (SFmode, arg);
2070 if (target == NULL_RTX || ! REG_P (target))
2071 target = gen_reg_rtx (SImode);
2073 emit_insn (gen_lrintsf2 (target, arg));
2079 valid_psw_flag (rtx op, const char *which)
2081 static int mvtc_inform_done = 0;
2083 if (GET_CODE (op) == CONST_INT)
2084 switch (INTVAL (op))
2086 case 0: case 'c': case 'C':
2087 case 1: case 'z': case 'Z':
2088 case 2: case 's': case 'S':
2089 case 3: case 'o': case 'O':
2090 case 8: case 'i': case 'I':
2091 case 9: case 'u': case 'U':
2095 error ("__builtin_rx_%s takes 'C', 'Z', 'S', 'O', 'I', or 'U'", which);
2096 if (!mvtc_inform_done)
2097 error ("use __builtin_rx_mvtc (0, ... ) to write arbitrary values to PSW");
2098 mvtc_inform_done = 1;
2104 rx_expand_builtin (tree exp,
2106 rtx subtarget ATTRIBUTE_UNUSED,
2107 enum machine_mode mode ATTRIBUTE_UNUSED,
2108 int ignore ATTRIBUTE_UNUSED)
2110 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
2111 tree arg = call_expr_nargs (exp) >= 1 ? CALL_EXPR_ARG (exp, 0) : NULL_TREE;
2112 rtx op = arg ? expand_normal (arg) : NULL_RTX;
2113 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
2117 case RX_BUILTIN_BRK: emit_insn (gen_brk ()); return NULL_RTX;
2118 case RX_BUILTIN_CLRPSW:
2119 if (!valid_psw_flag (op, "clrpsw"))
2121 return rx_expand_void_builtin_1_arg (op, gen_clrpsw, false);
2122 case RX_BUILTIN_SETPSW:
2123 if (!valid_psw_flag (op, "setpsw"))
2125 return rx_expand_void_builtin_1_arg (op, gen_setpsw, false);
2126 case RX_BUILTIN_INT: return rx_expand_void_builtin_1_arg
2127 (op, gen_int, false);
2128 case RX_BUILTIN_MACHI: return rx_expand_builtin_mac (exp, gen_machi);
2129 case RX_BUILTIN_MACLO: return rx_expand_builtin_mac (exp, gen_maclo);
2130 case RX_BUILTIN_MULHI: return rx_expand_builtin_mac (exp, gen_mulhi);
2131 case RX_BUILTIN_MULLO: return rx_expand_builtin_mac (exp, gen_mullo);
2132 case RX_BUILTIN_MVFACHI: return rx_expand_int_builtin_0_arg
2133 (target, gen_mvfachi);
2134 case RX_BUILTIN_MVFACMI: return rx_expand_int_builtin_0_arg
2135 (target, gen_mvfacmi);
2136 case RX_BUILTIN_MVTACHI: return rx_expand_void_builtin_1_arg
2137 (op, gen_mvtachi, true);
2138 case RX_BUILTIN_MVTACLO: return rx_expand_void_builtin_1_arg
2139 (op, gen_mvtaclo, true);
2140 case RX_BUILTIN_RMPA: emit_insn (gen_rmpa ()); return NULL_RTX;
2141 case RX_BUILTIN_MVFC: return rx_expand_builtin_mvfc (arg, target);
2142 case RX_BUILTIN_MVTC: return rx_expand_builtin_mvtc (exp);
2143 case RX_BUILTIN_MVTIPL: return rx_expand_builtin_mvtipl (op);
2144 case RX_BUILTIN_RACW: return rx_expand_void_builtin_1_arg
2145 (op, gen_racw, false);
2146 case RX_BUILTIN_ROUND: return rx_expand_builtin_round (op, target);
2147 case RX_BUILTIN_REVW: return rx_expand_int_builtin_1_arg
2148 (op, target, gen_revw, false);
2149 case RX_BUILTIN_WAIT: emit_insn (gen_wait ()); return NULL_RTX;
2152 internal_error ("bad builtin code");
2159 /* Place an element into a constructor or destructor section.
2160 Like default_ctor_section_asm_out_constructor in varasm.c
2161 except that it uses .init_array (or .fini_array) and it
2162 handles constructor priorities. */
2165 rx_elf_asm_cdtor (rtx symbol, int priority, bool is_ctor)
2169 if (priority != DEFAULT_INIT_PRIORITY)
2173 sprintf (buf, "%s.%.5u",
2174 is_ctor ? ".init_array" : ".fini_array",
2176 s = get_section (buf, SECTION_WRITE, NULL_TREE);
2183 switch_to_section (s);
2184 assemble_align (POINTER_SIZE);
2185 assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1);
2189 rx_elf_asm_constructor (rtx symbol, int priority)
2191 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */true);
2195 rx_elf_asm_destructor (rtx symbol, int priority)
2197 rx_elf_asm_cdtor (symbol, priority, /* is_ctor= */false);
2200 /* Check "fast_interrupt", "interrupt" and "naked" attributes. */
2203 rx_handle_func_attribute (tree * node,
2206 int flags ATTRIBUTE_UNUSED,
2207 bool * no_add_attrs)
2209 gcc_assert (DECL_P (* node));
2210 gcc_assert (args == NULL_TREE);
2212 if (TREE_CODE (* node) != FUNCTION_DECL)
2214 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2216 * no_add_attrs = true;
2219 /* FIXME: We ought to check for conflicting attributes. */
2221 /* FIXME: We ought to check that the interrupt and exception
2222 handler attributes have been applied to void functions. */
2226 /* Table of RX specific attributes. */
2227 const struct attribute_spec rx_attribute_table[] =
2229 /* Name, min_len, max_len, decl_req, type_req, fn_type_req, handler. */
2230 { "fast_interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
2231 { "interrupt", 0, 0, true, false, false, rx_handle_func_attribute },
2232 { "naked", 0, 0, true, false, false, rx_handle_func_attribute },
2233 { NULL, 0, 0, false, false, false, NULL }
2236 /* Extra processing for target specific command line options. */
2239 rx_handle_option (size_t code, const char * arg ATTRIBUTE_UNUSED, int value)
2243 case OPT_mint_register_:
2247 fixed_regs[10] = call_used_regs [10] = 1;
2250 fixed_regs[11] = call_used_regs [11] = 1;
2253 fixed_regs[12] = call_used_regs [12] = 1;
2256 fixed_regs[13] = call_used_regs [13] = 1;
2265 case OPT_mmax_constant_size_:
2266 /* Make sure that the -mmax-constant_size option is in range. */
2267 return value >= 0 && value <= 4;
2270 if (strcasecmp (arg, "RX610") == 0)
2271 rx_cpu_type = RX610;
2272 else if (strcasecmp (arg, "RX200") == 0)
2274 target_flags |= MASK_NO_USE_FPU;
2275 rx_cpu_type = RX200;
2277 else if (strcasecmp (arg, "RX600") != 0)
2278 warning (0, "unrecognized argument '%s' to -mcpu= option", arg);
2282 if (rx_cpu_type == RX200)
2283 error ("the RX200 cpu does not have FPU hardware");
2293 /* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE. */
2296 rx_override_options_after_change (void)
2298 static bool first_time = TRUE;
2302 /* If this is the first time through and the user has not disabled
2303 the use of RX FPU hardware then enable -ffinite-math-only,
2304 since the FPU instructions do not support NaNs and infinities. */
2306 flag_finite_math_only = 1;
2312 /* Alert the user if they are changing the optimization options
2313 to use IEEE compliant floating point arithmetic with RX FPU insns. */
2315 && !flag_finite_math_only)
2316 warning (0, "RX FPU instructions do not support NaNs and infinities");
2321 rx_option_override (void)
2323 /* This target defaults to strict volatile bitfields. */
2324 if (flag_strict_volatile_bitfields < 0)
2325 flag_strict_volatile_bitfields = 1;
2327 rx_override_options_after_change ();
2330 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
2331 static const struct default_options rx_option_optimization_table[] =
2333 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
2334 { OPT_LEVELS_NONE, 0, NULL, 0 }
2339 rx_allocate_stack_slots_for_args (void)
2341 /* Naked functions should not allocate stack slots for arguments. */
2342 return ! is_naked_func (NULL_TREE);
2346 rx_func_attr_inlinable (const_tree decl)
2348 return ! is_fast_interrupt_func (decl)
2349 && ! is_interrupt_func (decl)
2350 && ! is_naked_func (decl);
2353 /* Return nonzero if it is ok to make a tail-call to DECL,
2354 a function_decl or NULL if this is an indirect call, using EXP */
2357 rx_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
2359 /* Do not allow indirect tailcalls. The
2360 sibcall patterns do not support them. */
2364 /* Never tailcall from inside interrupt handlers or naked functions. */
2365 if (is_fast_interrupt_func (NULL_TREE)
2366 || is_interrupt_func (NULL_TREE)
2367 || is_naked_func (NULL_TREE))
2374 rx_file_start (void)
2376 if (! TARGET_AS100_SYNTAX)
2377 default_file_start ();
2381 rx_is_ms_bitfield_layout (const_tree record_type ATTRIBUTE_UNUSED)
2383 /* The packed attribute overrides the MS behaviour. */
2384 return ! TYPE_PACKED (record_type);
2387 /* Returns true if X a legitimate constant for an immediate
2388 operand on the RX. X is already known to satisfy CONSTANT_P. */
2391 rx_is_legitimate_constant (rtx x)
2393 switch (GET_CODE (x))
2398 if (GET_CODE (x) == PLUS)
2400 if (! CONST_INT_P (XEXP (x, 1)))
2403 /* GCC would not pass us CONST_INT + CONST_INT so we
2404 know that we have {SYMBOL|LABEL} + CONST_INT. */
2406 gcc_assert (! CONST_INT_P (x));
2409 switch (GET_CODE (x))
2416 return XINT (x, 1) == UNSPEC_CONST;
2419 /* FIXME: Can this ever happen ? */
2429 return (rx_max_constant_size == 0 || rx_max_constant_size == 4);
2433 gcc_assert (CONST_INT_P (x));
2437 return ok_for_max_constant (INTVAL (x));
2441 rx_address_cost (rtx addr, bool speed)
2445 if (GET_CODE (addr) != PLUS)
2446 return COSTS_N_INSNS (1);
2451 if (REG_P (a) && REG_P (b))
2452 /* Try to discourage REG+REG addressing as it keeps two registers live. */
2453 return COSTS_N_INSNS (4);
2456 /* [REG+OFF] is just as fast as [REG]. */
2457 return COSTS_N_INSNS (1);
2460 && ((INTVAL (b) > 128) || INTVAL (b) < -127))
2461 /* Try to discourage REG + <large OFF> when optimizing for size. */
2462 return COSTS_N_INSNS (2);
2464 return COSTS_N_INSNS (1);
2468 rx_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
2470 /* We can always eliminate to the frame pointer.
2471 We can eliminate to the stack pointer unless a frame
2472 pointer is needed. */
2474 return to == FRAME_POINTER_REGNUM
2475 || ( to == STACK_POINTER_REGNUM && ! frame_pointer_needed);
2480 rx_trampoline_template (FILE * file)
2482 /* Output assembler code for a block containing the constant
2483 part of a trampoline, leaving space for the variable parts.
2485 On the RX, (where r8 is the static chain regnum) the trampoline
2488 mov #<static chain value>, r8
2489 mov #<function's address>, r9
2492 In big-endian-data-mode however instructions are read into the CPU
2493 4 bytes at a time. These bytes are then swapped around before being
2494 passed to the decoder. So...we must partition our trampoline into
2495 4 byte packets and swap these packets around so that the instruction
2496 reader will reverse the process. But, in order to avoid splitting
2497 the 32-bit constants across these packet boundaries, (making inserting
2498 them into the constructed trampoline very difficult) we have to pad the
2499 instruction sequence with NOP insns. ie:
2511 if (! TARGET_BIG_ENDIAN_DATA)
2513 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", STATIC_CHAIN_REGNUM);
2514 asm_fprintf (file, "\tmov.L\t#0deadbeefH, r%d\n", TRAMPOLINE_TEMP_REGNUM);
2515 asm_fprintf (file, "\tjmp\tr%d\n", TRAMPOLINE_TEMP_REGNUM);
2519 char r8 = '0' + STATIC_CHAIN_REGNUM;
2520 char r9 = '0' + TRAMPOLINE_TEMP_REGNUM;
2522 if (TARGET_AS100_SYNTAX)
2524 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r8);
2525 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
2526 asm_fprintf (file, "\t.BYTE 0%c2H, 0fbH, 003H, 003H\n", r9);
2527 asm_fprintf (file, "\t.BYTE 0deH, 0adH, 0beH, 0efH\n");
2528 asm_fprintf (file, "\t.BYTE 003H, 003H, 00%cH, 07fH\n", r9);
2532 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r8);
2533 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
2534 asm_fprintf (file, "\t.byte 0x%c2, 0xfb, 0x03, 0x03\n", r9);
2535 asm_fprintf (file, "\t.byte 0xde, 0xad, 0xbe, 0xef\n");
2536 asm_fprintf (file, "\t.byte 0x03, 0x03, 0x0%c, 0x7f\n", r9);
2542 rx_trampoline_init (rtx tramp, tree fndecl, rtx chain)
2544 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
2546 emit_block_move (tramp, assemble_trampoline_template (),
2547 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
2549 if (TARGET_BIG_ENDIAN_DATA)
2551 emit_move_insn (adjust_address (tramp, SImode, 4), chain);
2552 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
2556 emit_move_insn (adjust_address (tramp, SImode, 2), chain);
2557 emit_move_insn (adjust_address (tramp, SImode, 6 + 2), fnaddr);
2562 rx_memory_move_cost (enum machine_mode mode, reg_class_t regclass, bool in)
2564 return 2 + memory_move_secondary_cost (mode, regclass, in);
2567 /* Convert a CC_MODE to the set of flags that it represents. */
2570 flags_from_mode (enum machine_mode mode)
2575 return CC_FLAG_S | CC_FLAG_Z;
2577 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O;
2579 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_C;
2581 return CC_FLAG_S | CC_FLAG_Z | CC_FLAG_O | CC_FLAG_C;
2589 /* Convert a set of flags to a CC_MODE that can implement it. */
2591 static enum machine_mode
2592 mode_from_flags (unsigned int f)
2603 else if (f & CC_FLAG_C)
2609 /* Convert an RTX_CODE to the set of flags needed to implement it.
2610 This assumes an integer comparison. */
2613 flags_from_code (enum rtx_code code)
2622 return CC_FLAG_S | CC_FLAG_O | CC_FLAG_Z;
2628 return CC_FLAG_C | CC_FLAG_Z;
2637 /* Return a CC_MODE of which both M1 and M2 are subsets. */
2639 static enum machine_mode
2640 rx_cc_modes_compatible (enum machine_mode m1, enum machine_mode m2)
2644 /* Early out for identical modes. */
2648 /* There's no valid combination for FP vs non-FP. */
2649 f = flags_from_mode (m1) | flags_from_mode (m2);
2653 /* Otherwise, see what mode can implement all the flags. */
2654 return mode_from_flags (f);
2657 /* Return the minimal CC mode needed to implement (CMP_CODE X Y). */
2660 rx_select_cc_mode (enum rtx_code cmp_code, rtx x, rtx y ATTRIBUTE_UNUSED)
2662 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
2665 return mode_from_flags (flags_from_code (cmp_code));
2668 /* Split the floating-point comparison IN into individual comparisons
2669 O1 and O2. O2 may be UNKNOWN if there is no second comparison.
2670 Return true iff the comparison operands must be swapped. */
2673 rx_split_fp_compare (enum rtx_code in, enum rtx_code *o1, enum rtx_code *o2)
2675 enum rtx_code cmp1 = in, cmp2 = UNKNOWN;
2690 cmp1 = swap_condition (cmp1);
2730 /* Split the conditional branch. Emit (COMPARE C1 C2) into CC_REG with
2731 CC_MODE, and use that in branches based on that compare. */
2734 rx_split_cbranch (enum machine_mode cc_mode, enum rtx_code cmp1,
2735 rtx c1, rtx c2, rtx label)
2739 flags = gen_rtx_REG (cc_mode, CC_REG);
2740 x = gen_rtx_COMPARE (cc_mode, c1, c2);
2741 x = gen_rtx_SET (VOIDmode, flags, x);
2744 x = gen_rtx_fmt_ee (cmp1, VOIDmode, flags, const0_rtx);
2745 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x, label, pc_rtx);
2746 x = gen_rtx_SET (VOIDmode, pc_rtx, x);
2750 /* A helper function for matching parallels that set the flags. */
2753 rx_match_ccmode (rtx insn, enum machine_mode cc_mode)
2756 enum machine_mode flags_mode;
2758 gcc_checking_assert (XVECLEN (PATTERN (insn), 0) == 2);
2760 op1 = XVECEXP (PATTERN (insn), 0, 1);
2761 gcc_checking_assert (GET_CODE (SET_SRC (op1)) == COMPARE);
2763 flags = SET_DEST (op1);
2764 flags_mode = GET_MODE (flags);
2766 if (GET_MODE (SET_SRC (op1)) != flags_mode)
2768 if (GET_MODE_CLASS (flags_mode) != MODE_CC)
2771 /* Ensure that the mode of FLAGS is compatible with CC_MODE. */
2772 if (flags_from_mode (flags_mode) & ~flags_from_mode (cc_mode))
2779 #undef TARGET_FUNCTION_VALUE
2780 #define TARGET_FUNCTION_VALUE rx_function_value
2782 #undef TARGET_RETURN_IN_MSB
2783 #define TARGET_RETURN_IN_MSB rx_return_in_msb
2785 #undef TARGET_IN_SMALL_DATA_P
2786 #define TARGET_IN_SMALL_DATA_P rx_in_small_data
2788 #undef TARGET_RETURN_IN_MEMORY
2789 #define TARGET_RETURN_IN_MEMORY rx_return_in_memory
2791 #undef TARGET_HAVE_SRODATA_SECTION
2792 #define TARGET_HAVE_SRODATA_SECTION true
2794 #undef TARGET_ASM_SELECT_RTX_SECTION
2795 #define TARGET_ASM_SELECT_RTX_SECTION rx_select_rtx_section
2797 #undef TARGET_ASM_SELECT_SECTION
2798 #define TARGET_ASM_SELECT_SECTION rx_select_section
2800 #undef TARGET_INIT_BUILTINS
2801 #define TARGET_INIT_BUILTINS rx_init_builtins
2803 #undef TARGET_EXPAND_BUILTIN
2804 #define TARGET_EXPAND_BUILTIN rx_expand_builtin
2806 #undef TARGET_ASM_CONSTRUCTOR
2807 #define TARGET_ASM_CONSTRUCTOR rx_elf_asm_constructor
2809 #undef TARGET_ASM_DESTRUCTOR
2810 #define TARGET_ASM_DESTRUCTOR rx_elf_asm_destructor
2812 #undef TARGET_STRUCT_VALUE_RTX
2813 #define TARGET_STRUCT_VALUE_RTX rx_struct_value_rtx
2815 #undef TARGET_ATTRIBUTE_TABLE
2816 #define TARGET_ATTRIBUTE_TABLE rx_attribute_table
2818 #undef TARGET_ASM_FILE_START
2819 #define TARGET_ASM_FILE_START rx_file_start
2821 #undef TARGET_MS_BITFIELD_LAYOUT_P
2822 #define TARGET_MS_BITFIELD_LAYOUT_P rx_is_ms_bitfield_layout
2824 #undef TARGET_LEGITIMATE_ADDRESS_P
2825 #define TARGET_LEGITIMATE_ADDRESS_P rx_is_legitimate_address
2827 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
2828 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS rx_allocate_stack_slots_for_args
2830 #undef TARGET_ASM_FUNCTION_PROLOGUE
2831 #define TARGET_ASM_FUNCTION_PROLOGUE rx_output_function_prologue
2833 #undef TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P
2834 #define TARGET_FUNCTION_ATTRIBUTE_INLINABLE_P rx_func_attr_inlinable
2836 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
2837 #define TARGET_FUNCTION_OK_FOR_SIBCALL rx_function_ok_for_sibcall
2839 #undef TARGET_FUNCTION_ARG
2840 #define TARGET_FUNCTION_ARG rx_function_arg
2842 #undef TARGET_FUNCTION_ARG_ADVANCE
2843 #define TARGET_FUNCTION_ARG_ADVANCE rx_function_arg_advance
2845 #undef TARGET_FUNCTION_ARG_BOUNDARY
2846 #define TARGET_FUNCTION_ARG_BOUNDARY rx_function_arg_boundary
2848 #undef TARGET_SET_CURRENT_FUNCTION
2849 #define TARGET_SET_CURRENT_FUNCTION rx_set_current_function
2851 #undef TARGET_HANDLE_OPTION
2852 #define TARGET_HANDLE_OPTION rx_handle_option
2854 #undef TARGET_ASM_INTEGER
2855 #define TARGET_ASM_INTEGER rx_assemble_integer
2857 #undef TARGET_USE_BLOCKS_FOR_CONSTANT_P
2858 #define TARGET_USE_BLOCKS_FOR_CONSTANT_P hook_bool_mode_const_rtx_true
2860 #undef TARGET_MAX_ANCHOR_OFFSET
2861 #define TARGET_MAX_ANCHOR_OFFSET 32
2863 #undef TARGET_ADDRESS_COST
2864 #define TARGET_ADDRESS_COST rx_address_cost
2866 #undef TARGET_CAN_ELIMINATE
2867 #define TARGET_CAN_ELIMINATE rx_can_eliminate
2869 #undef TARGET_CONDITIONAL_REGISTER_USAGE
2870 #define TARGET_CONDITIONAL_REGISTER_USAGE rx_conditional_register_usage
2872 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
2873 #define TARGET_ASM_TRAMPOLINE_TEMPLATE rx_trampoline_template
2875 #undef TARGET_TRAMPOLINE_INIT
2876 #define TARGET_TRAMPOLINE_INIT rx_trampoline_init
2878 #undef TARGET_PRINT_OPERAND
2879 #define TARGET_PRINT_OPERAND rx_print_operand
2881 #undef TARGET_PRINT_OPERAND_ADDRESS
2882 #define TARGET_PRINT_OPERAND_ADDRESS rx_print_operand_address
2884 #undef TARGET_CC_MODES_COMPATIBLE
2885 #define TARGET_CC_MODES_COMPATIBLE rx_cc_modes_compatible
2887 #undef TARGET_MEMORY_MOVE_COST
2888 #define TARGET_MEMORY_MOVE_COST rx_memory_move_cost
2890 #undef TARGET_OPTION_OVERRIDE
2891 #define TARGET_OPTION_OVERRIDE rx_option_override
2893 #undef TARGET_OPTION_OPTIMIZATION_TABLE
2894 #define TARGET_OPTION_OPTIMIZATION_TABLE rx_option_optimization_table
2896 #undef TARGET_PROMOTE_FUNCTION_MODE
2897 #define TARGET_PROMOTE_FUNCTION_MODE rx_promote_function_mode
2899 #undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
2900 #define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE rx_override_options_after_change
2902 #undef TARGET_EXCEPT_UNWIND_INFO
2903 #define TARGET_EXCEPT_UNWIND_INFO sjlj_except_unwind_info
2905 struct gcc_target targetm = TARGET_INITIALIZER;
2907 /* #include "gt-rx.h" */