1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright (C) 2001-2022 Free Software Foundation, Inc.
3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
25 #include "coretypes.h"
35 #include "stringpool.h"
41 #include "diagnostic-core.h"
44 #include "fold-const.h"
45 #include "stor-layout.h"
52 #include "langhooks.h"
56 #include "hw-doloop.h"
59 /* This file should be included last. */
60 #include "target-def.h"
62 /* Enumeration for all of the relational tests, so that we can build
63 arrays indexed by the test type, and not worry about the order
81 /* Array giving truth value on whether or not a given hard register
82 can support a given mode. */
83 static char xtensa_hard_regno_mode_ok_p
84 [(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
86 /* Largest block move to handle in-line. */
87 #define LARGEST_MOVE_RATIO 15
89 /* Define the structure for the machine field in struct function. */
90 struct GTY(()) machine_function
92 int accesses_prev_frame
;
96 rtx_insn
*set_frame_ptr_insn
;
97 /* Current frame size calculated by compute_frame_size. */
98 unsigned current_frame_size
;
99 /* Callee-save area size in the current frame calculated by
100 compute_frame_size. */
101 int callee_save_size
;
106 /* Vector, indexed by hard register number, which contains 1 for a
107 register that is allowable in a candidate for leaf function
110 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
114 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
118 static void xtensa_option_override (void);
119 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
120 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
, int *);
121 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
122 static rtx
gen_conditional_move (enum rtx_code
, machine_mode
, rtx
, rtx
);
123 static rtx
fixup_subreg_mem (rtx
);
124 static struct machine_function
* xtensa_init_machine_status (void);
125 static rtx
xtensa_legitimize_tls_address (rtx
);
126 static rtx
xtensa_legitimize_address (rtx
, rtx
, machine_mode
);
127 static bool xtensa_mode_dependent_address_p (const_rtx
, addr_space_t
);
128 static bool xtensa_return_in_msb (const_tree
);
129 static void printx (FILE *, signed int);
130 static rtx
xtensa_builtin_saveregs (void);
131 static bool xtensa_legitimate_address_p (machine_mode
, rtx
, bool);
132 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
133 int) ATTRIBUTE_UNUSED
;
134 static section
*xtensa_select_rtx_section (machine_mode
, rtx
,
135 unsigned HOST_WIDE_INT
);
136 static bool xtensa_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
137 static int xtensa_register_move_cost (machine_mode
, reg_class_t
,
139 static int xtensa_memory_move_cost (machine_mode
, reg_class_t
, bool);
140 static tree
xtensa_build_builtin_va_list (void);
141 static bool xtensa_return_in_memory (const_tree
, const_tree
);
142 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
144 static void xtensa_function_arg_advance (cumulative_args_t
,
145 const function_arg_info
&);
146 static rtx
xtensa_function_arg (cumulative_args_t
, const function_arg_info
&);
147 static rtx
xtensa_function_incoming_arg (cumulative_args_t
,
148 const function_arg_info
&);
149 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
150 static rtx
xtensa_libcall_value (machine_mode
, const_rtx
);
151 static bool xtensa_function_value_regno_p (const unsigned int);
152 static unsigned int xtensa_function_arg_boundary (machine_mode
,
154 static void xtensa_init_builtins (void);
155 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
156 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
157 static void xtensa_va_start (tree
, rtx
);
158 static bool xtensa_frame_pointer_required (void);
159 static rtx
xtensa_static_chain (const_tree
, bool);
160 static void xtensa_asm_trampoline_template (FILE *);
161 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
162 static bool xtensa_output_addr_const_extra (FILE *, rtx
);
163 static bool xtensa_cannot_force_const_mem (machine_mode
, rtx
);
165 static reg_class_t
xtensa_preferred_reload_class (rtx
, reg_class_t
);
166 static reg_class_t
xtensa_preferred_output_reload_class (rtx
, reg_class_t
);
167 static reg_class_t
xtensa_secondary_reload (bool, rtx
, reg_class_t
,
169 struct secondary_reload_info
*);
171 static bool constantpool_address_p (const_rtx addr
);
172 static bool xtensa_legitimate_constant_p (machine_mode
, rtx
);
173 static void xtensa_reorg (void);
174 static bool xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
176 static const char *xtensa_invalid_within_doloop (const rtx_insn
*);
178 static bool xtensa_member_type_forces_blk (const_tree
,
181 static void xtensa_conditional_register_usage (void);
182 static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode
);
183 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode
);
184 static bool xtensa_modes_tieable_p (machine_mode
, machine_mode
);
185 static HOST_WIDE_INT
xtensa_constant_alignment (const_tree
, HOST_WIDE_INT
);
186 static bool xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED
,
188 static HOST_WIDE_INT
xtensa_starting_frame_offset (void);
189 static unsigned HOST_WIDE_INT
xtensa_asan_shadow_offset (void);
191 static rtx
xtensa_delegitimize_address (rtx
);
195 /* These hooks specify assembly directives for creating certain kinds
196 of integer object. */
198 #undef TARGET_ASM_ALIGNED_SI_OP
199 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
201 #undef TARGET_ASM_SELECT_RTX_SECTION
202 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
204 #undef TARGET_LEGITIMIZE_ADDRESS
205 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
206 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
207 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
209 #undef TARGET_REGISTER_MOVE_COST
210 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
211 #undef TARGET_MEMORY_MOVE_COST
212 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
213 #undef TARGET_RTX_COSTS
214 #define TARGET_RTX_COSTS xtensa_rtx_costs
215 #undef TARGET_ADDRESS_COST
216 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
218 #undef TARGET_MEMBER_TYPE_FORCES_BLK
219 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
221 #undef TARGET_BUILD_BUILTIN_VA_LIST
222 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
224 #undef TARGET_EXPAND_BUILTIN_VA_START
225 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
227 #undef TARGET_PROMOTE_FUNCTION_MODE
228 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
229 #undef TARGET_PROMOTE_PROTOTYPES
230 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
232 #undef TARGET_RETURN_IN_MEMORY
233 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
234 #undef TARGET_FUNCTION_VALUE
235 #define TARGET_FUNCTION_VALUE xtensa_function_value
236 #undef TARGET_LIBCALL_VALUE
237 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
238 #undef TARGET_FUNCTION_VALUE_REGNO_P
239 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
241 #undef TARGET_SPLIT_COMPLEX_ARG
242 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
243 #undef TARGET_MUST_PASS_IN_STACK
244 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
245 #undef TARGET_FUNCTION_ARG_ADVANCE
246 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
247 #undef TARGET_FUNCTION_ARG
248 #define TARGET_FUNCTION_ARG xtensa_function_arg
249 #undef TARGET_FUNCTION_INCOMING_ARG
250 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
251 #undef TARGET_FUNCTION_ARG_BOUNDARY
252 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
254 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
255 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
256 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
257 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
259 #undef TARGET_RETURN_IN_MSB
260 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
262 #undef TARGET_INIT_BUILTINS
263 #define TARGET_INIT_BUILTINS xtensa_init_builtins
264 #undef TARGET_FOLD_BUILTIN
265 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
266 #undef TARGET_EXPAND_BUILTIN
267 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
269 #undef TARGET_PREFERRED_RELOAD_CLASS
270 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
271 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
272 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
274 #undef TARGET_SECONDARY_RELOAD
275 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
277 #undef TARGET_HAVE_TLS
278 #define TARGET_HAVE_TLS HAVE_AS_TLS
280 #undef TARGET_CANNOT_FORCE_CONST_MEM
281 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
284 #define TARGET_LRA_P hook_bool_void_false
286 #undef TARGET_LEGITIMATE_ADDRESS_P
287 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
289 #undef TARGET_FRAME_POINTER_REQUIRED
290 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
292 #undef TARGET_STATIC_CHAIN
293 #define TARGET_STATIC_CHAIN xtensa_static_chain
294 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
295 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
296 #undef TARGET_TRAMPOLINE_INIT
297 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
299 #undef TARGET_OPTION_OVERRIDE
300 #define TARGET_OPTION_OVERRIDE xtensa_option_override
302 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
303 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
305 #undef TARGET_LEGITIMATE_CONSTANT_P
306 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
308 #undef TARGET_MACHINE_DEPENDENT_REORG
309 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
311 #undef TARGET_CAN_USE_DOLOOP_P
312 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
314 #undef TARGET_INVALID_WITHIN_DOLOOP
315 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
317 #undef TARGET_CONDITIONAL_REGISTER_USAGE
318 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
320 #undef TARGET_HARD_REGNO_NREGS
321 #define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
322 #undef TARGET_HARD_REGNO_MODE_OK
323 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
325 #undef TARGET_MODES_TIEABLE_P
326 #define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p
328 #undef TARGET_CONSTANT_ALIGNMENT
329 #define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment
331 #undef TARGET_CAN_ELIMINATE
332 #define TARGET_CAN_ELIMINATE xtensa_can_eliminate
334 #undef TARGET_STARTING_FRAME_OFFSET
335 #define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset
337 #undef TARGET_ASAN_SHADOW_OFFSET
338 #define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset
340 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
341 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
343 #undef TARGET_DELEGITIMIZE_ADDRESS
344 #define TARGET_DELEGITIMIZE_ADDRESS xtensa_delegitimize_address
346 struct gcc_target targetm
= TARGET_INITIALIZER
;
349 /* Functions to test Xtensa immediate operand validity. */
352 xtensa_simm8 (HOST_WIDE_INT v
)
354 return v
>= -128 && v
<= 127;
359 xtensa_simm8x256 (HOST_WIDE_INT v
)
361 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
366 xtensa_simm12b (HOST_WIDE_INT v
)
368 return v
>= -2048 && v
<= 2047;
373 xtensa_uimm8 (HOST_WIDE_INT v
)
375 return v
>= 0 && v
<= 255;
380 xtensa_uimm8x2 (HOST_WIDE_INT v
)
382 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
387 xtensa_uimm8x4 (HOST_WIDE_INT v
)
389 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
394 xtensa_b4const (HOST_WIDE_INT v
)
421 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
425 return xtensa_b4const (v
);
430 xtensa_b4constu (HOST_WIDE_INT v
)
457 xtensa_mask_immediate (HOST_WIDE_INT v
)
459 #define MAX_MASK_SIZE 16
462 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
475 /* This is just like the standard true_regnum() function except that it
476 works even when reg_renumber is not initialized. */
479 xt_true_regnum (rtx x
)
481 if (GET_CODE (x
) == REG
)
484 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
485 && reg_renumber
[REGNO (x
)] >= 0)
486 return reg_renumber
[REGNO (x
)];
489 if (GET_CODE (x
) == SUBREG
)
491 int base
= xt_true_regnum (SUBREG_REG (x
));
492 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
493 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
494 GET_MODE (SUBREG_REG (x
)),
495 SUBREG_BYTE (x
), GET_MODE (x
));
502 xtensa_valid_move (machine_mode mode
, rtx
*operands
)
504 /* Either the destination or source must be a register, and the
505 MAC16 accumulator doesn't count. */
507 if (register_operand (operands
[0], mode
))
509 int dst_regnum
= xt_true_regnum (operands
[0]);
511 if (xtensa_tls_referenced_p (operands
[1]))
514 /* The stack pointer can only be assigned with a MOVSP opcode. */
515 if (dst_regnum
== STACK_POINTER_REGNUM
)
516 return !TARGET_WINDOWED_ABI
518 && register_operand (operands
[1], mode
)
519 && !ACC_REG_P (xt_true_regnum (operands
[1])));
521 if (!ACC_REG_P (dst_regnum
))
524 if (register_operand (operands
[1], mode
))
526 int src_regnum
= xt_true_regnum (operands
[1]);
527 if (!ACC_REG_P (src_regnum
))
535 smalloffset_mem_p (rtx op
)
537 if (GET_CODE (op
) == MEM
)
539 rtx addr
= XEXP (op
, 0);
540 if (GET_CODE (addr
) == REG
)
541 return BASE_REG_P (addr
, 0);
542 if (GET_CODE (addr
) == PLUS
)
544 rtx offset
= XEXP (addr
, 0);
546 if (GET_CODE (offset
) != CONST_INT
)
547 offset
= XEXP (addr
, 1);
548 if (GET_CODE (offset
) != CONST_INT
)
551 val
= INTVAL (offset
);
552 return (val
& 3) == 0 && (val
>= 0 && val
<= 60);
560 constantpool_address_p (const_rtx addr
)
562 const_rtx sym
= addr
;
564 if (GET_CODE (addr
) == CONST
)
568 /* Only handle (PLUS (SYM, OFFSET)) form. */
569 addr
= XEXP (addr
, 0);
570 if (GET_CODE (addr
) != PLUS
)
573 /* Make sure the address is word aligned. */
574 offset
= XEXP (addr
, 1);
575 if ((!CONST_INT_P (offset
))
576 || ((INTVAL (offset
) & 3) != 0))
579 sym
= XEXP (addr
, 0);
582 if ((GET_CODE (sym
) == SYMBOL_REF
)
583 && CONSTANT_POOL_ADDRESS_P (sym
))
590 constantpool_mem_p (rtx op
)
592 if (GET_CODE (op
) == SUBREG
)
593 op
= SUBREG_REG (op
);
594 if (GET_CODE (op
) == MEM
)
595 return constantpool_address_p (XEXP (op
, 0));
600 /* Return TRUE if X is a thread-local symbol. */
603 xtensa_tls_symbol_p (rtx x
)
605 if (! targetm
.have_tls
)
608 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
613 xtensa_extend_reg (rtx dst
, rtx src
)
615 rtx temp
= gen_reg_rtx (SImode
);
616 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
618 /* Generate paradoxical subregs as needed so that the modes match. */
619 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
620 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
622 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
623 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
628 xtensa_mem_offset (unsigned v
, machine_mode mode
)
633 /* Handle the worst case for block moves. See xtensa_expand_block_move
634 where we emit an optimized block move operation if the block can be
635 moved in < "move_ratio" pieces. The worst case is when the block is
636 aligned but has a size of (3 mod 4) (does this happen?) so that the
637 last piece requires a byte load/store. */
638 return (xtensa_uimm8 (v
)
639 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
642 return xtensa_uimm8 (v
);
645 return xtensa_uimm8x2 (v
);
649 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
655 return xtensa_uimm8x4 (v
);
659 /* Make normal rtx_code into something we can index from an array. */
661 static enum internal_test
662 map_test_to_internal_test (enum rtx_code test_code
)
664 enum internal_test test
= ITEST_MAX
;
669 case EQ
: test
= ITEST_EQ
; break;
670 case NE
: test
= ITEST_NE
; break;
671 case GT
: test
= ITEST_GT
; break;
672 case GE
: test
= ITEST_GE
; break;
673 case LT
: test
= ITEST_LT
; break;
674 case LE
: test
= ITEST_LE
; break;
675 case GTU
: test
= ITEST_GTU
; break;
676 case GEU
: test
= ITEST_GEU
; break;
677 case LTU
: test
= ITEST_LTU
; break;
678 case LEU
: test
= ITEST_LEU
; break;
685 /* Generate the code to compare two integer values. The return value is
686 the comparison expression. */
689 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
690 rtx cmp0
, /* first operand to compare */
691 rtx cmp1
, /* second operand to compare */
692 int *p_invert
/* whether branch needs to reverse test */)
696 enum rtx_code test_code
; /* test code to use in insn */
697 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
698 int const_add
; /* constant to add (convert LE -> LT) */
699 int reverse_regs
; /* reverse registers in test */
700 int invert_const
; /* != 0 if invert value if cmp1 is constant */
701 int invert_reg
; /* != 0 if invert value if cmp1 is register */
702 int unsignedp
; /* != 0 for unsigned comparisons. */
705 static struct cmp_info info
[ (int)ITEST_MAX
] = {
707 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
708 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
710 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
711 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
712 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
713 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
715 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
716 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
717 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
718 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
721 enum internal_test test
;
723 struct cmp_info
*p_info
;
725 test
= map_test_to_internal_test (test_code
);
726 gcc_assert (test
!= ITEST_MAX
);
728 p_info
= &info
[ (int)test
];
730 mode
= GET_MODE (cmp0
);
731 if (mode
== VOIDmode
)
732 mode
= GET_MODE (cmp1
);
734 /* Make sure we can handle any constants given to us. */
735 if (GET_CODE (cmp1
) == CONST_INT
)
737 HOST_WIDE_INT value
= INTVAL (cmp1
);
738 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
740 /* if the immediate overflows or does not fit in the immediate field,
741 spill it to a register */
743 if ((p_info
->unsignedp
?
744 (uvalue
+ p_info
->const_add
> uvalue
) :
745 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
747 cmp1
= force_reg (mode
, cmp1
);
749 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
751 cmp1
= force_reg (mode
, cmp1
);
754 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
756 cmp1
= force_reg (mode
, cmp1
);
759 /* See if we need to invert the result. */
760 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
761 ? p_info
->invert_const
762 : p_info
->invert_reg
);
764 /* Comparison to constants, may involve adding 1 to change a LT into LE.
765 Comparison between two registers, may involve switching operands. */
766 if (GET_CODE (cmp1
) == CONST_INT
)
768 if (p_info
->const_add
!= 0)
769 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
772 else if (p_info
->reverse_regs
)
779 return gen_rtx_fmt_ee (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
783 /* Generate the code to compare two float values. The return value is
784 the comparison expression. */
787 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
788 rtx cmp0
, /* first operand to compare */
789 rtx cmp1
/* second operand to compare */)
791 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
793 int reverse_regs
, invert
;
797 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
798 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
799 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
800 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
801 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
802 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
803 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
804 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
805 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
806 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
807 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
808 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
810 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
812 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
814 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
815 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
825 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
826 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
828 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
833 xtensa_expand_conditional_branch (rtx
*operands
, machine_mode mode
)
835 enum rtx_code test_code
= GET_CODE (operands
[0]);
836 rtx cmp0
= operands
[1];
837 rtx cmp1
= operands
[2];
846 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
850 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
854 if (!TARGET_HARD_FLOAT
)
855 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
,
858 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
862 /* Generate the branch. */
864 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
873 emit_jump_insn (gen_rtx_SET (pc_rtx
,
874 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
881 gen_conditional_move (enum rtx_code code
, machine_mode mode
,
888 /* Jump optimization calls get_condition() which canonicalizes
889 comparisons like (GE x <const>) to (GT x <const-1>).
890 Transform those comparisons back to GE, since that is the
891 comparison supported in Xtensa. We shouldn't have to
892 transform <LE x const> comparisons, because neither
893 xtensa_expand_conditional_branch() nor get_condition() will
896 if ((code
== GT
) && (op1
== constm1_rtx
))
901 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, pc_rtx
, const0_rtx
);
903 if (boolean_operator (cmp
, VOIDmode
))
905 /* Swap the operands to make const0 second. */
906 if (op0
== const0_rtx
)
912 /* If not comparing against zero, emit a comparison (subtract). */
913 if (op1
!= const0_rtx
)
915 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
916 0, 0, OPTAB_LIB_WIDEN
);
920 else if (branch_operator (cmp
, VOIDmode
))
922 /* Swap the operands to make const0 second. */
923 if (op0
== const0_rtx
)
930 case LT
: code
= GE
; break;
931 case GE
: code
= LT
; break;
932 default: gcc_unreachable ();
936 if (op1
!= const0_rtx
)
942 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
945 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
946 return gen_float_relational (code
, op0
, op1
);
953 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
955 rtx dest
= operands
[0];
956 rtx cmp
= operands
[1];
957 machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
958 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
960 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
961 XEXP (cmp
, 0), XEXP (cmp
, 1))))
965 gen_fn
= (cmp_mode
== SImode
966 ? gen_movsfcc_internal0
967 : gen_movsfcc_internal1
);
969 gen_fn
= (cmp_mode
== SImode
970 ? gen_movsicc_internal0
971 : gen_movsicc_internal1
);
973 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
979 xtensa_expand_scc (rtx operands
[4], machine_mode cmp_mode
)
981 rtx dest
= operands
[0];
983 rtx one_tmp
, zero_tmp
;
984 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
986 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
987 operands
[2], operands
[3])))
990 one_tmp
= gen_reg_rtx (SImode
);
991 zero_tmp
= gen_reg_rtx (SImode
);
992 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
993 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
995 gen_fn
= (cmp_mode
== SImode
996 ? gen_movsicc_internal0
997 : gen_movsicc_internal1
);
998 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
1003 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
1004 for the output, i.e., the input operands are twice as big as MODE. */
1007 xtensa_split_operand_pair (rtx operands
[4], machine_mode mode
)
1009 switch (GET_CODE (operands
[1]))
1012 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
1013 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
1017 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
1018 operands
[2] = adjust_address (operands
[1], mode
, 0);
1023 split_double (operands
[1], &operands
[2], &operands
[3]);
1030 switch (GET_CODE (operands
[0]))
1033 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
1034 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
1038 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
1039 operands
[0] = adjust_address (operands
[0], mode
, 0);
1048 /* Emit insns to move operands[1] into operands[0].
1049 Return 1 if we have written out everything that needs to be done to
1050 do the move. Otherwise, return 0 and the caller will emit the move
1054 xtensa_emit_move_sequence (rtx
*operands
, machine_mode mode
)
1056 rtx src
= operands
[1];
1058 if (CONSTANT_P (src
)
1059 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
1061 rtx dst
= operands
[0];
1063 if (xtensa_tls_referenced_p (src
))
1067 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
1069 addend
= XEXP (XEXP (src
, 0), 1);
1070 src
= XEXP (XEXP (src
, 0), 0);
1073 src
= xtensa_legitimize_tls_address (src
);
1076 src
= gen_rtx_PLUS (mode
, src
, addend
);
1077 src
= force_operand (src
, dst
);
1079 emit_move_insn (dst
, src
);
1083 if (! TARGET_AUTO_LITPOOLS
&& ! TARGET_CONST16
)
1085 /* Try to emit MOVI + SLLI sequence, that is smaller
1086 than L32R + literal. */
1087 if (optimize_size
&& mode
== SImode
&& CONST_INT_P (src
)
1088 && register_operand (dst
, mode
))
1090 HOST_WIDE_INT srcval
= INTVAL (src
);
1091 int shift
= ctz_hwi (srcval
);
1093 if (xtensa_simm12b (srcval
>> shift
))
1095 emit_move_insn (dst
, GEN_INT (srcval
>> shift
));
1096 emit_insn (gen_ashlsi3_internal (dst
, dst
, GEN_INT (shift
)));
1101 src
= force_const_mem (SImode
, src
);
1105 /* PC-relative loads are always SImode, and CONST16 is only
1106 supported in the movsi pattern, so add a SUBREG for any other
1111 if (register_operand (dst
, mode
))
1113 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
1118 src
= force_reg (SImode
, src
);
1119 src
= gen_lowpart_SUBREG (mode
, src
);
1125 if (!(reload_in_progress
| reload_completed
)
1126 && !xtensa_valid_move (mode
, operands
))
1127 operands
[1] = force_reg (mode
, operands
[1]);
1129 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1131 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1132 instruction won't be recognized after reload, so we remove the
1133 subreg and adjust mem accordingly. */
1134 if (reload_in_progress
)
1136 operands
[0] = fixup_subreg_mem (operands
[0]);
1137 operands
[1] = fixup_subreg_mem (operands
[1]);
1144 fixup_subreg_mem (rtx x
)
1146 if (GET_CODE (x
) == SUBREG
1147 && GET_CODE (SUBREG_REG (x
)) == REG
1148 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1151 gen_rtx_SUBREG (GET_MODE (x
),
1152 reg_equiv_mem (REGNO (SUBREG_REG (x
))),
1154 x
= alter_subreg (&temp
, true);
1160 /* Check if an incoming argument in a7 is expected to be used soon and
1161 if OPND is a register or register pair that includes a7. If so,
1162 create a new pseudo and copy a7 into that pseudo at the very
1163 beginning of the function, followed by the special "set_frame_ptr"
1164 unspec_volatile insn. The return value is either the original
1165 operand, if it is not a7, or the new pseudo containing a copy of
1166 the incoming argument. This is necessary because the register
1167 allocator will ignore conflicts with a7 and may either assign some
1168 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1169 the incoming argument in a7. By copying the argument out of a7 as
1170 the very first thing, and then immediately following that with an
1171 unspec_volatile to keep the scheduler away, we should avoid any
1172 problems. Putting the set_frame_ptr insn at the beginning, with
1173 only the a7 copy before it, also makes it easier for the prologue
1174 expander to initialize the frame pointer after the a7 copy and to
1175 fix up the a7 copy to use the stack pointer instead of the frame
1179 xtensa_copy_incoming_a7 (rtx opnd
)
1181 rtx entry_insns
= 0;
1185 if (!cfun
->machine
->need_a7_copy
)
1188 /* This function should never be called again once a7 has been copied. */
1189 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1191 mode
= GET_MODE (opnd
);
1193 /* The operand using a7 may come in a later instruction, so just return
1194 the original operand if it doesn't use a7. */
1196 if (GET_CODE (reg
) == SUBREG
)
1198 gcc_assert (SUBREG_BYTE (reg
) == 0);
1199 reg
= SUBREG_REG (reg
);
1201 if (GET_CODE (reg
) != REG
1202 || REGNO (reg
) > A7_REG
1203 || REGNO (reg
) + hard_regno_nregs (A7_REG
, mode
) <= A7_REG
)
1206 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1207 gcc_assert (REGNO (reg
) + hard_regno_nregs (A7_REG
, mode
) - 1 == A7_REG
);
1209 cfun
->machine
->need_a7_copy
= false;
1211 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1212 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1215 tmp
= gen_reg_rtx (mode
);
1221 /* Copy the value out of A7 here but keep the first word in A6 until
1222 after the set_frame_ptr insn. Otherwise, the register allocator
1223 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1225 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1226 gen_raw_REG (SImode
, A7_REG
)));
1229 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1232 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1235 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1238 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1244 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1246 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1247 if (mode
== DFmode
|| mode
== DImode
)
1248 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1249 gen_rtx_REG (SImode
, A7_REG
- 1)));
1250 entry_insns
= get_insns ();
1253 if (cfun
->machine
->vararg_a7
)
1255 /* This is called from within builtin_saveregs, which will insert the
1256 saveregs code at the function entry, ahead of anything placed at
1257 the function entry now. Instead, save the sequence to be inserted
1258 at the beginning of the saveregs code. */
1259 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1263 /* Put entry_insns after the NOTE that starts the function. If
1264 this is inside a start_sequence, make the outer-level insn
1265 chain current, so the code is placed at the start of the
1267 push_topmost_sequence ();
1268 /* Do not use entry_of_function() here. This is called from within
1269 expand_function_start, when the CFG still holds GIMPLE. */
1270 emit_insn_after (entry_insns
, get_insns ());
1271 pop_topmost_sequence ();
1278 /* Try to expand a block move operation to a sequence of RTL move
1279 instructions. If not optimizing, or if the block size is not a
1280 constant, or if the block is too large, the expansion fails and GCC
1281 falls back to calling memcpy().
1283 operands[0] is the destination
1284 operands[1] is the source
1285 operands[2] is the length
1286 operands[3] is the alignment */
1289 xtensa_expand_block_move (rtx
*operands
)
1291 static const machine_mode mode_from_align
[] =
1293 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1296 rtx dst_mem
= operands
[0];
1297 rtx src_mem
= operands
[1];
1298 HOST_WIDE_INT bytes
, align
;
1299 int num_pieces
, move_ratio
;
1301 machine_mode mode
[2];
1310 /* If this is not a fixed size move, just call memcpy. */
1311 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1314 bytes
= INTVAL (operands
[2]);
1315 align
= INTVAL (operands
[3]);
1317 /* Anything to move? */
1321 if (align
> MOVE_MAX
)
1324 /* Decide whether to expand inline based on the optimization level. */
1327 move_ratio
= LARGEST_MOVE_RATIO
;
1328 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* Close enough anyway. */
1329 if (num_pieces
> move_ratio
)
1332 x
= XEXP (dst_mem
, 0);
1335 x
= force_reg (Pmode
, x
);
1336 dst_mem
= replace_equiv_address (dst_mem
, x
);
1339 x
= XEXP (src_mem
, 0);
1342 x
= force_reg (Pmode
, x
);
1343 src_mem
= replace_equiv_address (src_mem
, x
);
1346 active
[0] = active
[1] = false;
1357 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1358 next_amount
= MIN (next_amount
, align
);
1360 amount
[next
] = next_amount
;
1361 mode
[next
] = mode_from_align
[next_amount
];
1362 temp
[next
] = gen_reg_rtx (mode
[next
]);
1364 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1365 emit_insn (gen_rtx_SET (temp
[next
], x
));
1367 offset_ld
+= next_amount
;
1368 bytes
-= next_amount
;
1369 active
[next
] = true;
1374 active
[phase
] = false;
1376 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1377 emit_insn (gen_rtx_SET (x
, temp
[phase
]));
1379 offset_st
+= amount
[phase
];
1382 while (active
[next
]);
1389 xtensa_expand_nonlocal_goto (rtx
*operands
)
1391 rtx goto_handler
= operands
[1];
1392 rtx containing_fp
= operands
[3];
1394 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1395 is too big to generate in-line. */
1397 if (GET_CODE (containing_fp
) != REG
)
1398 containing_fp
= force_reg (Pmode
, containing_fp
);
1400 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1401 LCT_NORMAL
, VOIDmode
,
1402 containing_fp
, Pmode
,
1403 goto_handler
, Pmode
);
1407 static struct machine_function
*
1408 xtensa_init_machine_status (void)
1410 return ggc_cleared_alloc
<machine_function
> ();
1414 /* Shift VAL of mode MODE left by COUNT bits. */
1417 xtensa_expand_mask_and_shift (rtx val
, machine_mode mode
, rtx count
)
1419 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1420 NULL_RTX
, 1, OPTAB_DIRECT
);
1421 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1422 NULL_RTX
, 1, OPTAB_DIRECT
);
1426 /* Structure to hold the initial parameters for a compare_and_swap operation
1427 in HImode and QImode. */
1429 struct alignment_context
1431 rtx memsi
; /* SI aligned memory location. */
1432 rtx shift
; /* Bit offset with regard to lsb. */
1433 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1434 rtx modemaski
; /* ~modemask */
1438 /* Initialize structure AC for word access to HI and QI mode memory. */
1441 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1443 machine_mode mode
= GET_MODE (mem
);
1444 rtx byteoffset
= NULL_RTX
;
1445 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1448 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1451 /* Alignment is unknown. */
1454 /* Force the address into a register. */
1455 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1457 /* Align it to SImode. */
1458 align
= expand_simple_binop (Pmode
, AND
, addr
,
1459 GEN_INT (-GET_MODE_SIZE (SImode
)),
1460 NULL_RTX
, 1, OPTAB_DIRECT
);
1462 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1463 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1464 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1465 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1467 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1468 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1469 NULL_RTX
, 1, OPTAB_DIRECT
);
1472 /* Calculate shiftcount. */
1473 if (TARGET_BIG_ENDIAN
)
1475 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1477 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1478 NULL_RTX
, 1, OPTAB_DIRECT
);
1483 ac
->shift
= NULL_RTX
;
1485 ac
->shift
= byteoffset
;
1488 if (ac
->shift
!= NULL_RTX
)
1490 /* Shift is the byte count, but we need the bitcount. */
1491 gcc_assert (exact_log2 (BITS_PER_UNIT
) >= 0);
1492 ac
->shift
= expand_simple_binop (SImode
, ASHIFT
, ac
->shift
,
1493 GEN_INT (exact_log2 (BITS_PER_UNIT
)),
1494 NULL_RTX
, 1, OPTAB_DIRECT
);
1495 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1496 GEN_INT (GET_MODE_MASK (mode
)),
1498 NULL_RTX
, 1, OPTAB_DIRECT
);
1501 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1503 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1507 /* Expand an atomic compare and swap operation for HImode and QImode.
1508 MEM is the memory location, CMP the old value to compare MEM with
1509 and NEW_RTX the value to set if CMP == MEM. */
1512 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1514 machine_mode mode
= GET_MODE (mem
);
1515 struct alignment_context ac
;
1516 rtx tmp
, cmpv
, newv
, val
;
1517 rtx oldval
= gen_reg_rtx (SImode
);
1518 rtx res
= gen_reg_rtx (SImode
);
1519 rtx_code_label
*csloop
= gen_label_rtx ();
1520 rtx_code_label
*csend
= gen_label_rtx ();
1522 init_alignment_context (&ac
, mem
);
1524 if (ac
.shift
!= NULL_RTX
)
1526 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1527 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1530 /* Load the surrounding word into VAL with the MEM value masked out. */
1531 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1532 ac
.modemaski
, NULL_RTX
, 1,
1534 emit_label (csloop
);
1536 /* Patch CMP and NEW_RTX into VAL at correct position. */
1537 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1538 NULL_RTX
, 1, OPTAB_DIRECT
));
1539 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1540 NULL_RTX
, 1, OPTAB_DIRECT
));
1542 /* Jump to end if we're done. */
1543 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1544 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1546 /* Check for changes outside mode. */
1547 emit_move_insn (oldval
, val
);
1548 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1549 val
, 1, OPTAB_DIRECT
);
1551 emit_move_insn (val
, tmp
);
1553 /* Loop internal if so. */
1554 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1558 /* Return the correct part of the bitfield. */
1559 convert_move (target
,
1560 (ac
.shift
== NULL_RTX
? res
1561 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1562 NULL_RTX
, 1, OPTAB_DIRECT
)),
1567 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1568 the default expansion works fine for SImode). MEM is the memory location
1569 and VAL the value to play with. If AFTER is true then store the value
1570 MEM holds after the operation, if AFTER is false then store the value MEM
1571 holds before the operation. If TARGET is zero then discard that value, else
1572 store it to TARGET. */
1575 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1578 machine_mode mode
= GET_MODE (mem
);
1579 struct alignment_context ac
;
1580 rtx_code_label
*csloop
= gen_label_rtx ();
1582 rtx old
= gen_reg_rtx (SImode
);
1583 rtx new_rtx
= gen_reg_rtx (SImode
);
1584 rtx orig
= NULL_RTX
;
1586 init_alignment_context (&ac
, mem
);
1588 /* Prepare values before the compare-and-swap loop. */
1589 if (ac
.shift
!= NULL_RTX
)
1590 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1595 orig
= gen_reg_rtx (SImode
);
1596 convert_move (orig
, val
, 1);
1604 case MULT
: /* NAND */
1606 /* val = "11..1<val>11..1" */
1607 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1608 NULL_RTX
, 1, OPTAB_DIRECT
);
1615 /* Load full word. Subsequent loads are performed by S32C1I. */
1616 cmp
= force_reg (SImode
, ac
.memsi
);
1618 emit_label (csloop
);
1619 emit_move_insn (old
, cmp
);
1625 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1626 NULL_RTX
, 1, OPTAB_DIRECT
);
1627 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1628 NULL_RTX
, 1, OPTAB_DIRECT
);
1631 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1632 NULL_RTX
, 1, OPTAB_DIRECT
);
1633 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1634 new_rtx
, 1, OPTAB_DIRECT
);
1640 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
1641 new_rtx
, 1, OPTAB_DIRECT
);
1644 case MULT
: /* NAND */
1645 tmp
= expand_simple_binop (SImode
, AND
, old
, val
,
1646 NULL_RTX
, 1, OPTAB_DIRECT
);
1647 tmp
= expand_simple_binop (SImode
, XOR
, tmp
, ac
.modemask
,
1648 new_rtx
, 1, OPTAB_DIRECT
);
1656 emit_move_insn (new_rtx
, tmp
);
1657 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
1658 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
1662 tmp
= (after
? new_rtx
: cmp
);
1663 convert_move (target
,
1664 (ac
.shift
== NULL_RTX
? tmp
1665 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
1666 NULL_RTX
, 1, OPTAB_DIRECT
)),
1673 xtensa_setup_frame_addresses (void)
1675 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1676 cfun
->machine
->accesses_prev_frame
= 1;
1678 if (TARGET_WINDOWED_ABI
)
1680 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1681 LCT_NORMAL
, VOIDmode
);
1685 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1686 a comment showing where the end of the loop is. However, if there is a
1687 label or a branch at the end of the loop then we need to place a nop
1688 there. If the loop ends with a label we need the nop so that branches
1689 targeting that label will target the nop (and thus remain in the loop),
1690 instead of targeting the instruction after the loop (and thus exiting
1691 the loop). If the loop ends with a branch, we need the nop in case the
1692 branch is targeting a location inside the loop. When the branch
1693 executes it will cause the loop count to be decremented even if it is
1694 taken (because it is the last instruction in the loop), so we need to
1695 nop after the branch to prevent the loop count from being decremented
1696 when the branch is taken. */
1699 xtensa_emit_loop_end (rtx_insn
*insn
, rtx
*operands
)
1703 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1705 switch (GET_CODE (insn
))
1712 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1718 rtx body
= PATTERN (insn
);
1722 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1725 else if ((GET_CODE (body
) != USE
)
1726 && (GET_CODE (body
) != CLOBBER
))
1733 output_asm_insn ("%1_LEND:", operands
);
1738 xtensa_emit_branch (bool inverted
, bool immed
, rtx
*operands
)
1740 static char result
[64];
1744 code
= GET_CODE (operands
[3]);
1747 case EQ
: op
= inverted
? "ne" : "eq"; break;
1748 case NE
: op
= inverted
? "eq" : "ne"; break;
1749 case LT
: op
= inverted
? "ge" : "lt"; break;
1750 case GE
: op
= inverted
? "lt" : "ge"; break;
1751 case LTU
: op
= inverted
? "geu" : "ltu"; break;
1752 case GEU
: op
= inverted
? "ltu" : "geu"; break;
1753 default: gcc_unreachable ();
1758 if (INTVAL (operands
[1]) == 0)
1759 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
1760 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
1762 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1765 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1772 xtensa_emit_bit_branch (bool inverted
, bool immed
, rtx
*operands
)
1774 static char result
[64];
1777 switch (GET_CODE (operands
[3]))
1779 case EQ
: op
= inverted
? "bs" : "bc"; break;
1780 case NE
: op
= inverted
? "bc" : "bs"; break;
1781 default: gcc_unreachable ();
1786 unsigned bitnum
= INTVAL (operands
[1]) & 0x1f;
1787 operands
[1] = GEN_INT (bitnum
);
1788 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1791 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1798 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
1800 static char result
[64];
1804 code
= GET_CODE (operands
[4]);
1809 case EQ
: op
= inverted
? "t" : "f"; break;
1810 case NE
: op
= inverted
? "f" : "t"; break;
1811 default: gcc_unreachable ();
1818 case EQ
: op
= inverted
? "nez" : "eqz"; break;
1819 case NE
: op
= inverted
? "eqz" : "nez"; break;
1820 case LT
: op
= inverted
? "gez" : "ltz"; break;
1821 case GE
: op
= inverted
? "ltz" : "gez"; break;
1822 default: gcc_unreachable ();
1826 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
1827 op
, isfp
? ".s" : "", inverted
? 3 : 2);
1833 xtensa_emit_call (int callop
, rtx
*operands
)
1835 static char result
[64];
1836 rtx tgt
= operands
[callop
];
1838 if (GET_CODE (tgt
) == CONST_INT
)
1839 sprintf (result
, "call%d\t" HOST_WIDE_INT_PRINT_HEX
,
1840 WINDOW_SIZE
, INTVAL (tgt
));
1841 else if (register_operand (tgt
, VOIDmode
))
1842 sprintf (result
, "callx%d\t%%%d", WINDOW_SIZE
, callop
);
1844 sprintf (result
, "call%d\t%%%d", WINDOW_SIZE
, callop
);
1851 xtensa_legitimate_address_p (machine_mode mode
, rtx addr
, bool strict
)
1853 /* Allow constant pool addresses. */
1854 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
1855 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
1856 && ! xtensa_tls_referenced_p (addr
))
1859 while (GET_CODE (addr
) == SUBREG
)
1860 addr
= SUBREG_REG (addr
);
1862 /* Allow base registers. */
1863 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
1866 /* Check for "register + offset" addressing. */
1867 if (GET_CODE (addr
) == PLUS
)
1869 rtx xplus0
= XEXP (addr
, 0);
1870 rtx xplus1
= XEXP (addr
, 1);
1871 enum rtx_code code0
;
1872 enum rtx_code code1
;
1874 while (GET_CODE (xplus0
) == SUBREG
)
1875 xplus0
= SUBREG_REG (xplus0
);
1876 code0
= GET_CODE (xplus0
);
1878 while (GET_CODE (xplus1
) == SUBREG
)
1879 xplus1
= SUBREG_REG (xplus1
);
1880 code1
= GET_CODE (xplus1
);
1882 /* Swap operands if necessary so the register is first. */
1883 if (code0
!= REG
&& code1
== REG
)
1885 xplus0
= XEXP (addr
, 1);
1886 xplus1
= XEXP (addr
, 0);
1887 code0
= GET_CODE (xplus0
);
1888 code1
= GET_CODE (xplus1
);
1891 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
1892 && code1
== CONST_INT
1893 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
1901 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1903 static GTY(()) rtx xtensa_tls_module_base_symbol
;
1906 xtensa_tls_module_base (void)
1908 if (! xtensa_tls_module_base_symbol
)
1910 xtensa_tls_module_base_symbol
=
1911 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
1912 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
1913 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
1916 return xtensa_tls_module_base_symbol
;
1921 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
1924 rtx_insn
*call_insn
, *insns
;
1927 fn
= gen_reg_rtx (Pmode
);
1928 arg
= gen_reg_rtx (Pmode
);
1929 a_io
= gen_rtx_REG (Pmode
, WINDOW_SIZE
+ 2);
1931 emit_insn (gen_tls_func (fn
, sym
));
1932 emit_insn (gen_tls_arg (arg
, sym
));
1933 emit_move_insn (a_io
, arg
);
1934 call_insn
= emit_call_insn (gen_tls_call (a_io
, fn
, sym
, const1_rtx
));
1935 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
), a_io
);
1936 insns
= get_insns ();
1945 xtensa_legitimize_tls_address (rtx x
)
1947 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
1948 rtx dest
, tp
, ret
, modbase
, base
, addend
;
1951 dest
= gen_reg_rtx (Pmode
);
1954 case TLS_MODEL_GLOBAL_DYNAMIC
:
1955 insns
= xtensa_call_tls_desc (x
, &ret
);
1956 emit_libcall_block (insns
, dest
, ret
, x
);
1959 case TLS_MODEL_LOCAL_DYNAMIC
:
1960 base
= gen_reg_rtx (Pmode
);
1961 modbase
= xtensa_tls_module_base ();
1962 insns
= xtensa_call_tls_desc (modbase
, &ret
);
1963 emit_libcall_block (insns
, base
, ret
, modbase
);
1964 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
1965 emit_insn (gen_addsi3 (dest
, base
, addend
));
1968 case TLS_MODEL_INITIAL_EXEC
:
1969 case TLS_MODEL_LOCAL_EXEC
:
1970 tp
= gen_reg_rtx (SImode
);
1971 emit_insn (gen_get_thread_pointersi (tp
));
1972 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
1973 emit_insn (gen_addsi3 (dest
, tp
, addend
));
1985 xtensa_legitimize_address (rtx x
,
1986 rtx oldx ATTRIBUTE_UNUSED
,
1989 if (xtensa_tls_symbol_p (x
))
1990 return xtensa_legitimize_tls_address (x
);
1992 if (GET_CODE (x
) == PLUS
)
1994 rtx plus0
= XEXP (x
, 0);
1995 rtx plus1
= XEXP (x
, 1);
1997 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1999 plus0
= XEXP (x
, 1);
2000 plus1
= XEXP (x
, 0);
2003 /* Try to split up the offset to use an ADDMI instruction. */
2004 if (GET_CODE (plus0
) == REG
2005 && GET_CODE (plus1
) == CONST_INT
2006 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
2007 && !xtensa_simm8 (INTVAL (plus1
))
2008 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
2009 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
2011 rtx temp
= gen_reg_rtx (Pmode
);
2012 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
2013 emit_insn (gen_rtx_SET (temp
, gen_rtx_PLUS (Pmode
, plus0
,
2015 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
2022 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
2024 Treat constant-pool references as "mode dependent" since they can
2025 only be accessed with SImode loads. This works around a bug in the
2026 combiner where a constant pool reference is temporarily converted
2027 to an HImode load, which is then assumed to zero-extend based on
2028 our definition of LOAD_EXTEND_OP. This is wrong because the high
2029 bits of a 16-bit value in the constant pool are now sign-extended
2033 xtensa_mode_dependent_address_p (const_rtx addr
,
2034 addr_space_t as ATTRIBUTE_UNUSED
)
2036 return constantpool_address_p (addr
);
2039 /* Return TRUE if X contains any TLS symbol references. */
2042 xtensa_tls_referenced_p (rtx x
)
2044 if (! targetm
.have_tls
)
2047 subrtx_iterator::array_type array
;
2048 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
2050 const_rtx x
= *iter
;
2051 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0)
2054 /* Ignore TLS references that have already been legitimized. */
2055 if (GET_CODE (x
) == UNSPEC
)
2056 switch (XINT (x
, 1))
2060 case UNSPEC_TLS_FUNC
:
2061 case UNSPEC_TLS_ARG
:
2062 case UNSPEC_TLS_CALL
:
2063 iter
.skip_subrtxes ();
2073 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2076 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2078 return xtensa_tls_referenced_p (x
);
2082 /* Return the debugger register number to use for 'regno'. */
2085 xtensa_dbx_register_number (int regno
)
2089 if (GP_REG_P (regno
))
2091 regno
-= GP_REG_FIRST
;
2094 else if (BR_REG_P (regno
))
2096 regno
-= BR_REG_FIRST
;
2099 else if (FP_REG_P (regno
))
2101 regno
-= FP_REG_FIRST
;
2104 else if (ACC_REG_P (regno
))
2106 first
= 0x200; /* Start of Xtensa special registers. */
2107 regno
= 16; /* ACCLO is special register 16. */
2110 /* When optimizing, we sometimes get asked about pseudo-registers
2111 that don't represent hard registers. Return 0 for these. */
2115 return first
+ regno
;
2119 /* Argument support functions. */
2121 /* Initialize CUMULATIVE_ARGS for a function. */
2124 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
2127 cum
->incoming
= incoming
;
2131 /* Advance the argument to the next argument position. */
2134 xtensa_function_arg_advance (cumulative_args_t cum
,
2135 const function_arg_info
&arg
)
2140 arg_words
= &get_cumulative_args (cum
)->arg_words
;
2141 max
= MAX_ARGS_IN_REGISTERS
;
2143 words
= ((arg
.promoted_size_in_bytes () + UNITS_PER_WORD
- 1)
2146 if (*arg_words
< max
2147 && (targetm
.calls
.must_pass_in_stack (arg
)
2148 || *arg_words
+ words
> max
))
2151 *arg_words
+= words
;
2155 /* Return an RTL expression containing the register for the given argument,
2156 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2157 if this is an incoming argument to the current function. */
2160 xtensa_function_arg_1 (cumulative_args_t cum_v
, const function_arg_info
&arg
,
2163 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2164 int regbase
, words
, max
;
2168 arg_words
= &cum
->arg_words
;
2169 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2170 max
= MAX_ARGS_IN_REGISTERS
;
2172 words
= ((arg
.promoted_size_in_bytes () + UNITS_PER_WORD
- 1)
2175 if (arg
.type
&& (TYPE_ALIGN (arg
.type
) > BITS_PER_WORD
))
2177 int align
= MIN (TYPE_ALIGN (arg
.type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2178 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2181 if (*arg_words
+ words
> max
)
2184 regno
= regbase
+ *arg_words
;
2186 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2187 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
2189 return gen_rtx_REG (arg
.mode
, regno
);
2192 /* Implement TARGET_FUNCTION_ARG. */
2195 xtensa_function_arg (cumulative_args_t cum
, const function_arg_info
&arg
)
2197 return xtensa_function_arg_1 (cum
, arg
, false);
2200 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2203 xtensa_function_incoming_arg (cumulative_args_t cum
,
2204 const function_arg_info
&arg
)
2206 return xtensa_function_arg_1 (cum
, arg
, true);
2210 xtensa_function_arg_boundary (machine_mode mode
, const_tree type
)
2212 unsigned int alignment
;
2214 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2215 if (alignment
< PARM_BOUNDARY
)
2216 alignment
= PARM_BOUNDARY
;
2217 if (alignment
> STACK_BOUNDARY
)
2218 alignment
= STACK_BOUNDARY
;
2224 xtensa_return_in_msb (const_tree valtype
)
2226 return (TARGET_BIG_ENDIAN
2227 && AGGREGATE_TYPE_P (valtype
)
2228 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2233 xtensa_option_override (void)
2238 if (xtensa_windowed_abi
== -1)
2239 xtensa_windowed_abi
= TARGET_WINDOWED_ABI_DEFAULT
;
2241 if (! TARGET_THREADPTR
)
2242 targetm
.have_tls
= false;
2244 /* Use CONST16 in the absence of L32R.
2245 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa
2246 configuration in the xtensa-common.c */
2249 target_flags
|= MASK_CONST16
;
2251 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2252 error ("boolean registers required for the floating-point option");
2254 /* Set up array giving whether a given register can hold a given mode. */
2255 for (mode
= VOIDmode
;
2256 mode
!= MAX_MACHINE_MODE
;
2257 mode
= (machine_mode
) ((int) mode
+ 1))
2259 int size
= GET_MODE_SIZE (mode
);
2260 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2262 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2266 if (ACC_REG_P (regno
))
2267 temp
= (TARGET_MAC16
2268 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2269 else if (GP_REG_P (regno
))
2270 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2271 else if (FP_REG_P (regno
))
2272 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2273 else if (BR_REG_P (regno
))
2274 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2278 xtensa_hard_regno_mode_ok_p
[(int) mode
][regno
] = temp
;
2282 init_machine_status
= xtensa_init_machine_status
;
2284 /* Check PIC settings. PIC is only supported when using L32R
2285 instructions, and some targets need to always use PIC. */
2286 if (flag_pic
&& TARGET_CONST16
)
2287 error ("%<-f%s%> is not supported with CONST16 instructions",
2288 (flag_pic
> 1 ? "PIC" : "pic"));
2289 else if (TARGET_FORCE_NO_PIC
)
2291 else if (XTENSA_ALWAYS_PIC
)
2294 error ("PIC is required but not supported with CONST16 instructions");
2297 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2300 if (flag_pic
&& !flag_pie
)
2303 /* Hot/cold partitioning does not work on this architecture, because of
2304 constant pools (the load instruction cannot necessarily reach that far).
2305 Therefore disable it on this architecture. */
2306 if (flag_reorder_blocks_and_partition
)
2308 flag_reorder_blocks_and_partition
= 0;
2309 flag_reorder_blocks
= 1;
2313 /* Implement TARGET_HARD_REGNO_NREGS. */
2316 xtensa_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
2318 if (FP_REG_P (regno
))
2319 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_FPREG
);
2320 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
2323 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2326 xtensa_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
2328 return xtensa_hard_regno_mode_ok_p
[mode
][regno
];
2331 /* Implement TARGET_MODES_TIEABLE_P. */
2334 xtensa_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
2336 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
2337 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
2338 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
2339 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
2342 /* A C compound statement to output to stdio stream STREAM the
2343 assembler syntax for an instruction operand X. X is an RTL
2346 CODE is a value that can be used to specify one of several ways
2347 of printing the operand. It is used when identical operands
2348 must be printed differently depending on the context. CODE
2349 comes from the '%' specification that was used to request
2350 printing of the operand. If the specification was just '%DIGIT'
2351 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2352 is the ASCII code for LTR.
2354 If X is a register, this macro should print the register's name.
2355 The names can be found in an array 'reg_names' whose type is
2356 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2358 When the machine description has a specification '%PUNCT' (a '%'
2359 followed by a punctuation character), this macro is called with
2360 a null pointer for X and the punctuation character for CODE.
2362 'a', 'c', 'l', and 'n' are reserved.
2364 The Xtensa specific codes are:
2366 'd' CONST_INT, print as signed decimal
2367 'x' CONST_INT, print as signed hexadecimal
2368 'K' CONST_INT, print number of bits in mask for EXTUI
2369 'R' CONST_INT, print (X & 0x1f)
2370 'L' CONST_INT, print ((32 - X) & 0x1f)
2371 'D' REG, print second register of double-word register operand
2372 'N' MEM, print address of next word following a memory operand
2373 'v' MEM, if memory reference is volatile, output a MEMW before it
2374 't' any constant, add "@h" suffix for top 16 bits
2375 'b' any constant, add "@l" suffix for bottom 16 bits
2379 printx (FILE *file
, signed int val
)
2381 /* Print a hexadecimal value in a nice way. */
2382 if ((val
> -0xa) && (val
< 0xa))
2383 fprintf (file
, "%d", val
);
2385 fprintf (file
, "-0x%x", -val
);
2387 fprintf (file
, "0x%x", val
);
2392 print_operand (FILE *file
, rtx x
, int letter
)
2395 error ("PRINT_OPERAND null pointer");
2400 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2401 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2403 output_operand_lossage ("invalid %%D value");
2407 if (GET_CODE (x
) == MEM
)
2409 /* For a volatile memory reference, emit a MEMW before the
2411 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2412 fprintf (file
, "memw\n\t");
2415 output_operand_lossage ("invalid %%v value");
2419 if (GET_CODE (x
) == MEM
2420 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2422 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? E_SFmode
: E_SImode
,
2424 output_address (GET_MODE (x
), XEXP (x
, 0));
2427 output_operand_lossage ("invalid %%N value");
2431 if (GET_CODE (x
) == CONST_INT
)
2434 unsigned val
= INTVAL (x
);
2440 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2441 fatal_insn ("invalid mask", x
);
2443 fprintf (file
, "%d", num_bits
);
2446 output_operand_lossage ("invalid %%K value");
2450 if (GET_CODE (x
) == CONST_INT
)
2451 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INTVAL (x
)) & 0x1f);
2453 output_operand_lossage ("invalid %%L value");
2457 if (GET_CODE (x
) == CONST_INT
)
2458 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0x1f);
2460 output_operand_lossage ("invalid %%R value");
2464 if (GET_CODE (x
) == CONST_INT
)
2465 printx (file
, INTVAL (x
));
2467 output_operand_lossage ("invalid %%x value");
2471 if (GET_CODE (x
) == CONST_INT
)
2472 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2474 output_operand_lossage ("invalid %%d value");
2479 if (GET_CODE (x
) == CONST_INT
)
2481 printx (file
, INTVAL (x
));
2482 fputs (letter
== 't' ? "@h" : "@l", file
);
2484 else if (GET_CODE (x
) == CONST_DOUBLE
)
2486 if (GET_MODE (x
) == SFmode
)
2489 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2490 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2493 output_operand_lossage ("invalid %%t/%%b value");
2495 else if (GET_CODE (x
) == CONST
)
2497 /* X must be a symbolic constant on ELF. Write an expression
2498 suitable for 'const16' that sets the high or low 16 bits. */
2499 if (GET_CODE (XEXP (x
, 0)) != PLUS
2500 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2501 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2502 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2503 output_operand_lossage ("invalid %%t/%%b value");
2504 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2505 fputs (letter
== 't' ? "@h" : "@l", file
);
2506 /* There must be a non-alphanumeric character between 'h' or 'l'
2507 and the number. The '-' is added by print_operand() already. */
2508 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2510 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2514 output_addr_const (file
, x
);
2515 fputs (letter
== 't' ? "@h" : "@l", file
);
2520 if (GET_CODE (x
) == CONST_DOUBLE
&&
2521 GET_MODE (x
) == SFmode
)
2524 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2525 fprintf (file
, "0x%08lx", l
);
2532 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2533 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2534 else if (GET_CODE (x
) == MEM
)
2535 output_address (GET_MODE (x
), XEXP (x
, 0));
2536 else if (GET_CODE (x
) == CONST_INT
)
2537 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2539 output_addr_const (file
, x
);
2544 /* A C compound statement to output to stdio stream STREAM the
2545 assembler syntax for an instruction operand that is a memory
2546 reference whose address is ADDR. ADDR is an RTL expression. */
2549 print_operand_address (FILE *file
, rtx addr
)
2552 error ("PRINT_OPERAND_ADDRESS, null pointer");
2554 switch (GET_CODE (addr
))
2557 fatal_insn ("invalid address", addr
);
2561 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2567 rtx offset
= (rtx
)0;
2568 rtx arg0
= XEXP (addr
, 0);
2569 rtx arg1
= XEXP (addr
, 1);
2571 if (GET_CODE (arg0
) == REG
)
2576 else if (GET_CODE (arg1
) == REG
)
2582 fatal_insn ("no register in address", addr
);
2584 if (CONSTANT_P (offset
))
2586 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2587 output_addr_const (file
, offset
);
2590 fatal_insn ("address offset not a constant", addr
);
2598 output_addr_const (file
, addr
);
2603 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2606 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2608 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2610 switch (XINT (x
, 1))
2613 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2614 fputs ("@TPOFF", fp
);
2617 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2618 fputs ("@DTPOFF", fp
);
2623 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2636 xtensa_output_integer_literal_parts (FILE *file
, rtx x
, int size
)
2638 if (size
> 4 && !(size
& (size
- 1)))
2642 split_double (x
, &first
, &second
);
2643 xtensa_output_integer_literal_parts (file
, first
, size
/ 2);
2645 xtensa_output_integer_literal_parts (file
, second
, size
/ 2);
2649 output_addr_const (file
, x
);
2658 xtensa_output_literal (FILE *file
, rtx x
, machine_mode mode
, int labelno
)
2662 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2664 switch (GET_MODE_CLASS (mode
))
2667 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
2672 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
),
2674 if (HOST_BITS_PER_LONG
> 32)
2675 value_long
[0] &= 0xffffffff;
2676 fprintf (file
, "0x%08lx\n", value_long
[0]);
2680 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x
),
2682 if (HOST_BITS_PER_LONG
> 32)
2684 value_long
[0] &= 0xffffffff;
2685 value_long
[1] &= 0xffffffff;
2687 fprintf (file
, "0x%08lx, 0x%08lx\n",
2688 value_long
[0], value_long
[1]);
2698 case MODE_PARTIAL_INT
:
2699 xtensa_output_integer_literal_parts (file
, x
, GET_MODE_SIZE (mode
));
2709 xtensa_call_save_reg(int regno
)
2711 if (TARGET_WINDOWED_ABI
)
2714 if (regno
== A0_REG
)
2715 return crtl
->profile
|| !crtl
->is_leaf
|| crtl
->calls_eh_return
||
2716 df_regs_ever_live_p (regno
);
2718 if (crtl
->calls_eh_return
&& regno
>= 2 && regno
< 4)
2721 return !call_used_or_fixed_reg_p (regno
) && df_regs_ever_live_p (regno
);
2724 /* Return the bytes needed to compute the frame pointer from the current
2727 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2728 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2731 compute_frame_size (poly_int64 size
)
2735 if (reload_completed
&& cfun
->machine
->frame_laid_out
)
2736 return cfun
->machine
->current_frame_size
;
2738 /* Add space for the incoming static chain value. */
2739 if (cfun
->static_chain_decl
!= NULL
)
2740 size
+= (1 * UNITS_PER_WORD
);
2742 cfun
->machine
->callee_save_size
= 0;
2743 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2745 if (xtensa_call_save_reg(regno
))
2746 cfun
->machine
->callee_save_size
+= UNITS_PER_WORD
;
2749 cfun
->machine
->current_frame_size
=
2750 XTENSA_STACK_ALIGN (size
2751 + cfun
->machine
->callee_save_size
2752 + crtl
->outgoing_args_size
2753 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2754 cfun
->machine
->callee_save_size
=
2755 XTENSA_STACK_ALIGN (cfun
->machine
->callee_save_size
);
2756 cfun
->machine
->frame_laid_out
= true;
2757 return cfun
->machine
->current_frame_size
;
2762 xtensa_frame_pointer_required (void)
2764 /* The code to expand builtin_frame_addr and builtin_return_addr
2765 currently uses the hard_frame_pointer instead of frame_pointer.
2766 This seems wrong but maybe it's necessary for other architectures.
2767 This function is derived from the i386 code. */
2769 if (cfun
->machine
->accesses_prev_frame
|| cfun
->has_nonlocal_label
)
2776 xtensa_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
2778 long frame_size
= compute_frame_size (get_frame_size ());
2779 HOST_WIDE_INT offset
;
2783 case FRAME_POINTER_REGNUM
:
2784 if (FRAME_GROWS_DOWNWARD
)
2785 offset
= frame_size
- (WINDOW_SIZE
* UNITS_PER_WORD
)
2786 - cfun
->machine
->callee_save_size
;
2790 case ARG_POINTER_REGNUM
:
2791 offset
= frame_size
;
2800 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2801 and the total number of words must be a multiple of 128 bits. */
2802 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2805 xtensa_expand_prologue (void)
2807 HOST_WIDE_INT total_size
;
2808 rtx_insn
*insn
= NULL
;
2812 total_size
= compute_frame_size (get_frame_size ());
2814 if (flag_stack_usage_info
)
2815 current_function_static_stack_size
= total_size
;
2817 if (TARGET_WINDOWED_ABI
)
2819 if (total_size
< (1 << (12+3)))
2820 insn
= emit_insn (gen_entry (GEN_INT (total_size
)));
2823 /* Use a8 as a temporary since a0-a7 may be live. */
2824 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2825 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
2826 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2827 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2828 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
2834 HOST_WIDE_INT offset
= 0;
2835 int callee_save_size
= cfun
->machine
->callee_save_size
;
2837 /* -128 is a limit of single addi instruction. */
2838 if (total_size
> 0 && total_size
<= 128)
2840 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2841 GEN_INT (-total_size
)));
2842 RTX_FRAME_RELATED_P (insn
) = 1;
2843 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2844 plus_constant (Pmode
, stack_pointer_rtx
,
2846 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2847 offset
= total_size
- UNITS_PER_WORD
;
2849 else if (callee_save_size
)
2851 /* 1020 is maximal s32i offset, if the frame is bigger than that
2852 * we move sp to the end of callee-saved save area, save and then
2853 * move it to its final location. */
2854 if (total_size
> 1024)
2856 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2857 GEN_INT (-callee_save_size
)));
2858 RTX_FRAME_RELATED_P (insn
) = 1;
2859 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2860 plus_constant (Pmode
, stack_pointer_rtx
,
2861 -callee_save_size
));
2862 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2863 offset
= callee_save_size
- UNITS_PER_WORD
;
2867 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2868 emit_move_insn (tmp_reg
, GEN_INT (total_size
));
2869 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2870 stack_pointer_rtx
, tmp_reg
));
2871 RTX_FRAME_RELATED_P (insn
) = 1;
2872 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2873 plus_constant (Pmode
, stack_pointer_rtx
,
2875 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2876 offset
= total_size
- UNITS_PER_WORD
;
2880 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2882 if (xtensa_call_save_reg(regno
))
2884 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2885 rtx mem
= gen_frame_mem (SImode
, x
);
2886 rtx reg
= gen_rtx_REG (SImode
, regno
);
2888 offset
-= UNITS_PER_WORD
;
2889 insn
= emit_move_insn (mem
, reg
);
2890 RTX_FRAME_RELATED_P (insn
) = 1;
2891 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
2892 gen_rtx_SET (mem
, reg
));
2895 if (total_size
> 1024
2896 || (!callee_save_size
&& total_size
> 128))
2898 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2899 emit_move_insn (tmp_reg
, GEN_INT (total_size
-
2901 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2902 stack_pointer_rtx
, tmp_reg
));
2903 RTX_FRAME_RELATED_P (insn
) = 1;
2904 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2905 plus_constant (Pmode
, stack_pointer_rtx
,
2908 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2912 if (frame_pointer_needed
)
2914 if (cfun
->machine
->set_frame_ptr_insn
)
2918 push_topmost_sequence ();
2919 first
= get_insns ();
2920 pop_topmost_sequence ();
2922 /* For all instructions prior to set_frame_ptr_insn, replace
2923 hard_frame_pointer references with stack_pointer. */
2925 insn
!= cfun
->machine
->set_frame_ptr_insn
;
2926 insn
= NEXT_INSN (insn
))
2930 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2931 hard_frame_pointer_rtx
,
2933 df_insn_rescan (insn
);
2939 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2940 stack_pointer_rtx
));
2941 if (!TARGET_WINDOWED_ABI
)
2943 note_rtx
= gen_rtx_SET (hard_frame_pointer_rtx
,
2945 RTX_FRAME_RELATED_P (insn
) = 1;
2946 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2951 if (TARGET_WINDOWED_ABI
)
2953 /* Create a note to describe the CFA. Because this is only used to set
2954 DW_AT_frame_base for debug info, don't bother tracking changes through
2955 each instruction in the prologue. It just takes up space. */
2956 note_rtx
= gen_rtx_SET ((frame_pointer_needed
2957 ? hard_frame_pointer_rtx
2958 : stack_pointer_rtx
),
2959 plus_constant (Pmode
, stack_pointer_rtx
,
2961 RTX_FRAME_RELATED_P (insn
) = 1;
2962 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2967 xtensa_expand_epilogue (void)
2969 if (!TARGET_WINDOWED_ABI
)
2972 HOST_WIDE_INT offset
;
2974 if (cfun
->machine
->current_frame_size
> (frame_pointer_needed
? 127 : 1024))
2976 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2977 emit_move_insn (tmp_reg
, GEN_INT (cfun
->machine
->current_frame_size
-
2978 cfun
->machine
->callee_save_size
));
2979 emit_insn (gen_addsi3 (stack_pointer_rtx
, frame_pointer_needed
?
2980 hard_frame_pointer_rtx
: stack_pointer_rtx
,
2982 offset
= cfun
->machine
->callee_save_size
- UNITS_PER_WORD
;
2986 if (frame_pointer_needed
)
2987 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
2988 offset
= cfun
->machine
->current_frame_size
- UNITS_PER_WORD
;
2991 /* Prevent reordering of saved a0 update and loading it back from
2993 if (crtl
->calls_eh_return
)
2994 emit_insn (gen_blockage ());
2996 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2998 if (xtensa_call_save_reg(regno
))
3000 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
3002 offset
-= UNITS_PER_WORD
;
3003 emit_move_insn (gen_rtx_REG (SImode
, regno
),
3004 gen_frame_mem (SImode
, x
));
3008 if (cfun
->machine
->current_frame_size
> 0)
3010 if (frame_pointer_needed
|| /* always reachable with addi */
3011 cfun
->machine
->current_frame_size
> 1024 ||
3012 cfun
->machine
->current_frame_size
<= 127)
3014 if (cfun
->machine
->current_frame_size
<= 127)
3015 offset
= cfun
->machine
->current_frame_size
;
3017 offset
= cfun
->machine
->callee_save_size
;
3019 emit_insn (gen_addsi3 (stack_pointer_rtx
,
3025 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
3026 emit_move_insn (tmp_reg
,
3027 GEN_INT (cfun
->machine
->current_frame_size
));
3028 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
3033 if (crtl
->calls_eh_return
)
3034 emit_insn (gen_add3_insn (stack_pointer_rtx
,
3036 EH_RETURN_STACKADJ_RTX
));
3038 cfun
->machine
->epilogue_done
= true;
3039 emit_jump_insn (gen_return ());
3043 xtensa_use_return_instruction_p (void)
3045 if (!reload_completed
)
3047 if (TARGET_WINDOWED_ABI
)
3049 if (compute_frame_size (get_frame_size ()) == 0)
3051 return cfun
->machine
->epilogue_done
;
3055 xtensa_set_return_address (rtx address
, rtx scratch
)
3057 HOST_WIDE_INT total_size
= compute_frame_size (get_frame_size ());
3058 rtx frame
= frame_pointer_needed
?
3059 hard_frame_pointer_rtx
: stack_pointer_rtx
;
3060 rtx a0_addr
= plus_constant (Pmode
, frame
,
3061 total_size
- UNITS_PER_WORD
);
3062 rtx note
= gen_rtx_SET (gen_frame_mem (SImode
, a0_addr
),
3063 gen_rtx_REG (SImode
, A0_REG
));
3066 if (total_size
> 1024) {
3067 emit_move_insn (scratch
, GEN_INT (total_size
- UNITS_PER_WORD
));
3068 emit_insn (gen_addsi3 (scratch
, frame
, scratch
));
3072 insn
= emit_move_insn (gen_frame_mem (SImode
, a0_addr
), address
);
3073 RTX_FRAME_RELATED_P (insn
) = 1;
3074 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
3078 xtensa_return_addr (int count
, rtx frame
)
3080 rtx result
, retaddr
, curaddr
, label
;
3082 if (!TARGET_WINDOWED_ABI
)
3087 return get_hard_reg_initial_val (Pmode
, A0_REG
);
3091 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
3094 rtx addr
= plus_constant (Pmode
, frame
, -4 * UNITS_PER_WORD
);
3095 addr
= memory_address (Pmode
, addr
);
3096 retaddr
= gen_reg_rtx (Pmode
);
3097 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
3100 /* The 2 most-significant bits of the return address on Xtensa hold
3101 the register window size. To get the real return address, these
3102 bits must be replaced with the high bits from some address in the
3105 /* Get the 2 high bits of a local label in the code. */
3106 curaddr
= gen_reg_rtx (Pmode
);
3107 label
= gen_label_rtx ();
3109 LABEL_PRESERVE_P (label
) = 1;
3110 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
3111 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
3112 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
3114 /* Clear the 2 high bits of the return address. */
3115 result
= gen_reg_rtx (Pmode
);
3116 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
3117 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
3119 /* Combine them to get the result. */
3120 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
3124 /* Disable the use of word-sized or smaller complex modes for structures,
3125 and for function arguments in particular, where they cause problems with
3126 register a7. The xtensa_copy_incoming_a7 function assumes that there is
3127 a single reference to an argument in a7, but with small complex modes the
3128 real and imaginary components may be extracted separately, leading to two
3129 uses of the register, only one of which would be replaced. */
3132 xtensa_member_type_forces_blk (const_tree
, machine_mode mode
)
3134 return mode
== CQImode
|| mode
== CHImode
;
3137 /* Create the va_list data type.
3139 This structure is set up by __builtin_saveregs. The __va_reg field
3140 points to a stack-allocated region holding the contents of the
3141 incoming argument registers. The __va_ndx field is an index
3142 initialized to the position of the first unnamed (variable)
3143 argument. This same index is also used to address the arguments
3144 passed in memory. Thus, the __va_stk field is initialized to point
3145 to the position of the first argument in memory offset to account
3146 for the arguments passed in registers and to account for the size
3147 of the argument registers not being 16-byte aligned. E.G., there
3148 are 6 argument registers of 4 bytes each, but we want the __va_ndx
3149 for the first stack argument to have the maximal alignment of 16
3150 bytes, so we offset the __va_stk address by 32 bytes so that
3151 __va_stk[32] references the first argument on the stack. */
3154 xtensa_build_builtin_va_list (void)
3156 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
3158 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
3159 type_decl
= build_decl (BUILTINS_LOCATION
,
3160 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
3162 f_stk
= build_decl (BUILTINS_LOCATION
,
3163 FIELD_DECL
, get_identifier ("__va_stk"),
3165 f_reg
= build_decl (BUILTINS_LOCATION
,
3166 FIELD_DECL
, get_identifier ("__va_reg"),
3168 f_ndx
= build_decl (BUILTINS_LOCATION
,
3169 FIELD_DECL
, get_identifier ("__va_ndx"),
3172 DECL_FIELD_CONTEXT (f_stk
) = record
;
3173 DECL_FIELD_CONTEXT (f_reg
) = record
;
3174 DECL_FIELD_CONTEXT (f_ndx
) = record
;
3176 TYPE_STUB_DECL (record
) = type_decl
;
3177 TYPE_NAME (record
) = type_decl
;
3178 TYPE_FIELDS (record
) = f_stk
;
3179 DECL_CHAIN (f_stk
) = f_reg
;
3180 DECL_CHAIN (f_reg
) = f_ndx
;
3182 layout_type (record
);
3187 /* Save the incoming argument registers on the stack. Returns the
3188 address of the saved registers. */
3191 xtensa_builtin_saveregs (void)
3194 int arg_words
= crtl
->args
.info
.arg_words
;
3195 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
3200 /* Allocate the general-purpose register space. */
3201 gp_regs
= assign_stack_local
3202 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
3203 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
3205 /* Now store the incoming registers. */
3206 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
3207 cfun
->machine
->vararg_a7
= true;
3208 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
3209 adjust_address (gp_regs
, BLKmode
,
3210 arg_words
* UNITS_PER_WORD
),
3212 if (cfun
->machine
->vararg_a7_copy
!= 0)
3213 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
3215 return XEXP (gp_regs
, 0);
3219 /* Implement `va_start' for varargs and stdarg. We look at the
3220 current function to fill in an initial va_list. */
3223 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
3231 arg_words
= crtl
->args
.info
.arg_words
;
3233 f_stk
= TYPE_FIELDS (va_list_type_node
);
3234 f_reg
= DECL_CHAIN (f_stk
);
3235 f_ndx
= DECL_CHAIN (f_reg
);
3237 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
3238 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3240 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3243 /* Call __builtin_saveregs; save the result in __va_reg */
3244 u
= make_tree (sizetype
, expand_builtin_saveregs ());
3245 u
= fold_convert (ptr_type_node
, u
);
3246 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
3247 TREE_SIDE_EFFECTS (t
) = 1;
3248 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3250 /* Set the __va_stk member to ($arg_ptr - 32). */
3251 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
3252 u
= fold_build_pointer_plus_hwi (u
, -32);
3253 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
3254 TREE_SIDE_EFFECTS (t
) = 1;
3255 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3257 /* Set the __va_ndx member. If the first variable argument is on
3258 the stack, adjust __va_ndx by 2 words to account for the extra
3259 alignment offset for __va_stk. */
3260 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
3262 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
3263 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
3264 TREE_SIDE_EFFECTS (t
) = 1;
3265 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3269 /* Implement `va_arg'. */
3272 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
3273 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
3278 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
3279 tree lab_false
, lab_over
, lab_false2
;
3282 indirect
= pass_va_arg_by_reference (type
);
3284 type
= build_pointer_type (type
);
3286 /* Handle complex values as separate real and imaginary parts. */
3287 if (TREE_CODE (type
) == COMPLEX_TYPE
)
3289 tree real_part
, imag_part
;
3291 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
3293 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
3295 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
3298 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
3300 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
3303 f_stk
= TYPE_FIELDS (va_list_type_node
);
3304 f_reg
= DECL_CHAIN (f_stk
);
3305 f_ndx
= DECL_CHAIN (f_reg
);
3307 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
3309 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3311 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3314 type_size
= size_in_bytes (type
);
3315 va_size
= round_up (type_size
, UNITS_PER_WORD
);
3316 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
3319 /* First align __va_ndx if necessary for this arg:
3321 orig_ndx = (AP).__va_ndx;
3322 if (__alignof__ (TYPE) > 4 )
3323 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3324 & -__alignof__ (TYPE)); */
3326 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
3328 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
3330 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
3332 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
3333 build_int_cst (integer_type_node
, align
- 1));
3334 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
3335 build_int_cst (integer_type_node
, -align
));
3336 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
3340 /* Increment __va_ndx to point past the argument:
3342 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3344 t
= fold_convert (integer_type_node
, va_size
);
3345 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
3346 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3349 /* Check if the argument is in registers:
3351 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3352 && !must_pass_in_stack (type))
3353 __array = (AP).__va_reg; */
3355 array
= create_tmp_var (ptr_type_node
);
3358 if (!must_pass_va_arg_in_stack (type
))
3360 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
3361 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
3363 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
3364 build_int_cst (integer_type_node
,
3365 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3366 t
= build3 (COND_EXPR
, void_type_node
, t
,
3367 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
3369 gimplify_and_add (t
, pre_p
);
3371 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
3373 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
3374 gimplify_and_add (t
, pre_p
);
3376 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
3377 gimplify_and_add (t
, pre_p
);
3381 /* ...otherwise, the argument is on the stack (never split between
3382 registers and the stack -- change __va_ndx if necessary):
3386 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3387 (AP).__va_ndx = 32 + __va_size (TYPE);
3388 __array = (AP).__va_stk;
3391 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
3393 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
3394 build_int_cst (integer_type_node
,
3395 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3396 t
= build3 (COND_EXPR
, void_type_node
, t
,
3397 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
3399 gimplify_and_add (t
, pre_p
);
3401 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
3402 t
= fold_convert (integer_type_node
, t
);
3403 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3405 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
3406 gimplify_and_add (t
, pre_p
);
3408 gimplify_assign (array
, stk
, pre_p
);
3412 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
3413 gimplify_and_add (t
, pre_p
);
3417 /* Given the base array pointer (__array) and index to the subsequent
3418 argument (__va_ndx), find the address:
3420 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3424 The results are endian-dependent because values smaller than one word
3425 are aligned differently. */
3428 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
3430 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
3431 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
3432 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
3433 unshare_expr (type_size
));
3437 size
= unshare_expr (va_size
);
3439 t
= fold_convert (sizetype
, unshare_expr (ndx
));
3440 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
3441 addr
= fold_build_pointer_plus (unshare_expr (array
), t
);
3443 addr
= fold_convert (build_pointer_type (type
), addr
);
3445 addr
= build_va_arg_indirect_ref (addr
);
3446 return build_va_arg_indirect_ref (addr
);
3454 XTENSA_BUILTIN_UMULSIDI3
,
3460 xtensa_init_builtins (void)
3464 ftype
= build_function_type_list (unsigned_intDI_type_node
,
3465 unsigned_intSI_type_node
,
3466 unsigned_intSI_type_node
, NULL_TREE
);
3468 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
3469 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
3470 "__umulsidi3", NULL_TREE
);
3471 TREE_NOTHROW (decl
) = 1;
3472 TREE_READONLY (decl
) = 1;
3477 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3478 bool ignore ATTRIBUTE_UNUSED
)
3480 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
3485 case XTENSA_BUILTIN_UMULSIDI3
:
3488 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3489 || TARGET_MUL32_HIGH
)
3490 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3491 fold_convert (unsigned_intDI_type_node
, arg0
),
3492 fold_convert (unsigned_intDI_type_node
, arg1
));
3496 internal_error ("bad builtin code");
3505 xtensa_expand_builtin (tree exp
, rtx target
,
3506 rtx subtarget ATTRIBUTE_UNUSED
,
3507 machine_mode mode ATTRIBUTE_UNUSED
,
3510 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3511 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
3515 case XTENSA_BUILTIN_UMULSIDI3
:
3516 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3517 __umulsidi3 function when the Xtensa configuration can directly
3518 implement it. If not, just call the function. */
3519 return expand_call (exp
, target
, ignore
);
3522 internal_error ("bad builtin code");
3527 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3530 xtensa_preferred_reload_class (rtx x
, reg_class_t rclass
)
3532 if (CONSTANT_P (x
) && CONST_DOUBLE_P (x
))
3535 /* Don't use the stack pointer or hard frame pointer for reloads!
3536 The hard frame pointer would normally be OK except that it may
3537 briefly hold an incoming argument in the prologue, and reload
3538 won't know that it is live because the hard frame pointer is
3539 treated specially. */
3541 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3547 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3550 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED
,
3553 /* Don't use the stack pointer or hard frame pointer for reloads!
3554 The hard frame pointer would normally be OK except that it may
3555 briefly hold an incoming argument in the prologue, and reload
3556 won't know that it is live because the hard frame pointer is
3557 treated specially. */
3559 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3565 /* Worker function for TARGET_SECONDARY_RELOAD. */
3568 xtensa_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass
,
3569 machine_mode mode
, secondary_reload_info
*sri
)
3573 if (in_p
&& constantpool_mem_p (x
))
3575 if (rclass
== FP_REGS
)
3579 sri
->icode
= CODE_FOR_reloadqi_literal
;
3580 else if (mode
== HImode
)
3581 sri
->icode
= CODE_FOR_reloadhi_literal
;
3584 regno
= xt_true_regnum (x
);
3585 if (ACC_REG_P (regno
))
3586 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3587 if (rclass
== ACC_REG
)
3588 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3595 order_regs_for_local_alloc (void)
3597 if (!leaf_function_p ())
3599 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
3601 static const int reg_nonleaf_alloc_order_call0
[FIRST_PSEUDO_REGISTER
] =
3603 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
3605 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
3610 memcpy (reg_alloc_order
, TARGET_WINDOWED_ABI
?
3611 reg_nonleaf_alloc_order
: reg_nonleaf_alloc_order_call0
,
3612 FIRST_PSEUDO_REGISTER
* sizeof (int));
3616 int i
, num_arg_regs
;
3619 /* Use the AR registers in increasing order (skipping a0 and a1)
3620 but save the incoming argument registers for a last resort. */
3621 num_arg_regs
= crtl
->args
.info
.arg_words
;
3622 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
3623 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
3624 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
3625 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
3626 for (i
= 0; i
< num_arg_regs
; i
++)
3627 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
3629 /* List the coprocessor registers in order. */
3630 for (i
= 0; i
< BR_REG_NUM
; i
++)
3631 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
3633 /* List the FP registers in order for now. */
3634 for (i
= 0; i
< 16; i
++)
3635 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
3637 /* GCC requires that we list *all* the registers.... */
3638 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
3639 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
3640 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
3641 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
3643 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
3648 /* Some Xtensa targets support multiple bss sections. If the section
3649 name ends with ".bss", add SECTION_BSS to the flags. */
3652 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
3654 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
3657 suffix
= strrchr (name
, '.');
3658 if (suffix
&& strcmp (suffix
, ".bss") == 0)
3660 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
3661 && DECL_INITIAL (decl
) == NULL_TREE
))
3662 flags
|= SECTION_BSS
; /* @nobits */
3664 warning (0, "only uninitialized variables can be placed in a "
3672 /* The literal pool stays with the function. */
3675 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED
,
3676 rtx x ATTRIBUTE_UNUSED
,
3677 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
3679 return function_section (current_function_decl
);
3682 /* Worker function for TARGET_REGISTER_MOVE_COST. */
3685 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3686 reg_class_t from
, reg_class_t to
)
3688 if (from
== to
&& from
!= BR_REGS
&& to
!= BR_REGS
)
3690 else if (reg_class_subset_p (from
, AR_REGS
)
3691 && reg_class_subset_p (to
, AR_REGS
))
3693 else if (reg_class_subset_p (from
, AR_REGS
) && to
== ACC_REG
)
3695 else if (from
== ACC_REG
&& reg_class_subset_p (to
, AR_REGS
))
3701 /* Worker function for TARGET_MEMORY_MOVE_COST. */
3704 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3705 reg_class_t rclass ATTRIBUTE_UNUSED
,
3706 bool in ATTRIBUTE_UNUSED
)
3711 /* Compute a (partial) cost for rtx X. Return true if the complete
3712 cost has been computed, and false if subexpressions should be
3713 scanned. In either case, *TOTAL contains the cost result. */
3716 xtensa_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
3717 int opno ATTRIBUTE_UNUSED
,
3718 int *total
, bool speed ATTRIBUTE_UNUSED
)
3720 int code
= GET_CODE (x
);
3728 if (xtensa_simm12b (INTVAL (x
)))
3735 if (xtensa_simm8 (INTVAL (x
))
3736 || xtensa_simm8x256 (INTVAL (x
)))
3743 if (xtensa_mask_immediate (INTVAL (x
)))
3750 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
3761 /* No way to tell if X is the 2nd operand so be conservative. */
3764 if (xtensa_simm12b (INTVAL (x
)))
3766 else if (TARGET_CONST16
)
3767 *total
= COSTS_N_INSNS (2);
3776 *total
= COSTS_N_INSNS (2);
3783 *total
= COSTS_N_INSNS (4);
3791 (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3793 if (memory_address_p (mode
, XEXP ((x
), 0)))
3794 *total
= COSTS_N_INSNS (num_words
);
3796 *total
= COSTS_N_INSNS (2*num_words
);
3802 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
3806 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
3810 *total
= COSTS_N_INSNS (mode
== DImode
? 3 : 2);
3817 *total
= COSTS_N_INSNS (2);
3819 *total
= COSTS_N_INSNS (1);
3826 *total
= COSTS_N_INSNS (50);
3828 *total
= COSTS_N_INSNS (1);
3834 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3835 else if (mode
== DFmode
)
3836 *total
= COSTS_N_INSNS (50);
3838 *total
= COSTS_N_INSNS (4);
3846 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3847 else if (mode
== DFmode
|| mode
== DImode
)
3848 *total
= COSTS_N_INSNS (50);
3850 *total
= COSTS_N_INSNS (1);
3855 *total
= COSTS_N_INSNS (mode
== DImode
? 4 : 2);
3861 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3862 else if (mode
== DFmode
)
3863 *total
= COSTS_N_INSNS (50);
3864 else if (mode
== DImode
)
3865 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
3866 else if (TARGET_MUL32
)
3867 *total
= COSTS_N_INSNS (4);
3868 else if (TARGET_MAC16
)
3869 *total
= COSTS_N_INSNS (16);
3870 else if (TARGET_MUL16
)
3871 *total
= COSTS_N_INSNS (12);
3873 *total
= COSTS_N_INSNS (50);
3882 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3885 else if (mode
== DFmode
)
3887 *total
= COSTS_N_INSNS (50);
3897 *total
= COSTS_N_INSNS (50);
3898 else if (TARGET_DIV32
)
3899 *total
= COSTS_N_INSNS (32);
3901 *total
= COSTS_N_INSNS (50);
3907 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3909 *total
= COSTS_N_INSNS (50);
3916 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3921 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3926 *total
= COSTS_N_INSNS (1);
3934 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3937 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3939 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
3940 > 4 * UNITS_PER_WORD
);
3943 /* Worker function for TARGET_FUNCTION_VALUE. */
3946 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
3949 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
3950 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
3951 ? SImode
: TYPE_MODE (valtype
),
3952 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
3955 /* Worker function for TARGET_LIBCALL_VALUE. */
3958 xtensa_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
3960 return gen_rtx_REG ((GET_MODE_CLASS (mode
) == MODE_INT
3961 && GET_MODE_SIZE (mode
) < UNITS_PER_WORD
)
3962 ? SImode
: mode
, GP_RETURN
);
3965 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
3968 xtensa_function_value_regno_p (const unsigned int regno
)
3970 return (regno
== GP_RETURN
);
3973 /* The static chain is passed in memory. Provide rtx giving 'mem'
3974 expressions that denote where they are stored. */
3977 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl_or_type
), bool incoming_p
)
3979 if (TARGET_WINDOWED_ABI
)
3981 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
3982 return gen_frame_mem (Pmode
, plus_constant (Pmode
, base
,
3983 -5 * UNITS_PER_WORD
));
3986 return gen_rtx_REG (Pmode
, A8_REG
);
3990 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3991 instruction with a minimal stack frame in order to get some free
3992 registers. Once the actual call target is known, the proper stack frame
3993 size is extracted from the ENTRY instruction at the target and the
3994 current frame is adjusted to match. The trampoline then transfers
3995 control to the instruction following the ENTRY at the target. Note:
3996 this assumes that the target begins with an ENTRY instruction. */
3999 xtensa_asm_trampoline_template (FILE *stream
)
4001 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
4003 fprintf (stream
, "\t.begin no-transform\n");
4005 if (TARGET_WINDOWED_ABI
)
4007 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
4011 /* Save the return address. */
4012 fprintf (stream
, "\tmov\ta10, a0\n");
4014 /* Use a CALL0 instruction to skip past the constants and in the
4015 process get the PC into A0. This allows PC-relative access to
4016 the constants without relying on L32R. */
4017 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
4020 fprintf (stream
, "\tj\t.Lskipconsts\n");
4022 fprintf (stream
, "\t.align\t4\n");
4023 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
4024 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
4025 fprintf (stream
, ".Lskipconsts:\n");
4027 /* Load the static chain and function address from the trampoline. */
4030 fprintf (stream
, "\taddi\ta0, a0, 3\n");
4031 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
4032 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
4036 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
4037 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
4040 /* Store the static chain. */
4041 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
4043 /* Set the proper stack pointer value. */
4044 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
4045 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
4046 TARGET_BIG_ENDIAN
? 8 : 12);
4047 fprintf (stream
, "\tslli\ta9, a9, 3\n");
4048 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
4049 fprintf (stream
, "\tsub\ta9, sp, a9\n");
4050 fprintf (stream
, "\tmovsp\tsp, a9\n");
4053 /* Restore the return address. */
4054 fprintf (stream
, "\tmov\ta0, a10\n");
4056 /* Jump to the instruction following the ENTRY. */
4057 fprintf (stream
, "\taddi\ta8, a8, 3\n");
4058 fprintf (stream
, "\tjx\ta8\n");
4060 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4062 fprintf (stream
, "\t.byte\t0\n");
4064 fprintf (stream
, "\tnop\n");
4070 /* Save the return address. */
4071 fprintf (stream
, "\tmov\ta10, a0\n");
4073 /* Use a CALL0 instruction to skip past the constants and in the
4074 process get the PC into A0. This allows PC-relative access to
4075 the constants without relying on L32R. */
4076 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
4079 fprintf (stream
, "\tj\t.Lskipconsts\n");
4081 fprintf (stream
, "\t.align\t4\n");
4082 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
4083 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
4084 fprintf (stream
, ".Lskipconsts:\n");
4086 /* Load the static chain and function address from the trampoline. */
4089 fprintf (stream
, "\taddi\ta0, a0, 3\n");
4090 fprintf (stream
, "\tl32i\ta8, a0, 0\n");
4091 fprintf (stream
, "\tl32i\ta9, a0, 4\n");
4092 fprintf (stream
, "\tmov\ta0, a10\n");
4096 fprintf (stream
, "\tl32r\ta8, .Lchainval\n");
4097 fprintf (stream
, "\tl32r\ta9, .Lfnaddr\n");
4099 fprintf (stream
, "\tjx\ta9\n");
4101 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4103 fprintf (stream
, "\t.byte\t0\n");
4105 fprintf (stream
, "\tnop\n");
4107 fprintf (stream
, "\t.end no-transform\n");
4111 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
4113 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
4114 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
4118 if (TARGET_WINDOWED_ABI
)
4120 chain_off
= use_call0
? 12 : 8;
4121 func_off
= use_call0
? 16 : 12;
4125 chain_off
= use_call0
? 8 : 4;
4126 func_off
= use_call0
? 12 : 8;
4129 emit_block_move (m_tramp
, assemble_trampoline_template (),
4130 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4132 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
4133 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
4134 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
4135 LCT_NORMAL
, VOIDmode
, XEXP (m_tramp
, 0), Pmode
);
4138 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
4141 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
4143 return !xtensa_tls_referenced_p (x
);
4146 /* Implement TARGET_CAN_USE_DOLOOP_P. */
4149 xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
4150 unsigned int loop_depth
, bool entered_at_top
)
4152 /* Considering limitations in the hardware, only use doloop
4153 for innermost loops which must be entered from the top. */
4154 if (loop_depth
> 1 || !entered_at_top
)
4160 /* NULL if INSN insn is valid within a low-overhead loop.
4161 Otherwise return why doloop cannot be applied. */
4164 xtensa_invalid_within_doloop (const rtx_insn
*insn
)
4167 return "Function call in the loop.";
4169 if (JUMP_P (insn
) && INSN_CODE (insn
) == CODE_FOR_return
)
4170 return "Return from a call instruction in the loop.";
4175 /* Optimize LOOP. */
4178 hwloop_optimize (hwloop_info loop
)
4182 basic_block entry_bb
;
4184 rtx_insn
*insn
, *seq
, *entry_after
;
4186 if (loop
->depth
> 1)
4189 fprintf (dump_file
, ";; loop %d is not innermost\n",
4194 if (!loop
->incoming_dest
)
4197 fprintf (dump_file
, ";; loop %d has more than one entry\n",
4202 if (loop
->incoming_dest
!= loop
->head
)
4205 fprintf (dump_file
, ";; loop %d is not entered from head\n",
4210 if (loop
->has_call
|| loop
->has_asm
)
4213 fprintf (dump_file
, ";; loop %d has invalid insn\n",
4218 /* Scan all the blocks to make sure they don't use iter_reg. */
4219 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
4222 fprintf (dump_file
, ";; loop %d uses iterator\n",
4227 /* Check if start_label appears before doloop_end. */
4228 insn
= loop
->start_label
;
4229 while (insn
&& insn
!= loop
->loop_end
)
4230 insn
= NEXT_INSN (insn
);
4235 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
4240 /* Get the loop iteration register. */
4241 iter_reg
= loop
->iter_reg
;
4243 gcc_assert (REG_P (iter_reg
));
4247 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
4248 if (entry_edge
->flags
& EDGE_FALLTHRU
)
4251 if (entry_edge
== NULL
)
4254 /* Place the zero_cost_loop_start instruction before the loop. */
4255 entry_bb
= entry_edge
->src
;
4259 insn
= emit_insn (gen_zero_cost_loop_start (loop
->iter_reg
,
4265 entry_after
= BB_END (entry_bb
);
4266 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
4273 emit_insn_before (seq
, BB_HEAD (loop
->head
));
4274 seq
= emit_label_before (gen_label_rtx (), seq
);
4275 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
4276 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
4278 if (!(e
->flags
& EDGE_FALLTHRU
))
4279 redirect_edge_and_branch_force (e
, new_bb
);
4281 redirect_edge_succ (e
, new_bb
);
4284 make_edge (new_bb
, loop
->head
, 0);
4288 while (DEBUG_INSN_P (entry_after
)
4289 || (NOTE_P (entry_after
)
4290 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
))
4291 entry_after
= PREV_INSN (entry_after
);
4293 emit_insn_after (seq
, entry_after
);
4301 /* A callback for the hw-doloop pass. Called when a loop we have discovered
4302 turns out not to be optimizable; we have to split the loop_end pattern into
4303 a subtract and a test. */
4306 hwloop_fail (hwloop_info loop
)
4309 rtx_insn
*insn
= loop
->loop_end
;
4311 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
4316 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
4317 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
4318 loop
->iter_reg
, const0_rtx
,
4322 JUMP_LABEL (insn
) = loop
->start_label
;
4323 LABEL_NUSES (loop
->start_label
)++;
4324 delete_insn (loop
->loop_end
);
4327 /* A callback for the hw-doloop pass. This function examines INSN; if
4328 it is a doloop_end pattern we recognize, return the reg rtx for the
4329 loop counter. Otherwise, return NULL_RTX. */
4332 hwloop_pattern_reg (rtx_insn
*insn
)
4336 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
4339 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
4347 static struct hw_doloop_hooks xtensa_doloop_hooks
=
4354 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
4355 and tries to rewrite the RTL of these loops so that proper Xtensa
4356 hardware loops are generated. */
4359 xtensa_reorg_loops (void)
4362 reorg_loops (false, &xtensa_doloop_hooks
);
4365 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4370 /* We are freeing block_for_insn in the toplev to keep compatibility
4371 with old MDEP_REORGS that are not CFG based. Recompute it now. */
4372 compute_bb_for_insn ();
4376 /* Doloop optimization. */
4377 xtensa_reorg_loops ();
4380 /* Update register usage after having seen the compiler flags. */
4383 xtensa_conditional_register_usage (void)
4387 c_mask
= TARGET_WINDOWED_ABI
? (1 << 1) : (1 << 2);
4389 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4391 /* Set/reset conditionally defined registers from
4392 CALL_USED_REGISTERS initializer. */
4393 if (call_used_regs
[i
] > 1)
4394 call_used_regs
[i
] = !!(call_used_regs
[i
] & c_mask
);
4397 /* Remove hard FP register from the preferred reload registers set. */
4398 CLEAR_HARD_REG_BIT (reg_class_contents
[(int)RL_REGS
],
4399 HARD_FRAME_POINTER_REGNUM
);
4402 /* Map hard register number to register class */
4404 enum reg_class
xtensa_regno_to_class (int regno
)
4406 static const enum reg_class regno_to_class
[FIRST_PSEUDO_REGISTER
] =
4408 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
4409 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4410 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4411 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4412 AR_REGS
, AR_REGS
, BR_REGS
,
4413 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4414 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4415 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4416 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4420 if (regno
== HARD_FRAME_POINTER_REGNUM
)
4423 return regno_to_class
[regno
];
4426 /* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and
4427 constructors to at least a word boundary. The typical use of this
4428 macro is to increase alignment for string constants to be word
4429 aligned so that 'strcpy' calls that copy constants can be done
4432 static HOST_WIDE_INT
4433 xtensa_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
4435 if ((TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
4437 return MAX (align
, BITS_PER_WORD
);
4442 xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4444 gcc_assert (from
== ARG_POINTER_REGNUM
|| from
== FRAME_POINTER_REGNUM
);
4446 /* If we need a frame pointer, ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM
4447 can only eliminate to HARD_FRAME_POINTER_REGNUM. */
4448 return to
== HARD_FRAME_POINTER_REGNUM
4449 || (!frame_pointer_needed
&& to
== STACK_POINTER_REGNUM
);
4452 /* Implement TARGET_STARTING_FRAME_OFFSET. */
4454 static HOST_WIDE_INT
4455 xtensa_starting_frame_offset (void)
4457 if (FRAME_GROWS_DOWNWARD
)
4459 return crtl
->outgoing_args_size
;
4462 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
4464 static unsigned HOST_WIDE_INT
4465 xtensa_asan_shadow_offset (void)
4467 return HOST_WIDE_INT_UC (0x10000000);
4471 xtensa_delegitimize_address (rtx op
)
4473 switch (GET_CODE (op
))
4476 return xtensa_delegitimize_address (XEXP (op
, 0));
4479 if (XINT (op
, 1) == UNSPEC_PLT
)
4480 return XVECEXP(op
, 0, 0);
4489 #include "gt-xtensa.h"