1 /* Subroutines for insn-output.cc 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"
58 #include "insn-attr.h"
60 /* This file should be included last. */
61 #include "target-def.h"
63 /* Enumeration for all of the relational tests, so that we can build
64 arrays indexed by the test type, and not worry about the order
82 /* Array giving truth value on whether or not a given hard register
83 can support a given mode. */
84 static char xtensa_hard_regno_mode_ok_p
85 [(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
87 /* Largest block move to handle in-line. */
88 #define LARGEST_MOVE_RATIO 15
90 /* Define the structure for the machine field in struct function. */
91 struct GTY(()) machine_function
93 int accesses_prev_frame
;
97 rtx_insn
*set_frame_ptr_insn
;
98 /* Current frame size calculated by compute_frame_size. */
99 unsigned current_frame_size
;
100 /* Callee-save area size in the current frame calculated by
101 compute_frame_size. */
102 int callee_save_size
;
105 bool inhibit_logues_a1_adjusts
;
108 /* Vector, indexed by hard register number, which contains 1 for a
109 register that is allowable in a candidate for leaf function
112 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
114 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
116 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
120 static void xtensa_option_override (void);
121 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
122 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
);
123 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
124 static rtx
gen_conditional_move (enum rtx_code
, machine_mode
, rtx
, rtx
);
125 static rtx
fixup_subreg_mem (rtx
);
126 static struct machine_function
* xtensa_init_machine_status (void);
127 static rtx
xtensa_legitimize_tls_address (rtx
);
128 static rtx
xtensa_legitimize_address (rtx
, rtx
, machine_mode
);
129 static bool xtensa_mode_dependent_address_p (const_rtx
, addr_space_t
);
130 static bool xtensa_return_in_msb (const_tree
);
131 static void printx (FILE *, signed int);
132 static rtx
xtensa_builtin_saveregs (void);
133 static bool xtensa_legitimate_address_p (machine_mode
, rtx
, bool);
134 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
135 int) ATTRIBUTE_UNUSED
;
136 static section
*xtensa_select_rtx_section (machine_mode
, rtx
,
137 unsigned HOST_WIDE_INT
);
138 static bool xtensa_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
139 static int xtensa_insn_cost (rtx_insn
*, bool);
140 static int xtensa_register_move_cost (machine_mode
, reg_class_t
,
142 static int xtensa_memory_move_cost (machine_mode
, reg_class_t
, bool);
143 static tree
xtensa_build_builtin_va_list (void);
144 static bool xtensa_return_in_memory (const_tree
, const_tree
);
145 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
147 static void xtensa_function_arg_advance (cumulative_args_t
,
148 const function_arg_info
&);
149 static rtx
xtensa_function_arg (cumulative_args_t
, const function_arg_info
&);
150 static rtx
xtensa_function_incoming_arg (cumulative_args_t
,
151 const function_arg_info
&);
152 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
153 static rtx
xtensa_libcall_value (machine_mode
, const_rtx
);
154 static bool xtensa_function_value_regno_p (const unsigned int);
155 static unsigned int xtensa_function_arg_boundary (machine_mode
,
157 static void xtensa_init_builtins (void);
158 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
159 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
160 static void xtensa_va_start (tree
, rtx
);
161 static bool xtensa_frame_pointer_required (void);
162 static rtx
xtensa_static_chain (const_tree
, bool);
163 static void xtensa_asm_trampoline_template (FILE *);
164 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
165 static bool xtensa_output_addr_const_extra (FILE *, rtx
);
166 static bool xtensa_cannot_force_const_mem (machine_mode
, rtx
);
168 static reg_class_t
xtensa_preferred_reload_class (rtx
, reg_class_t
);
169 static reg_class_t
xtensa_preferred_output_reload_class (rtx
, reg_class_t
);
170 static reg_class_t
xtensa_secondary_reload (bool, rtx
, reg_class_t
,
172 struct secondary_reload_info
*);
174 static bool constantpool_address_p (const_rtx addr
);
175 static bool xtensa_legitimate_constant_p (machine_mode
, rtx
);
176 static void xtensa_reorg (void);
177 static bool xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
179 static const char *xtensa_invalid_within_doloop (const rtx_insn
*);
181 static bool xtensa_member_type_forces_blk (const_tree
,
184 static void xtensa_conditional_register_usage (void);
185 static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode
);
186 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode
);
187 static bool xtensa_modes_tieable_p (machine_mode
, machine_mode
);
188 static HOST_WIDE_INT
xtensa_constant_alignment (const_tree
, HOST_WIDE_INT
);
189 static bool xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED
,
191 static HOST_WIDE_INT
xtensa_starting_frame_offset (void);
192 static unsigned HOST_WIDE_INT
xtensa_asan_shadow_offset (void);
193 static bool xtensa_function_ok_for_sibcall (tree
, tree
);
194 static rtx
xtensa_delegitimize_address (rtx
);
198 /* These hooks specify assembly directives for creating certain kinds
199 of integer object. */
201 #undef TARGET_ASM_ALIGNED_SI_OP
202 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
204 #undef TARGET_ASM_SELECT_RTX_SECTION
205 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
207 #undef TARGET_LEGITIMIZE_ADDRESS
208 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
209 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
210 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
212 #undef TARGET_REGISTER_MOVE_COST
213 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
214 #undef TARGET_MEMORY_MOVE_COST
215 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
216 #undef TARGET_RTX_COSTS
217 #define TARGET_RTX_COSTS xtensa_rtx_costs
218 #undef TARGET_INSN_COST
219 #define TARGET_INSN_COST xtensa_insn_cost
220 #undef TARGET_ADDRESS_COST
221 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
223 #undef TARGET_MEMBER_TYPE_FORCES_BLK
224 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
226 #undef TARGET_BUILD_BUILTIN_VA_LIST
227 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
229 #undef TARGET_EXPAND_BUILTIN_VA_START
230 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
232 #undef TARGET_PROMOTE_FUNCTION_MODE
233 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
234 #undef TARGET_PROMOTE_PROTOTYPES
235 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
237 #undef TARGET_RETURN_IN_MEMORY
238 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
239 #undef TARGET_FUNCTION_VALUE
240 #define TARGET_FUNCTION_VALUE xtensa_function_value
241 #undef TARGET_LIBCALL_VALUE
242 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
243 #undef TARGET_FUNCTION_VALUE_REGNO_P
244 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
246 #undef TARGET_SPLIT_COMPLEX_ARG
247 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
248 #undef TARGET_MUST_PASS_IN_STACK
249 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
250 #undef TARGET_FUNCTION_ARG_ADVANCE
251 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
252 #undef TARGET_FUNCTION_ARG
253 #define TARGET_FUNCTION_ARG xtensa_function_arg
254 #undef TARGET_FUNCTION_INCOMING_ARG
255 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
256 #undef TARGET_FUNCTION_ARG_BOUNDARY
257 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
259 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
260 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
261 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
262 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
264 #undef TARGET_RETURN_IN_MSB
265 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
267 #undef TARGET_INIT_BUILTINS
268 #define TARGET_INIT_BUILTINS xtensa_init_builtins
269 #undef TARGET_FOLD_BUILTIN
270 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
271 #undef TARGET_EXPAND_BUILTIN
272 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
274 #undef TARGET_PREFERRED_RELOAD_CLASS
275 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
276 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
277 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
279 #undef TARGET_SECONDARY_RELOAD
280 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
282 #undef TARGET_HAVE_TLS
283 #define TARGET_HAVE_TLS HAVE_AS_TLS
285 #undef TARGET_CANNOT_FORCE_CONST_MEM
286 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
289 #define TARGET_LRA_P hook_bool_void_false
291 #undef TARGET_LEGITIMATE_ADDRESS_P
292 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
294 #undef TARGET_FRAME_POINTER_REQUIRED
295 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
297 #undef TARGET_STATIC_CHAIN
298 #define TARGET_STATIC_CHAIN xtensa_static_chain
299 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
300 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
301 #undef TARGET_TRAMPOLINE_INIT
302 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
304 #undef TARGET_OPTION_OVERRIDE
305 #define TARGET_OPTION_OVERRIDE xtensa_option_override
307 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
308 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
310 #undef TARGET_LEGITIMATE_CONSTANT_P
311 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
313 #undef TARGET_MACHINE_DEPENDENT_REORG
314 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
316 #undef TARGET_CAN_USE_DOLOOP_P
317 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
319 #undef TARGET_INVALID_WITHIN_DOLOOP
320 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
322 #undef TARGET_CONDITIONAL_REGISTER_USAGE
323 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
325 #undef TARGET_HARD_REGNO_NREGS
326 #define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
327 #undef TARGET_HARD_REGNO_MODE_OK
328 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
330 #undef TARGET_MODES_TIEABLE_P
331 #define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p
333 #undef TARGET_CONSTANT_ALIGNMENT
334 #define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment
336 #undef TARGET_CAN_ELIMINATE
337 #define TARGET_CAN_ELIMINATE xtensa_can_eliminate
339 #undef TARGET_STARTING_FRAME_OFFSET
340 #define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset
342 #undef TARGET_ASAN_SHADOW_OFFSET
343 #define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset
345 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
346 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
348 #undef TARGET_DELEGITIMIZE_ADDRESS
349 #define TARGET_DELEGITIMIZE_ADDRESS xtensa_delegitimize_address
351 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
352 #define TARGET_FUNCTION_OK_FOR_SIBCALL xtensa_function_ok_for_sibcall
354 struct gcc_target targetm
= TARGET_INITIALIZER
;
357 /* Functions to test Xtensa immediate operand validity. */
360 xtensa_simm8 (HOST_WIDE_INT v
)
362 return IN_RANGE (v
, -128, 127);
367 xtensa_simm8x256 (HOST_WIDE_INT v
)
369 return (v
& 255) == 0 && IN_RANGE (v
, -32768, 32512);
374 xtensa_simm12b (HOST_WIDE_INT v
)
376 return IN_RANGE (v
, -2048, 2047);
381 xtensa_uimm8 (HOST_WIDE_INT v
)
383 return IN_RANGE (v
, 0, 255);
388 xtensa_uimm8x2 (HOST_WIDE_INT v
)
390 return (v
& 1) == 0 && IN_RANGE (v
, 0, 510);
395 xtensa_uimm8x4 (HOST_WIDE_INT v
)
397 return (v
& 3) == 0 && IN_RANGE (v
, 0, 1020);
402 xtensa_b4const (HOST_WIDE_INT v
)
429 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
433 return xtensa_b4const (v
);
438 xtensa_b4constu (HOST_WIDE_INT v
)
465 xtensa_mask_immediate (HOST_WIDE_INT v
)
467 return IN_RANGE (exact_log2 (v
+ 1), 1, 16);
471 /* This is just like the standard true_regnum() function except that it
472 works even when reg_renumber is not initialized. */
475 xt_true_regnum (rtx x
)
477 if (GET_CODE (x
) == REG
)
480 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
481 && reg_renumber
[REGNO (x
)] >= 0)
482 return reg_renumber
[REGNO (x
)];
485 if (GET_CODE (x
) == SUBREG
)
487 int base
= xt_true_regnum (SUBREG_REG (x
));
488 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
489 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
490 GET_MODE (SUBREG_REG (x
)),
491 SUBREG_BYTE (x
), GET_MODE (x
));
498 xtensa_valid_move (machine_mode mode
, rtx
*operands
)
500 /* Either the destination or source must be a register, and the
501 MAC16 accumulator doesn't count. */
503 if (register_operand (operands
[0], mode
))
505 int dst_regnum
= xt_true_regnum (operands
[0]);
507 if (xtensa_tls_referenced_p (operands
[1]))
510 /* The stack pointer can only be assigned with a MOVSP opcode. */
511 if (dst_regnum
== STACK_POINTER_REGNUM
)
512 return !TARGET_WINDOWED_ABI
514 && register_operand (operands
[1], mode
)
515 && !ACC_REG_P (xt_true_regnum (operands
[1])));
517 if (!ACC_REG_P (dst_regnum
))
520 if (register_operand (operands
[1], mode
))
522 int src_regnum
= xt_true_regnum (operands
[1]);
523 if (!ACC_REG_P (src_regnum
))
531 smalloffset_mem_p (rtx op
)
533 if (GET_CODE (op
) == MEM
)
535 rtx addr
= XEXP (op
, 0);
536 if (GET_CODE (addr
) == REG
)
537 return BASE_REG_P (addr
, 0);
538 if (GET_CODE (addr
) == PLUS
)
540 rtx offset
= XEXP (addr
, 0);
542 if (GET_CODE (offset
) != CONST_INT
)
543 offset
= XEXP (addr
, 1);
544 if (GET_CODE (offset
) != CONST_INT
)
547 val
= INTVAL (offset
);
548 return (val
& 3) == 0 && IN_RANGE (val
, 0, 60);
556 constantpool_address_p (const_rtx addr
)
558 const_rtx sym
= addr
;
560 if (GET_CODE (addr
) == CONST
)
564 /* Only handle (PLUS (SYM, OFFSET)) form. */
565 addr
= XEXP (addr
, 0);
566 if (GET_CODE (addr
) != PLUS
)
569 /* Make sure the address is word aligned. */
570 offset
= XEXP (addr
, 1);
571 if ((!CONST_INT_P (offset
))
572 || ((INTVAL (offset
) & 3) != 0))
575 sym
= XEXP (addr
, 0);
578 if ((GET_CODE (sym
) == SYMBOL_REF
)
579 && CONSTANT_POOL_ADDRESS_P (sym
))
586 constantpool_mem_p (rtx op
)
588 if (GET_CODE (op
) == SUBREG
)
589 op
= SUBREG_REG (op
);
590 if (GET_CODE (op
) == MEM
)
591 return constantpool_address_p (XEXP (op
, 0));
596 /* Return TRUE if X is a thread-local symbol. */
599 xtensa_tls_symbol_p (rtx x
)
601 if (! targetm
.have_tls
)
604 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
609 xtensa_extend_reg (rtx dst
, rtx src
)
611 rtx temp
= gen_reg_rtx (SImode
);
612 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
614 /* Generate paradoxical subregs as needed so that the modes match. */
615 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
616 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
618 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
619 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
624 xtensa_mem_offset (unsigned v
, machine_mode mode
)
629 /* Handle the worst case for block moves. See xtensa_expand_block_move
630 where we emit an optimized block move operation if the block can be
631 moved in < "move_ratio" pieces. The worst case is when the block is
632 aligned but has a size of (3 mod 4) (does this happen?) so that the
633 last piece requires a byte load/store. */
634 return (xtensa_uimm8 (v
)
635 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
638 return xtensa_uimm8 (v
);
641 return xtensa_uimm8x2 (v
);
645 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
651 return xtensa_uimm8x4 (v
);
655 /* Make normal rtx_code into something we can index from an array. */
657 static enum internal_test
658 map_test_to_internal_test (enum rtx_code test_code
)
660 enum internal_test test
= ITEST_MAX
;
665 case EQ
: test
= ITEST_EQ
; break;
666 case NE
: test
= ITEST_NE
; break;
667 case GT
: test
= ITEST_GT
; break;
668 case GE
: test
= ITEST_GE
; break;
669 case LT
: test
= ITEST_LT
; break;
670 case LE
: test
= ITEST_LE
; break;
671 case GTU
: test
= ITEST_GTU
; break;
672 case GEU
: test
= ITEST_GEU
; break;
673 case LTU
: test
= ITEST_LTU
; break;
674 case LEU
: test
= ITEST_LEU
; break;
681 /* Generate the code to compare two integer values. The return value is
682 the comparison expression. */
685 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
686 rtx cmp0
, /* first operand to compare */
687 rtx cmp1
/* second operand to compare */)
691 enum rtx_code test_code
; /* test code to use in insn */
692 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
693 int const_add
; /* constant to add (convert LE -> LT) */
694 int reverse_regs
; /* reverse registers in test */
695 int invert_const
; /* != 0 if invert value if cmp1 is constant */
696 int invert_reg
; /* != 0 if invert value if cmp1 is register */
697 int unsignedp
; /* != 0 for unsigned comparisons. */
700 static struct cmp_info info
[ (int)ITEST_MAX
] = {
702 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
703 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
705 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
706 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
707 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
708 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
710 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
711 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
712 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
713 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
716 enum internal_test test
;
718 struct cmp_info
*p_info
;
721 test
= map_test_to_internal_test (test_code
);
722 gcc_assert (test
!= ITEST_MAX
);
724 p_info
= &info
[ (int)test
];
726 mode
= GET_MODE (cmp0
);
727 if (mode
== VOIDmode
)
728 mode
= GET_MODE (cmp1
);
730 /* Make sure we can handle any constants given to us. */
731 if (GET_CODE (cmp1
) == CONST_INT
)
733 HOST_WIDE_INT value
= INTVAL (cmp1
);
734 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
736 /* if the immediate overflows or does not fit in the immediate field,
737 spill it to a register */
739 if ((p_info
->unsignedp
?
740 (uvalue
+ p_info
->const_add
> uvalue
) :
741 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
743 cmp1
= force_reg (mode
, cmp1
);
745 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
747 cmp1
= force_reg (mode
, cmp1
);
750 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
752 cmp1
= force_reg (mode
, cmp1
);
755 /* See if we need to invert the result. */
756 invert
= (CONST_INT_P (cmp1
)
757 ? p_info
->invert_const
758 : p_info
->invert_reg
);
760 /* Comparison to constants, may involve adding 1 to change a LT into LE.
761 Comparison between two registers, may involve switching operands. */
762 if (GET_CODE (cmp1
) == CONST_INT
)
764 if (p_info
->const_add
!= 0)
765 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
768 else if (p_info
->reverse_regs
)
775 return gen_rtx_fmt_ee (invert
? reverse_condition (p_info
->test_code
)
777 VOIDmode
, cmp0
, cmp1
);
781 /* Generate the code to compare two float values. The return value is
782 the comparison expression. */
785 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
786 rtx cmp0
, /* first operand to compare */
787 rtx cmp1
/* second operand to compare */)
789 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
791 int reverse_regs
, invert
;
795 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
796 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
797 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
798 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
799 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
800 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
801 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
802 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
803 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
804 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
805 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
806 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
808 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
810 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
812 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
813 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
823 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
824 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
826 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
831 xtensa_expand_conditional_branch (rtx
*operands
, machine_mode mode
)
833 enum rtx_code test_code
= GET_CODE (operands
[0]);
834 rtx cmp0
= operands
[1];
835 rtx cmp1
= operands
[2];
841 if (TARGET_HARD_FLOAT
)
843 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
850 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
853 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
);
857 /* Generate the branch. */
858 label
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
859 emit_jump_insn (gen_rtx_SET (pc_rtx
,
860 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
867 gen_conditional_move (enum rtx_code code
, machine_mode mode
,
874 /* Jump optimization calls get_condition() which canonicalizes
875 comparisons like (GE x <const>) to (GT x <const-1>).
876 Transform those comparisons back to GE, since that is the
877 comparison supported in Xtensa. We shouldn't have to
878 transform <LE x const> comparisons, because neither
879 xtensa_expand_conditional_branch() nor get_condition() will
882 if ((code
== GT
) && (op1
== constm1_rtx
))
887 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, pc_rtx
, const0_rtx
);
889 if (boolean_operator (cmp
, VOIDmode
))
891 /* Swap the operands to make const0 second. */
892 if (op0
== const0_rtx
)
898 /* If not comparing against zero, emit a comparison (subtract). */
899 if (op1
!= const0_rtx
)
901 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
902 0, 0, OPTAB_LIB_WIDEN
);
906 else if (branch_operator (cmp
, VOIDmode
))
908 /* Swap the operands to make const0 second. */
909 if (op0
== const0_rtx
)
916 case LT
: code
= GE
; break;
917 case GE
: code
= LT
; break;
918 default: gcc_unreachable ();
922 if (op1
!= const0_rtx
)
928 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
931 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
932 return gen_float_relational (code
, op0
, op1
);
939 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
941 rtx dest
= operands
[0];
942 rtx cmp
= operands
[1];
943 machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
944 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
946 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
947 XEXP (cmp
, 0), XEXP (cmp
, 1))))
951 gen_fn
= (cmp_mode
== SImode
952 ? gen_movsfcc_internal0
953 : gen_movsfcc_internal1
);
955 gen_fn
= (cmp_mode
== SImode
956 ? gen_movsicc_internal0
957 : gen_movsicc_internal1
);
959 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
965 xtensa_expand_scc (rtx operands
[4], machine_mode cmp_mode
)
967 rtx dest
= operands
[0];
969 rtx one_tmp
, zero_tmp
;
970 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
972 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
973 operands
[2], operands
[3])))
976 one_tmp
= gen_reg_rtx (SImode
);
977 zero_tmp
= gen_reg_rtx (SImode
);
978 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
979 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
981 gen_fn
= (cmp_mode
== SImode
982 ? gen_movsicc_internal0
983 : gen_movsicc_internal1
);
984 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
989 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
990 for the output, i.e., the input operands are twice as big as MODE. */
993 xtensa_split_operand_pair (rtx operands
[4], machine_mode mode
)
995 switch (GET_CODE (operands
[1]))
998 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
999 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
1003 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
1004 operands
[2] = adjust_address (operands
[1], mode
, 0);
1009 split_double (operands
[1], &operands
[2], &operands
[3]);
1016 switch (GET_CODE (operands
[0]))
1019 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
1020 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
1024 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
1025 operands
[0] = adjust_address (operands
[0], mode
, 0);
1034 /* Try to emit insns to load srcval (that cannot fit into signed 12-bit)
1035 into dst with synthesizing a such constant value from a sequence of
1036 load-immediate / arithmetic ones, instead of a L32R instruction
1037 (plus a constant in litpool). */
1040 xtensa_constantsynth_2insn (rtx dst
, HOST_WIDE_INT srcval
,
1041 rtx (*gen_op
)(rtx
, HOST_WIDE_INT
),
1042 HOST_WIDE_INT op_imm
)
1044 HOST_WIDE_INT imm
= INT_MAX
;
1048 gcc_assert (REG_P (dst
));
1050 shift
= exact_log2 (srcval
+ 1);
1051 if (IN_RANGE (shift
, 1, 31))
1054 x
= gen_lshrsi3 (dst
, dst
, GEN_INT (32 - shift
));
1058 shift
= ctz_hwi (srcval
);
1059 if ((!x
|| (TARGET_DENSITY
&& ! IN_RANGE (imm
, -32, 95)))
1060 && xtensa_simm12b (srcval
>> shift
))
1062 imm
= srcval
>> shift
;
1063 x
= gen_ashlsi3 (dst
, dst
, GEN_INT (shift
));
1066 if ((!x
|| (TARGET_DENSITY
&& ! IN_RANGE (imm
, -32, 95)))
1067 && IN_RANGE (srcval
, (-2048 - 32768), (2047 + 32512)))
1069 HOST_WIDE_INT imm0
, imm1
;
1071 if (srcval
< -32768)
1073 else if (srcval
> 32512)
1076 imm1
= srcval
& ~255;
1077 imm0
= srcval
- imm1
;
1078 if (TARGET_DENSITY
&& imm1
< 32512 && IN_RANGE (imm0
, 224, 255))
1079 imm0
-= 256, imm1
+= 256;
1081 x
= gen_addsi3 (dst
, dst
, GEN_INT (imm1
));
1087 emit_move_insn (dst
, GEN_INT (imm
));
1090 emit_move_insn (dst
, gen_op (dst
, op_imm
));
1096 xtensa_constantsynth_rtx_SLLI (rtx reg
, HOST_WIDE_INT imm
)
1098 return gen_rtx_ASHIFT (SImode
, reg
, GEN_INT (imm
));
1102 xtensa_constantsynth_rtx_ADDSUBX (rtx reg
, HOST_WIDE_INT imm
)
1105 ? gen_rtx_MINUS (SImode
, gen_rtx_ASHIFT (SImode
, reg
, GEN_INT (3)),
1107 : gen_rtx_PLUS (SImode
, gen_rtx_ASHIFT (SImode
, reg
,
1108 GEN_INT (floor_log2 (imm
- 1))),
1113 xtensa_constantsynth (rtx dst
, HOST_WIDE_INT srcval
)
1115 /* No need for synthesizing for what fits into MOVI instruction. */
1116 if (xtensa_simm12b (srcval
))
1119 /* 2-insns substitution. */
1120 if ((optimize_size
|| (optimize
&& xtensa_extra_l32r_costs
>= 1))
1121 && xtensa_constantsynth_2insn (dst
, srcval
, NULL
, 0))
1124 /* 3-insns substitution. */
1125 if (optimize
> 1 && !optimize_size
&& xtensa_extra_l32r_costs
>= 2)
1129 /* 2-insns substitution followed by SLLI. */
1130 shift
= ctz_hwi (srcval
);
1131 if (IN_RANGE (shift
, 1, 31) &&
1132 xtensa_constantsynth_2insn (dst
, srcval
>> shift
,
1133 xtensa_constantsynth_rtx_SLLI
,
1137 /* 2-insns substitution followed by ADDX[248] or SUBX8. */
1139 for (divisor
= 3; divisor
<= 9; divisor
+= 2)
1140 if (srcval
% divisor
== 0 &&
1141 xtensa_constantsynth_2insn (dst
, srcval
/ divisor
,
1142 xtensa_constantsynth_rtx_ADDSUBX
,
1146 /* loading simm12 followed by left/right bitwise rotation:
1147 MOVI + SSAI + SRC. */
1148 if ((srcval
& 0x001FF800) == 0
1149 || (srcval
& 0x001FF800) == 0x001FF800)
1153 for (shift
= 1; shift
< 12; ++shift
)
1155 v
= (int32_t)(((uint32_t)srcval
>> shift
)
1156 | ((uint32_t)srcval
<< (32 - shift
)));
1157 if (xtensa_simm12b(v
))
1159 emit_move_insn (dst
, GEN_INT (v
));
1160 emit_insn (gen_rotlsi3 (dst
, dst
, GEN_INT (shift
)));
1164 for (shift
= 1; shift
< 12; ++shift
)
1166 v
= (int32_t)(((uint32_t)srcval
<< shift
)
1167 | ((uint32_t)srcval
>> (32 - shift
)));
1168 if (xtensa_simm12b(v
))
1170 emit_move_insn (dst
, GEN_INT (v
));
1171 emit_insn (gen_rotrsi3 (dst
, dst
, GEN_INT (shift
)));
1182 /* Emit insns to move operands[1] into operands[0].
1183 Return 1 if we have written out everything that needs to be done to
1184 do the move. Otherwise, return 0 and the caller will emit the move
1188 xtensa_emit_move_sequence (rtx
*operands
, machine_mode mode
)
1190 rtx src
= operands
[1];
1192 if (CONSTANT_P (src
)
1193 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
1195 rtx dst
= operands
[0];
1197 if (xtensa_tls_referenced_p (src
))
1201 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
1203 addend
= XEXP (XEXP (src
, 0), 1);
1204 src
= XEXP (XEXP (src
, 0), 0);
1207 src
= xtensa_legitimize_tls_address (src
);
1210 src
= gen_rtx_PLUS (mode
, src
, addend
);
1211 src
= force_operand (src
, dst
);
1213 emit_move_insn (dst
, src
);
1217 if (! TARGET_AUTO_LITPOOLS
&& ! TARGET_CONST16
1218 && ! (CONST_INT_P (src
) && can_create_pseudo_p ()))
1220 src
= force_const_mem (SImode
, src
);
1224 /* PC-relative loads are always SImode, and CONST16 is only
1225 supported in the movsi pattern, so add a SUBREG for any other
1230 if (register_operand (dst
, mode
))
1232 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
1237 src
= force_reg (SImode
, src
);
1238 src
= gen_lowpart_SUBREG (mode
, src
);
1244 if (can_create_pseudo_p ()
1245 && !xtensa_valid_move (mode
, operands
))
1246 operands
[1] = force_reg (mode
, operands
[1]);
1248 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1250 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1251 instruction won't be recognized after reload, so we remove the
1252 subreg and adjust mem accordingly. */
1253 if (reload_in_progress
)
1255 operands
[0] = fixup_subreg_mem (operands
[0]);
1256 operands
[1] = fixup_subreg_mem (operands
[1]);
1263 fixup_subreg_mem (rtx x
)
1265 if (GET_CODE (x
) == SUBREG
1266 && GET_CODE (SUBREG_REG (x
)) == REG
1267 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1270 gen_rtx_SUBREG (GET_MODE (x
),
1271 reg_equiv_mem (REGNO (SUBREG_REG (x
))),
1273 x
= alter_subreg (&temp
, true);
1279 /* Check if an incoming argument in a7 is expected to be used soon and
1280 if OPND is a register or register pair that includes a7. If so,
1281 create a new pseudo and copy a7 into that pseudo at the very
1282 beginning of the function, followed by the special "set_frame_ptr"
1283 unspec_volatile insn. The return value is either the original
1284 operand, if it is not a7, or the new pseudo containing a copy of
1285 the incoming argument. This is necessary because the register
1286 allocator will ignore conflicts with a7 and may either assign some
1287 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1288 the incoming argument in a7. By copying the argument out of a7 as
1289 the very first thing, and then immediately following that with an
1290 unspec_volatile to keep the scheduler away, we should avoid any
1291 problems. Putting the set_frame_ptr insn at the beginning, with
1292 only the a7 copy before it, also makes it easier for the prologue
1293 expander to initialize the frame pointer after the a7 copy and to
1294 fix up the a7 copy to use the stack pointer instead of the frame
1298 xtensa_copy_incoming_a7 (rtx opnd
)
1300 rtx entry_insns
= 0;
1304 if (!cfun
->machine
->need_a7_copy
)
1307 /* This function should never be called again once a7 has been copied. */
1308 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1310 mode
= GET_MODE (opnd
);
1312 /* The operand using a7 may come in a later instruction, so just return
1313 the original operand if it doesn't use a7. */
1315 if (GET_CODE (reg
) == SUBREG
)
1317 gcc_assert (SUBREG_BYTE (reg
) == 0);
1318 reg
= SUBREG_REG (reg
);
1320 if (GET_CODE (reg
) != REG
1321 || REGNO (reg
) > A7_REG
1322 || REGNO (reg
) + hard_regno_nregs (A7_REG
, mode
) <= A7_REG
)
1325 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1326 gcc_assert (REGNO (reg
) + hard_regno_nregs (A7_REG
, mode
) - 1 == A7_REG
);
1328 cfun
->machine
->need_a7_copy
= false;
1330 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1331 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1334 tmp
= gen_reg_rtx (mode
);
1340 /* Copy the value out of A7 here but keep the first word in A6 until
1341 after the set_frame_ptr insn. Otherwise, the register allocator
1342 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1344 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1345 gen_raw_REG (SImode
, A7_REG
)));
1348 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1351 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1354 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1357 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1363 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1365 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1366 if (mode
== DFmode
|| mode
== DImode
)
1367 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1368 gen_rtx_REG (SImode
, A7_REG
- 1)));
1369 entry_insns
= get_insns ();
1372 if (cfun
->machine
->vararg_a7
)
1374 /* This is called from within builtin_saveregs, which will insert the
1375 saveregs code at the function entry, ahead of anything placed at
1376 the function entry now. Instead, save the sequence to be inserted
1377 at the beginning of the saveregs code. */
1378 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1382 /* Put entry_insns after the NOTE that starts the function. If
1383 this is inside a start_sequence, make the outer-level insn
1384 chain current, so the code is placed at the start of the
1386 push_topmost_sequence ();
1387 /* Do not use entry_of_function() here. This is called from within
1388 expand_function_start, when the CFG still holds GIMPLE. */
1389 emit_insn_after (entry_insns
, get_insns ());
1390 pop_topmost_sequence ();
1397 /* Try to expand a block move operation to a sequence of RTL move
1398 instructions. If not optimizing, or if the block size is not a
1399 constant, or if the block is too large, the expansion fails and GCC
1400 falls back to calling memcpy().
1402 operands[0] is the destination
1403 operands[1] is the source
1404 operands[2] is the length
1405 operands[3] is the alignment */
1408 xtensa_expand_block_move (rtx
*operands
)
1410 static const machine_mode mode_from_align
[] =
1412 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1415 rtx dst_mem
= operands
[0];
1416 rtx src_mem
= operands
[1];
1417 HOST_WIDE_INT bytes
, align
;
1418 int num_pieces
, move_ratio
;
1420 machine_mode mode
[2];
1429 /* If this is not a fixed size move, just call memcpy. */
1430 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1433 bytes
= INTVAL (operands
[2]);
1434 align
= INTVAL (operands
[3]);
1436 /* Anything to move? */
1440 if (align
> MOVE_MAX
)
1443 /* Decide whether to expand inline based on the optimization level. */
1446 move_ratio
= LARGEST_MOVE_RATIO
;
1447 num_pieces
= (bytes
/ align
) + ((bytes
% align
+ 1) / 2);
1448 if (num_pieces
> move_ratio
)
1451 x
= XEXP (dst_mem
, 0);
1454 x
= force_reg (Pmode
, x
);
1455 dst_mem
= replace_equiv_address (dst_mem
, x
);
1458 x
= XEXP (src_mem
, 0);
1461 x
= force_reg (Pmode
, x
);
1462 src_mem
= replace_equiv_address (src_mem
, x
);
1465 active
[0] = active
[1] = false;
1476 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1477 next_amount
= MIN (next_amount
, align
);
1479 amount
[next
] = next_amount
;
1480 mode
[next
] = mode_from_align
[next_amount
];
1481 temp
[next
] = gen_reg_rtx (mode
[next
]);
1483 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1484 emit_move_insn (temp
[next
], x
);
1486 offset_ld
+= next_amount
;
1487 bytes
-= next_amount
;
1488 active
[next
] = true;
1493 active
[phase
] = false;
1495 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1496 emit_move_insn (x
, temp
[phase
]);
1498 offset_st
+= amount
[phase
];
1501 while (active
[next
]);
1507 /* Try to expand a block set operation to a sequence of RTL move
1508 instructions. If not optimizing, or if the block size is not a
1509 constant, or if the block is too large, or if the value to
1510 initialize the block with is not a constant, the expansion
1511 fails and GCC falls back to calling memset().
1513 operands[0] is the destination
1514 operands[1] is the length
1515 operands[2] is the initialization value
1516 operands[3] is the alignment */
1519 xtensa_sizeof_MOVI (HOST_WIDE_INT imm
)
1521 return (TARGET_DENSITY
&& IN_RANGE (imm
, -32, 95)) ? 2 : 3;
1525 xtensa_expand_block_set_unrolled_loop (rtx
*operands
)
1527 rtx dst_mem
= operands
[0];
1528 HOST_WIDE_INT bytes
, value
, align
;
1529 int expand_len
, funccall_len
;
1533 if (!CONST_INT_P (operands
[1]) || !CONST_INT_P (operands
[2]))
1536 bytes
= INTVAL (operands
[1]);
1539 value
= (int8_t)INTVAL (operands
[2]);
1540 align
= INTVAL (operands
[3]);
1541 if (align
> MOVE_MAX
)
1544 /* Insn expansion: holding the init value.
1545 Either MOV(.N) or L32R w/litpool. */
1547 expand_len
= xtensa_sizeof_MOVI (value
);
1548 else if (value
== 0 || value
== -1)
1549 expand_len
= TARGET_DENSITY
? 2 : 3;
1552 /* Insn expansion: a series of aligned memory stores.
1553 Consist of S8I, S16I or S32I(.N). */
1554 expand_len
+= (bytes
/ align
) * (TARGET_DENSITY
1555 && align
== 4 ? 2 : 3);
1556 /* Insn expansion: the remainder, sub-aligned memory stores.
1557 A combination of S8I and S16I as needed. */
1558 expand_len
+= ((bytes
% align
+ 1) / 2) * 3;
1560 /* Function call: preparing two arguments. */
1561 funccall_len
= xtensa_sizeof_MOVI (value
);
1562 funccall_len
+= xtensa_sizeof_MOVI (bytes
);
1563 /* Function call: calling memset(). */
1564 funccall_len
+= TARGET_LONGCALLS
? (3 + 4 + 3) : 3;
1566 /* Apply expansion bonus (2x) if optimizing for speed. */
1567 if (optimize
> 1 && !optimize_size
)
1570 /* Decide whether to expand or not, based on the sum of the length
1572 if (expand_len
> funccall_len
)
1575 x
= XEXP (dst_mem
, 0);
1577 dst_mem
= replace_equiv_address (dst_mem
, force_reg (Pmode
, x
));
1583 value
= (int16_t)((uint8_t)value
* 0x0101U
);
1586 value
= (int32_t)((uint8_t)value
* 0x01010101U
);
1591 reg
= force_reg (SImode
, GEN_INT (value
));
1596 int unit_size
= MIN (bytes
, align
);
1597 machine_mode unit_mode
= (unit_size
>= 4 ? SImode
:
1598 (unit_size
>= 2 ? HImode
:
1600 unit_size
= GET_MODE_SIZE (unit_mode
);
1602 emit_move_insn (adjust_address (dst_mem
, unit_mode
, offset
),
1603 unit_mode
== SImode
? reg
1604 : convert_to_mode (unit_mode
, reg
, true));
1606 offset
+= unit_size
;
1615 xtensa_expand_block_set_small_loop (rtx
*operands
)
1617 HOST_WIDE_INT bytes
, value
, align
, count
;
1618 int expand_len
, funccall_len
;
1619 rtx x
, dst
, end
, reg
;
1620 machine_mode unit_mode
;
1621 rtx_code_label
*label
;
1623 if (!CONST_INT_P (operands
[1]) || !CONST_INT_P (operands
[2]))
1626 bytes
= INTVAL (operands
[1]);
1629 value
= (int8_t)INTVAL (operands
[2]);
1630 align
= INTVAL (operands
[3]);
1631 if (align
> MOVE_MAX
)
1634 /* Totally-aligned block only. */
1635 if (bytes
% align
!= 0)
1637 count
= bytes
/ align
;
1639 /* If the Loop Option (zero-overhead looping) is configured and active,
1640 almost no restrictions about the length of the block. */
1641 if (! (TARGET_LOOPS
&& optimize
))
1643 /* If 4-byte aligned, small loop substitution is almost optimal,
1644 thus limited to only offset to the end address for ADDI/ADDMI
1647 && ! (bytes
<= 127 || xtensa_simm8x256 (bytes
)))
1650 /* If no 4-byte aligned, loop count should be treated as the
1653 && count
> ((optimize
> 1 && !optimize_size
) ? 8 : 15))
1657 /* Insn expansion: holding the init value.
1658 Either MOV(.N) or L32R w/litpool. */
1660 expand_len
= xtensa_sizeof_MOVI (value
);
1661 else if (value
== 0 || value
== -1)
1662 expand_len
= TARGET_DENSITY
? 2 : 3;
1665 if (TARGET_LOOPS
&& optimize
) /* zero-overhead looping */
1667 /* Insn translation: Either MOV(.N) or L32R w/litpool for the
1669 expand_len
+= xtensa_simm12b (count
) ? xtensa_sizeof_MOVI (count
)
1671 /* Insn translation: LOOP, the zero-overhead looping setup
1674 /* Insn expansion: the loop body instructions.
1675 For store, one of S8I, S16I or S32I(.N).
1676 For advance, ADDI(.N). */
1677 expand_len
+= (TARGET_DENSITY
&& align
== 4 ? 2 : 3)
1678 + (TARGET_DENSITY
? 2 : 3);
1680 else /* NO zero-overhead looping */
1682 /* Insn expansion: Either ADDI(.N) or ADDMI for the end address. */
1683 expand_len
+= bytes
> 127 ? 3
1684 : (TARGET_DENSITY
&& bytes
<= 15) ? 2 : 3;
1685 /* Insn expansion: the loop body and branch instruction.
1686 For store, one of S8I, S16I or S32I(.N).
1687 For advance, ADDI(.N).
1689 expand_len
+= (TARGET_DENSITY
&& align
== 4 ? 2 : 3)
1690 + (TARGET_DENSITY
? 2 : 3) + 3;
1693 /* Function call: preparing two arguments. */
1694 funccall_len
= xtensa_sizeof_MOVI (value
);
1695 funccall_len
+= xtensa_sizeof_MOVI (bytes
);
1696 /* Function call: calling memset(). */
1697 funccall_len
+= TARGET_LONGCALLS
? (3 + 4 + 3) : 3;
1699 /* Apply expansion bonus (2x) if optimizing for speed. */
1700 if (optimize
> 1 && !optimize_size
)
1703 /* Decide whether to expand or not, based on the sum of the length
1705 if (expand_len
> funccall_len
)
1708 x
= XEXP (operands
[0], 0);
1710 x
= XEXP (replace_equiv_address (operands
[0], force_reg (Pmode
, x
)), 0);
1711 dst
= gen_reg_rtx (SImode
);
1712 emit_move_insn (dst
, x
);
1713 end
= gen_reg_rtx (SImode
);
1714 if (TARGET_LOOPS
&& optimize
)
1715 x
= force_reg (SImode
, operands
[1] /* the length */);
1718 emit_insn (gen_addsi3 (end
, dst
, x
));
1725 value
= (int16_t)((uint8_t)value
* 0x0101U
);
1729 value
= (int32_t)((uint8_t)value
* 0x01010101U
);
1735 reg
= force_reg (unit_mode
, GEN_INT (value
));
1737 label
= gen_label_rtx ();
1739 emit_move_insn (gen_rtx_MEM (unit_mode
, dst
), reg
);
1740 emit_insn (gen_addsi3 (dst
, dst
, GEN_INT (align
)));
1741 emit_cmp_and_jump_insns (dst
, end
, NE
, const0_rtx
, SImode
, true, label
);
1748 xtensa_expand_nonlocal_goto (rtx
*operands
)
1750 rtx goto_handler
= operands
[1];
1751 rtx containing_fp
= operands
[3];
1753 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1754 is too big to generate in-line. */
1756 if (GET_CODE (containing_fp
) != REG
)
1757 containing_fp
= force_reg (Pmode
, containing_fp
);
1759 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1760 LCT_NORMAL
, VOIDmode
,
1761 containing_fp
, Pmode
,
1762 goto_handler
, Pmode
);
1766 static struct machine_function
*
1767 xtensa_init_machine_status (void)
1769 return ggc_cleared_alloc
<machine_function
> ();
1773 /* Shift VAL of mode MODE left by COUNT bits. */
1776 xtensa_expand_mask_and_shift (rtx val
, machine_mode mode
, rtx count
)
1778 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1779 NULL_RTX
, 1, OPTAB_DIRECT
);
1780 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1781 NULL_RTX
, 1, OPTAB_DIRECT
);
1785 /* Structure to hold the initial parameters for a compare_and_swap operation
1786 in HImode and QImode. */
1788 struct alignment_context
1790 rtx memsi
; /* SI aligned memory location. */
1791 rtx shift
; /* Bit offset with regard to lsb. */
1792 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1793 rtx modemaski
; /* ~modemask */
1797 /* Initialize structure AC for word access to HI and QI mode memory. */
1800 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1802 machine_mode mode
= GET_MODE (mem
);
1803 rtx byteoffset
= NULL_RTX
;
1804 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1807 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1810 /* Alignment is unknown. */
1813 /* Force the address into a register. */
1814 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1816 /* Align it to SImode. */
1817 align
= expand_simple_binop (Pmode
, AND
, addr
,
1818 GEN_INT (-GET_MODE_SIZE (SImode
)),
1819 NULL_RTX
, 1, OPTAB_DIRECT
);
1821 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1822 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1823 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1824 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1826 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1827 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1828 NULL_RTX
, 1, OPTAB_DIRECT
);
1831 /* Calculate shiftcount. */
1832 if (TARGET_BIG_ENDIAN
)
1834 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1836 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1837 NULL_RTX
, 1, OPTAB_DIRECT
);
1842 ac
->shift
= NULL_RTX
;
1844 ac
->shift
= byteoffset
;
1847 if (ac
->shift
!= NULL_RTX
)
1849 /* Shift is the byte count, but we need the bitcount. */
1850 gcc_assert (exact_log2 (BITS_PER_UNIT
) >= 0);
1851 ac
->shift
= expand_simple_binop (SImode
, ASHIFT
, ac
->shift
,
1852 GEN_INT (exact_log2 (BITS_PER_UNIT
)),
1853 NULL_RTX
, 1, OPTAB_DIRECT
);
1854 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1855 GEN_INT (GET_MODE_MASK (mode
)),
1857 NULL_RTX
, 1, OPTAB_DIRECT
);
1860 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1862 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1866 /* Expand an atomic compare and swap operation for HImode and QImode.
1867 MEM is the memory location, CMP the old value to compare MEM with
1868 and NEW_RTX the value to set if CMP == MEM. */
1871 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1873 machine_mode mode
= GET_MODE (mem
);
1874 struct alignment_context ac
;
1875 rtx tmp
, cmpv
, newv
, val
;
1876 rtx oldval
= gen_reg_rtx (SImode
);
1877 rtx res
= gen_reg_rtx (SImode
);
1878 rtx_code_label
*csloop
= gen_label_rtx ();
1879 rtx_code_label
*csend
= gen_label_rtx ();
1881 init_alignment_context (&ac
, mem
);
1883 if (ac
.shift
!= NULL_RTX
)
1885 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1886 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1889 /* Load the surrounding word into VAL with the MEM value masked out. */
1890 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1891 ac
.modemaski
, NULL_RTX
, 1,
1893 emit_label (csloop
);
1895 /* Patch CMP and NEW_RTX into VAL at correct position. */
1896 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1897 NULL_RTX
, 1, OPTAB_DIRECT
));
1898 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1899 NULL_RTX
, 1, OPTAB_DIRECT
));
1901 /* Jump to end if we're done. */
1902 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1903 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1905 /* Check for changes outside mode. */
1906 emit_move_insn (oldval
, val
);
1907 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1908 val
, 1, OPTAB_DIRECT
);
1910 emit_move_insn (val
, tmp
);
1912 /* Loop internal if so. */
1913 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1917 /* Return the correct part of the bitfield. */
1918 convert_move (target
,
1919 (ac
.shift
== NULL_RTX
? res
1920 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1921 NULL_RTX
, 1, OPTAB_DIRECT
)),
1926 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1927 the default expansion works fine for SImode). MEM is the memory location
1928 and VAL the value to play with. If AFTER is true then store the value
1929 MEM holds after the operation, if AFTER is false then store the value MEM
1930 holds before the operation. If TARGET is zero then discard that value, else
1931 store it to TARGET. */
1934 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1937 machine_mode mode
= GET_MODE (mem
);
1938 struct alignment_context ac
;
1939 rtx_code_label
*csloop
= gen_label_rtx ();
1941 rtx old
= gen_reg_rtx (SImode
);
1942 rtx new_rtx
= gen_reg_rtx (SImode
);
1943 rtx orig
= NULL_RTX
;
1945 init_alignment_context (&ac
, mem
);
1947 /* Prepare values before the compare-and-swap loop. */
1948 if (ac
.shift
!= NULL_RTX
)
1949 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1954 orig
= gen_reg_rtx (SImode
);
1955 convert_move (orig
, val
, 1);
1963 case MULT
: /* NAND */
1965 /* val = "11..1<val>11..1" */
1966 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1967 NULL_RTX
, 1, OPTAB_DIRECT
);
1974 /* Load full word. Subsequent loads are performed by S32C1I. */
1975 cmp
= force_reg (SImode
, ac
.memsi
);
1977 emit_label (csloop
);
1978 emit_move_insn (old
, cmp
);
1984 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1985 NULL_RTX
, 1, OPTAB_DIRECT
);
1986 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1987 NULL_RTX
, 1, OPTAB_DIRECT
);
1990 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1991 NULL_RTX
, 1, OPTAB_DIRECT
);
1992 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1993 new_rtx
, 1, OPTAB_DIRECT
);
1999 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
2000 new_rtx
, 1, OPTAB_DIRECT
);
2003 case MULT
: /* NAND */
2004 tmp
= expand_simple_binop (SImode
, AND
, old
, val
,
2005 NULL_RTX
, 1, OPTAB_DIRECT
);
2006 tmp
= expand_simple_binop (SImode
, XOR
, tmp
, ac
.modemask
,
2007 new_rtx
, 1, OPTAB_DIRECT
);
2015 emit_move_insn (new_rtx
, tmp
);
2016 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
2017 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
2021 tmp
= (after
? new_rtx
: cmp
);
2022 convert_move (target
,
2023 (ac
.shift
== NULL_RTX
? tmp
2024 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
2025 NULL_RTX
, 1, OPTAB_DIRECT
)),
2032 xtensa_setup_frame_addresses (void)
2034 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
2035 cfun
->machine
->accesses_prev_frame
= 1;
2037 if (TARGET_WINDOWED_ABI
)
2039 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
2040 LCT_NORMAL
, VOIDmode
);
2044 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
2045 a comment showing where the end of the loop is. However, if there is a
2046 label or a branch at the end of the loop then we need to place a nop
2047 there. If the loop ends with a label we need the nop so that branches
2048 targeting that label will target the nop (and thus remain in the loop),
2049 instead of targeting the instruction after the loop (and thus exiting
2050 the loop). If the loop ends with a branch, we need the nop in case the
2051 branch is targeting a location inside the loop. When the branch
2052 executes it will cause the loop count to be decremented even if it is
2053 taken (because it is the last instruction in the loop), so we need to
2054 nop after the branch to prevent the loop count from being decremented
2055 when the branch is taken. */
2058 xtensa_emit_loop_end (rtx_insn
*insn
, rtx
*operands
)
2062 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
2064 switch (GET_CODE (insn
))
2071 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
2077 rtx body
= PATTERN (insn
);
2081 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
2084 else if ((GET_CODE (body
) != USE
)
2085 && (GET_CODE (body
) != CLOBBER
))
2092 output_asm_insn ("%1_LEND:", operands
);
2097 xtensa_emit_branch (bool immed
, rtx
*operands
)
2099 static char result
[64];
2100 enum rtx_code code
= GET_CODE (operands
[3]);
2105 case EQ
: op
= "eq"; break;
2106 case NE
: op
= "ne"; break;
2107 case LT
: op
= "lt"; break;
2108 case GE
: op
= "ge"; break;
2109 case LTU
: op
= "ltu"; break;
2110 case GEU
: op
= "geu"; break;
2111 default: gcc_unreachable ();
2116 if (INTVAL (operands
[1]) == 0)
2117 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
2118 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
2120 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
2123 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
2130 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
2132 static char result
[64];
2136 code
= GET_CODE (operands
[4]);
2138 code
= reverse_condition (code
);
2143 case EQ
: op
= "f"; break;
2144 case NE
: op
= "t"; break;
2145 default: gcc_unreachable ();
2152 case EQ
: op
= "eqz"; break;
2153 case NE
: op
= "nez"; break;
2154 case LT
: op
= "ltz"; break;
2155 case GE
: op
= "gez"; break;
2156 default: gcc_unreachable ();
2160 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
2161 op
, isfp
? ".s" : "", inverted
? 3 : 2);
2167 xtensa_prepare_expand_call (int callop
, rtx
*operands
)
2169 rtx addr
= XEXP (operands
[callop
], 0);
2171 if (flag_pic
&& SYMBOL_REF_P (addr
)
2172 && (!SYMBOL_REF_LOCAL_P (addr
) || SYMBOL_REF_EXTERNAL_P (addr
)))
2173 addr
= gen_sym_PLT (addr
);
2175 if (!call_insn_operand (addr
, VOIDmode
))
2176 XEXP (operands
[callop
], 0) = copy_to_mode_reg (Pmode
, addr
);
2181 xtensa_emit_call (int callop
, rtx
*operands
)
2183 static char result
[64];
2184 rtx tgt
= operands
[callop
];
2186 if (GET_CODE (tgt
) == CONST_INT
)
2187 sprintf (result
, "call%d\t" HOST_WIDE_INT_PRINT_HEX
,
2188 WINDOW_SIZE
, INTVAL (tgt
));
2189 else if (register_operand (tgt
, VOIDmode
))
2190 sprintf (result
, "callx%d\t%%%d", WINDOW_SIZE
, callop
);
2192 sprintf (result
, "call%d\t%%%d", WINDOW_SIZE
, callop
);
2199 xtensa_emit_sibcall (int callop
, rtx
*operands
)
2201 static char result
[64];
2202 rtx tgt
= operands
[callop
];
2204 if (CONST_INT_P (tgt
))
2205 sprintf (result
, "j.l\t" HOST_WIDE_INT_PRINT_HEX
", a9",
2207 else if (register_operand (tgt
, VOIDmode
))
2208 sprintf (result
, "jx\t%%%d", callop
);
2210 sprintf (result
, "j.l\t%%%d, a9", callop
);
2217 xtensa_legitimate_address_p (machine_mode mode
, rtx addr
, bool strict
)
2219 /* Allow constant pool addresses. */
2220 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
2221 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
2222 && ! xtensa_tls_referenced_p (addr
))
2225 while (GET_CODE (addr
) == SUBREG
)
2226 addr
= SUBREG_REG (addr
);
2228 /* Allow base registers. */
2229 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
2232 /* Check for "register + offset" addressing. */
2233 if (GET_CODE (addr
) == PLUS
)
2235 rtx xplus0
= XEXP (addr
, 0);
2236 rtx xplus1
= XEXP (addr
, 1);
2237 enum rtx_code code0
;
2238 enum rtx_code code1
;
2240 while (GET_CODE (xplus0
) == SUBREG
)
2241 xplus0
= SUBREG_REG (xplus0
);
2242 code0
= GET_CODE (xplus0
);
2244 while (GET_CODE (xplus1
) == SUBREG
)
2245 xplus1
= SUBREG_REG (xplus1
);
2246 code1
= GET_CODE (xplus1
);
2248 /* Swap operands if necessary so the register is first. */
2249 if (code0
!= REG
&& code1
== REG
)
2251 xplus0
= XEXP (addr
, 1);
2252 xplus1
= XEXP (addr
, 0);
2253 code0
= GET_CODE (xplus0
);
2254 code1
= GET_CODE (xplus1
);
2257 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
2258 && code1
== CONST_INT
2259 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
2267 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
2269 static GTY(()) rtx xtensa_tls_module_base_symbol
;
2272 xtensa_tls_module_base (void)
2274 if (! xtensa_tls_module_base_symbol
)
2276 xtensa_tls_module_base_symbol
=
2277 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
2278 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
2279 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
2282 return xtensa_tls_module_base_symbol
;
2287 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
2290 rtx_insn
*call_insn
, *insns
;
2293 fn
= gen_reg_rtx (Pmode
);
2294 arg
= gen_reg_rtx (Pmode
);
2295 a_io
= gen_rtx_REG (Pmode
, WINDOW_SIZE
+ 2);
2297 emit_insn (gen_tls_func (fn
, sym
));
2298 emit_insn (gen_tls_arg (arg
, sym
));
2299 emit_move_insn (a_io
, arg
);
2300 call_insn
= emit_call_insn (gen_tls_call (a_io
, fn
, sym
, const1_rtx
));
2301 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
), a_io
);
2302 insns
= get_insns ();
2311 xtensa_legitimize_tls_address (rtx x
)
2313 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
2314 rtx dest
, tp
, ret
, modbase
, base
, addend
;
2317 dest
= gen_reg_rtx (Pmode
);
2320 case TLS_MODEL_GLOBAL_DYNAMIC
:
2321 insns
= xtensa_call_tls_desc (x
, &ret
);
2322 emit_libcall_block (insns
, dest
, ret
, x
);
2325 case TLS_MODEL_LOCAL_DYNAMIC
:
2326 base
= gen_reg_rtx (Pmode
);
2327 modbase
= xtensa_tls_module_base ();
2328 insns
= xtensa_call_tls_desc (modbase
, &ret
);
2329 emit_libcall_block (insns
, base
, ret
, modbase
);
2330 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
2331 emit_insn (gen_addsi3 (dest
, base
, addend
));
2334 case TLS_MODEL_INITIAL_EXEC
:
2335 case TLS_MODEL_LOCAL_EXEC
:
2336 tp
= gen_reg_rtx (SImode
);
2337 emit_insn (gen_get_thread_pointersi (tp
));
2338 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
2339 emit_insn (gen_addsi3 (dest
, tp
, addend
));
2351 xtensa_legitimize_address (rtx x
,
2352 rtx oldx ATTRIBUTE_UNUSED
,
2355 if (xtensa_tls_symbol_p (x
))
2356 return xtensa_legitimize_tls_address (x
);
2358 if (GET_CODE (x
) == PLUS
)
2360 rtx plus0
= XEXP (x
, 0);
2361 rtx plus1
= XEXP (x
, 1);
2363 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
2365 plus0
= XEXP (x
, 1);
2366 plus1
= XEXP (x
, 0);
2369 /* Try to split up the offset to use an ADDMI instruction. */
2370 if (GET_CODE (plus0
) == REG
2371 && GET_CODE (plus1
) == CONST_INT
2372 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
2373 && !xtensa_simm8 (INTVAL (plus1
))
2374 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
2375 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
2377 rtx temp
= gen_reg_rtx (Pmode
);
2378 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
2379 emit_insn (gen_rtx_SET (temp
, gen_rtx_PLUS (Pmode
, plus0
,
2381 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
2388 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
2390 Treat constant-pool references as "mode dependent" since they can
2391 only be accessed with SImode loads. This works around a bug in the
2392 combiner where a constant pool reference is temporarily converted
2393 to an HImode load, which is then assumed to zero-extend based on
2394 our definition of LOAD_EXTEND_OP. This is wrong because the high
2395 bits of a 16-bit value in the constant pool are now sign-extended
2399 xtensa_mode_dependent_address_p (const_rtx addr
,
2400 addr_space_t as ATTRIBUTE_UNUSED
)
2402 return constantpool_address_p (addr
);
2405 /* Return TRUE if X contains any TLS symbol references. */
2408 xtensa_tls_referenced_p (rtx x
)
2410 if (! targetm
.have_tls
)
2413 subrtx_iterator::array_type array
;
2414 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
2416 const_rtx x
= *iter
;
2417 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0)
2420 /* Ignore TLS references that have already been legitimized. */
2421 if (GET_CODE (x
) == UNSPEC
)
2422 switch (XINT (x
, 1))
2426 case UNSPEC_TLS_FUNC
:
2427 case UNSPEC_TLS_ARG
:
2428 case UNSPEC_TLS_CALL
:
2429 iter
.skip_subrtxes ();
2439 /* Helper function for "*shlrd_..." patterns. */
2442 xtensa_shlrd_which_direction (rtx op0
, rtx op1
)
2444 if (GET_CODE (op0
) == ASHIFT
&& GET_CODE (op1
) == LSHIFTRT
)
2445 return ASHIFT
; /* shld */
2446 if (GET_CODE (op0
) == LSHIFTRT
&& GET_CODE (op1
) == ASHIFT
)
2447 return LSHIFTRT
; /* shrd */
2453 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2456 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2458 return xtensa_tls_referenced_p (x
);
2462 /* Return the debugger register number to use for 'regno'. */
2465 xtensa_debugger_regno (int regno
)
2469 if (GP_REG_P (regno
))
2471 regno
-= GP_REG_FIRST
;
2474 else if (BR_REG_P (regno
))
2476 regno
-= BR_REG_FIRST
;
2479 else if (FP_REG_P (regno
))
2481 regno
-= FP_REG_FIRST
;
2484 else if (ACC_REG_P (regno
))
2486 first
= 0x200; /* Start of Xtensa special registers. */
2487 regno
= 16; /* ACCLO is special register 16. */
2490 /* When optimizing, we sometimes get asked about pseudo-registers
2491 that don't represent hard registers. Return 0 for these. */
2495 return first
+ regno
;
2499 /* Argument support functions. */
2501 /* Initialize CUMULATIVE_ARGS for a function. */
2504 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
2507 cum
->incoming
= incoming
;
2511 /* Advance the argument to the next argument position. */
2514 xtensa_function_arg_advance (cumulative_args_t cum
,
2515 const function_arg_info
&arg
)
2520 arg_words
= &get_cumulative_args (cum
)->arg_words
;
2521 max
= MAX_ARGS_IN_REGISTERS
;
2523 words
= ((arg
.promoted_size_in_bytes () + UNITS_PER_WORD
- 1)
2526 if (*arg_words
< max
2527 && (targetm
.calls
.must_pass_in_stack (arg
)
2528 || *arg_words
+ words
> max
))
2531 *arg_words
+= words
;
2535 /* Return an RTL expression containing the register for the given argument,
2536 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2537 if this is an incoming argument to the current function. */
2540 xtensa_function_arg_1 (cumulative_args_t cum_v
, const function_arg_info
&arg
,
2543 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2544 int regbase
, words
, max
;
2548 arg_words
= &cum
->arg_words
;
2549 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2550 max
= MAX_ARGS_IN_REGISTERS
;
2552 words
= ((arg
.promoted_size_in_bytes () + UNITS_PER_WORD
- 1)
2555 if (arg
.type
&& (TYPE_ALIGN (arg
.type
) > BITS_PER_WORD
))
2557 int align
= MIN (TYPE_ALIGN (arg
.type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2558 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2561 if (*arg_words
+ words
> max
)
2564 regno
= regbase
+ *arg_words
;
2566 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2567 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
2569 return gen_rtx_REG (arg
.mode
, regno
);
2572 /* Implement TARGET_FUNCTION_ARG. */
2575 xtensa_function_arg (cumulative_args_t cum
, const function_arg_info
&arg
)
2577 return xtensa_function_arg_1 (cum
, arg
, false);
2580 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2583 xtensa_function_incoming_arg (cumulative_args_t cum
,
2584 const function_arg_info
&arg
)
2586 return xtensa_function_arg_1 (cum
, arg
, true);
2590 xtensa_function_arg_boundary (machine_mode mode
, const_tree type
)
2592 unsigned int alignment
;
2594 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2595 if (alignment
< PARM_BOUNDARY
)
2596 alignment
= PARM_BOUNDARY
;
2597 if (alignment
> STACK_BOUNDARY
)
2598 alignment
= STACK_BOUNDARY
;
2604 xtensa_return_in_msb (const_tree valtype
)
2606 return (TARGET_BIG_ENDIAN
2607 && AGGREGATE_TYPE_P (valtype
)
2608 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2613 xtensa_option_override (void)
2618 if (xtensa_windowed_abi
== -1)
2619 xtensa_windowed_abi
= TARGET_WINDOWED_ABI_DEFAULT
;
2621 if (! TARGET_THREADPTR
)
2622 targetm
.have_tls
= false;
2624 /* Use CONST16 in the absence of L32R.
2625 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa
2626 configuration in the xtensa-common.cc */
2629 target_flags
|= MASK_CONST16
;
2631 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2632 error ("boolean registers required for the floating-point option");
2634 /* Set up array giving whether a given register can hold a given mode. */
2635 for (mode
= VOIDmode
;
2636 mode
!= MAX_MACHINE_MODE
;
2637 mode
= (machine_mode
) ((int) mode
+ 1))
2639 int size
= GET_MODE_SIZE (mode
);
2640 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2642 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2646 if (ACC_REG_P (regno
))
2647 temp
= (TARGET_MAC16
2648 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2649 else if (GP_REG_P (regno
))
2650 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2651 else if (FP_REG_P (regno
))
2652 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2653 else if (BR_REG_P (regno
))
2654 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2658 xtensa_hard_regno_mode_ok_p
[(int) mode
][regno
] = temp
;
2662 init_machine_status
= xtensa_init_machine_status
;
2664 /* Check PIC settings. PIC is only supported when using L32R
2665 instructions, and some targets need to always use PIC. */
2666 if (flag_pic
&& TARGET_CONST16
)
2667 error ("%<-f%s%> is not supported with CONST16 instructions",
2668 (flag_pic
> 1 ? "PIC" : "pic"));
2669 else if (TARGET_FORCE_NO_PIC
)
2671 else if (XTENSA_ALWAYS_PIC
)
2674 error ("PIC is required but not supported with CONST16 instructions");
2677 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2680 if (flag_pic
&& !flag_pie
)
2683 /* Hot/cold partitioning does not work on this architecture, because of
2684 constant pools (the load instruction cannot necessarily reach that far).
2685 Therefore disable it on this architecture. */
2686 if (flag_reorder_blocks_and_partition
)
2688 flag_reorder_blocks_and_partition
= 0;
2689 flag_reorder_blocks
= 1;
2693 /* Implement TARGET_HARD_REGNO_NREGS. */
2696 xtensa_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
2698 if (FP_REG_P (regno
))
2699 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_FPREG
);
2700 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
2703 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2706 xtensa_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
2708 return xtensa_hard_regno_mode_ok_p
[mode
][regno
];
2711 /* Implement TARGET_MODES_TIEABLE_P. */
2714 xtensa_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
2716 return ((GET_MODE_CLASS (mode1
) == MODE_FLOAT
2717 || GET_MODE_CLASS (mode1
) == MODE_COMPLEX_FLOAT
)
2718 == (GET_MODE_CLASS (mode2
) == MODE_FLOAT
2719 || GET_MODE_CLASS (mode2
) == MODE_COMPLEX_FLOAT
));
2722 /* A C compound statement to output to stdio stream STREAM the
2723 assembler syntax for an instruction operand X. X is an RTL
2726 CODE is a value that can be used to specify one of several ways
2727 of printing the operand. It is used when identical operands
2728 must be printed differently depending on the context. CODE
2729 comes from the '%' specification that was used to request
2730 printing of the operand. If the specification was just '%DIGIT'
2731 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2732 is the ASCII code for LTR.
2734 If X is a register, this macro should print the register's name.
2735 The names can be found in an array 'reg_names' whose type is
2736 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2738 When the machine description has a specification '%PUNCT' (a '%'
2739 followed by a punctuation character), this macro is called with
2740 a null pointer for X and the punctuation character for CODE.
2742 'a', 'c', 'l', and 'n' are reserved.
2744 The Xtensa specific codes are:
2746 'd' CONST_INT, print as signed decimal
2747 'x' CONST_INT, print as signed hexadecimal
2748 'K' CONST_INT, print number of bits in mask for EXTUI
2749 'R' CONST_INT, print (X & 0x1f)
2750 'L' CONST_INT, print ((32 - X) & 0x1f)
2751 'D' REG, print second register of double-word register operand
2752 'N' MEM, print address of next word following a memory operand
2753 'v' MEM, if memory reference is volatile, output a MEMW before it
2754 't' any constant, add "@h" suffix for top 16 bits
2755 'b' any constant, add "@l" suffix for bottom 16 bits
2759 printx (FILE *file
, signed int val
)
2761 /* Print a hexadecimal value in a nice way. */
2762 if (IN_RANGE (val
, -9, 9))
2763 fprintf (file
, "%d", val
);
2765 fprintf (file
, "-0x%x", -val
);
2767 fprintf (file
, "0x%x", val
);
2772 print_operand (FILE *file
, rtx x
, int letter
)
2775 error ("%<PRINT_OPERAND%> null pointer");
2780 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2781 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2783 output_operand_lossage ("invalid %%D value");
2787 if (GET_CODE (x
) == MEM
)
2789 /* For a volatile memory reference, emit a MEMW before the
2791 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2792 fprintf (file
, "memw\n\t");
2795 output_operand_lossage ("invalid %%v value");
2799 if (GET_CODE (x
) == MEM
2800 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2802 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? E_SFmode
: E_SImode
,
2804 output_address (GET_MODE (x
), XEXP (x
, 0));
2807 output_operand_lossage ("invalid %%N value");
2811 if (GET_CODE (x
) == CONST_INT
)
2813 unsigned val
= INTVAL (x
);
2814 if (!xtensa_mask_immediate (val
))
2815 fatal_insn ("invalid mask", x
);
2817 fprintf (file
, "%d", floor_log2 (val
+ 1));
2820 output_operand_lossage ("invalid %%K value");
2824 if (GET_CODE (x
) == CONST_INT
)
2825 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INTVAL (x
)) & 0x1f);
2827 output_operand_lossage ("invalid %%L value");
2831 if (GET_CODE (x
) == CONST_INT
)
2832 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0x1f);
2834 output_operand_lossage ("invalid %%R value");
2838 if (GET_CODE (x
) == CONST_INT
)
2839 printx (file
, INTVAL (x
));
2841 output_operand_lossage ("invalid %%x value");
2845 if (GET_CODE (x
) == CONST_INT
)
2846 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2848 output_operand_lossage ("invalid %%d value");
2853 if (GET_CODE (x
) == CONST_INT
)
2855 printx (file
, INTVAL (x
));
2856 fputs (letter
== 't' ? "@h" : "@l", file
);
2858 else if (GET_CODE (x
) == CONST_DOUBLE
)
2860 if (GET_MODE (x
) == SFmode
)
2863 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2864 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2867 output_operand_lossage ("invalid %%t/%%b value");
2869 else if (GET_CODE (x
) == CONST
)
2871 /* X must be a symbolic constant on ELF. Write an expression
2872 suitable for 'const16' that sets the high or low 16 bits. */
2873 if (GET_CODE (XEXP (x
, 0)) != PLUS
2874 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2875 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2876 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2877 output_operand_lossage ("invalid %%t/%%b value");
2878 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2879 fputs (letter
== 't' ? "@h" : "@l", file
);
2880 /* There must be a non-alphanumeric character between 'h' or 'l'
2881 and the number. The '-' is added by print_operand() already. */
2882 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2884 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2888 output_addr_const (file
, x
);
2889 fputs (letter
== 't' ? "@h" : "@l", file
);
2894 if (GET_CODE (x
) == CONST_DOUBLE
&&
2895 GET_MODE (x
) == SFmode
)
2898 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2899 fprintf (file
, "0x%08lx", l
);
2906 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2907 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2908 else if (GET_CODE (x
) == MEM
)
2909 output_address (GET_MODE (x
), XEXP (x
, 0));
2910 else if (GET_CODE (x
) == CONST_INT
)
2911 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2913 output_addr_const (file
, x
);
2918 /* A C compound statement to output to stdio stream STREAM the
2919 assembler syntax for an instruction operand that is a memory
2920 reference whose address is ADDR. ADDR is an RTL expression. */
2923 print_operand_address (FILE *file
, rtx addr
)
2926 error ("%<PRINT_OPERAND_ADDRESS%>, null pointer");
2928 switch (GET_CODE (addr
))
2931 fatal_insn ("invalid address", addr
);
2935 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2941 rtx offset
= (rtx
)0;
2942 rtx arg0
= XEXP (addr
, 0);
2943 rtx arg1
= XEXP (addr
, 1);
2945 if (GET_CODE (arg0
) == REG
)
2950 else if (GET_CODE (arg1
) == REG
)
2956 fatal_insn ("no register in address", addr
);
2958 if (CONSTANT_P (offset
))
2960 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2961 output_addr_const (file
, offset
);
2964 fatal_insn ("address offset not a constant", addr
);
2972 output_addr_const (file
, addr
);
2977 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2980 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2982 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2984 switch (XINT (x
, 1))
2987 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2988 fputs ("@TPOFF", fp
);
2991 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2992 fputs ("@DTPOFF", fp
);
2997 output_addr_const (fp
, XVECEXP (x
, 0, 0));
3010 xtensa_output_integer_literal_parts (FILE *file
, rtx x
, int size
)
3012 if (size
> 4 && !(size
& (size
- 1)))
3016 split_double (x
, &first
, &second
);
3017 xtensa_output_integer_literal_parts (file
, first
, size
/ 2);
3019 xtensa_output_integer_literal_parts (file
, second
, size
/ 2);
3023 output_addr_const (file
, x
);
3032 xtensa_output_literal (FILE *file
, rtx x
, machine_mode mode
, int labelno
)
3036 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
3038 switch (GET_MODE_CLASS (mode
))
3041 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
3046 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
),
3048 if (HOST_BITS_PER_LONG
> 32)
3049 value_long
[0] &= 0xffffffff;
3050 fprintf (file
, "0x%08lx\n", value_long
[0]);
3054 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x
),
3056 if (HOST_BITS_PER_LONG
> 32)
3058 value_long
[0] &= 0xffffffff;
3059 value_long
[1] &= 0xffffffff;
3061 fprintf (file
, "0x%08lx, 0x%08lx\n",
3062 value_long
[0], value_long
[1]);
3072 case MODE_PARTIAL_INT
:
3073 xtensa_output_integer_literal_parts (file
, x
, GET_MODE_SIZE (mode
));
3083 xtensa_call_save_reg (int regno
)
3085 if (TARGET_WINDOWED_ABI
)
3088 if (regno
== A0_REG
)
3089 return crtl
->profile
|| !crtl
->is_leaf
|| crtl
->calls_eh_return
||
3090 df_regs_ever_live_p (regno
);
3092 if (crtl
->calls_eh_return
&& IN_RANGE (regno
, 2, 3))
3095 return !call_used_or_fixed_reg_p (regno
) && df_regs_ever_live_p (regno
);
3098 /* Return the bytes needed to compute the frame pointer from the current
3101 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
3102 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
3105 compute_frame_size (poly_int64 size
)
3109 if (reload_completed
&& cfun
->machine
->frame_laid_out
)
3110 return cfun
->machine
->current_frame_size
;
3112 /* Add space for the incoming static chain value. */
3113 if (cfun
->static_chain_decl
!= NULL
)
3114 size
+= (1 * UNITS_PER_WORD
);
3116 cfun
->machine
->callee_save_size
= 0;
3117 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
3119 if (xtensa_call_save_reg (regno
))
3120 cfun
->machine
->callee_save_size
+= UNITS_PER_WORD
;
3123 cfun
->machine
->current_frame_size
=
3124 XTENSA_STACK_ALIGN (size
3125 + cfun
->machine
->callee_save_size
3126 + crtl
->outgoing_args_size
3127 + (WINDOW_SIZE
* UNITS_PER_WORD
));
3128 cfun
->machine
->callee_save_size
=
3129 XTENSA_STACK_ALIGN (cfun
->machine
->callee_save_size
);
3130 cfun
->machine
->frame_laid_out
= true;
3131 return cfun
->machine
->current_frame_size
;
3136 xtensa_frame_pointer_required (void)
3138 /* The code to expand builtin_frame_addr and builtin_return_addr
3139 currently uses the hard_frame_pointer instead of frame_pointer.
3140 This seems wrong but maybe it's necessary for other architectures.
3141 This function is derived from the i386 code. */
3143 if (cfun
->machine
->accesses_prev_frame
|| cfun
->has_nonlocal_label
)
3150 xtensa_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
3152 long frame_size
= compute_frame_size (get_frame_size ());
3153 HOST_WIDE_INT offset
;
3157 case FRAME_POINTER_REGNUM
:
3158 if (FRAME_GROWS_DOWNWARD
)
3159 offset
= frame_size
- (WINDOW_SIZE
* UNITS_PER_WORD
)
3160 - cfun
->machine
->callee_save_size
;
3164 case ARG_POINTER_REGNUM
:
3165 offset
= frame_size
;
3174 #define ADJUST_SP_NONE 0x0
3175 #define ADJUST_SP_NEED_NOTE 0x1
3176 #define ADJUST_SP_FRAME_PTR 0x2
3178 xtensa_emit_adjust_stack_ptr (HOST_WIDE_INT offset
, int flags
)
3181 rtx ptr
= (flags
& ADJUST_SP_FRAME_PTR
) ? hard_frame_pointer_rtx
3182 : stack_pointer_rtx
;
3184 if (cfun
->machine
->inhibit_logues_a1_adjusts
)
3187 if (xtensa_simm8 (offset
)
3188 || xtensa_simm8x256 (offset
))
3189 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, ptr
, GEN_INT (offset
)));
3192 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
3196 emit_move_insn (tmp_reg
, GEN_INT (-offset
));
3197 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
, ptr
, tmp_reg
));
3201 emit_move_insn (tmp_reg
, GEN_INT (offset
));
3202 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, ptr
, tmp_reg
));
3206 if (flags
& ADJUST_SP_NEED_NOTE
)
3208 rtx note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
3209 plus_constant (Pmode
, stack_pointer_rtx
,
3212 RTX_FRAME_RELATED_P (insn
) = 1;
3213 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
3217 /* minimum frame = reg save area (4 words) plus static chain (1 word)
3218 and the total number of words must be a multiple of 128 bits. */
3219 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
3222 xtensa_expand_prologue (void)
3224 HOST_WIDE_INT total_size
;
3225 rtx_insn
*insn
= NULL
;
3228 total_size
= compute_frame_size (get_frame_size ());
3230 if (flag_stack_usage_info
)
3231 current_function_static_stack_size
= total_size
;
3233 if (TARGET_WINDOWED_ABI
)
3235 if (total_size
< (1 << (12+3)))
3236 insn
= emit_insn (gen_entry (GEN_INT (total_size
)));
3239 /* Use a8 as a temporary since a0-a7 may be live. */
3240 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
3241 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
3242 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
3243 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
3244 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
3250 HOST_WIDE_INT offset
= 0;
3251 int callee_save_size
= cfun
->machine
->callee_save_size
;
3253 bool stack_pointer_needed
= frame_pointer_needed
3254 || crtl
->calls_eh_return
;
3256 /* Check if the function body really needs the stack pointer. */
3257 if (!stack_pointer_needed
)
3258 for (ref
= DF_REG_USE_CHAIN (A1_REG
);
3259 ref
; ref
= DF_REF_NEXT_REG (ref
))
3260 if (DF_REF_CLASS (ref
) == DF_REF_REGULAR
3261 && NONJUMP_INSN_P (DF_REF_INSN (ref
)))
3262 stack_pointer_needed
= true;
3263 /* Check if callee-saved registers really need saving to the stack. */
3264 if (!stack_pointer_needed
)
3265 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
3266 if (xtensa_call_save_reg (regno
))
3267 stack_pointer_needed
= true;
3269 cfun
->machine
->inhibit_logues_a1_adjusts
= !stack_pointer_needed
;
3271 /* -128 is a limit of single addi instruction. */
3272 if (IN_RANGE (total_size
, 1, 128))
3274 xtensa_emit_adjust_stack_ptr (-total_size
,
3275 ADJUST_SP_NEED_NOTE
);
3276 offset
= total_size
- UNITS_PER_WORD
;
3278 else if (callee_save_size
)
3280 /* 1020 is maximal s32i offset, if the frame is bigger than that
3281 * we move sp to the end of callee-saved save area, save and then
3282 * move it to its final location. */
3283 if (total_size
> 1024)
3285 xtensa_emit_adjust_stack_ptr (-callee_save_size
,
3286 ADJUST_SP_NEED_NOTE
);
3287 offset
= callee_save_size
- UNITS_PER_WORD
;
3291 xtensa_emit_adjust_stack_ptr (-total_size
,
3292 ADJUST_SP_NEED_NOTE
);
3293 offset
= total_size
- UNITS_PER_WORD
;
3297 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
3299 if (xtensa_call_save_reg(regno
))
3301 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
3302 rtx mem
= gen_frame_mem (SImode
, x
);
3303 rtx reg
= gen_rtx_REG (SImode
, regno
);
3305 offset
-= UNITS_PER_WORD
;
3306 insn
= emit_move_insn (mem
, reg
);
3307 RTX_FRAME_RELATED_P (insn
) = 1;
3308 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
3309 gen_rtx_SET (mem
, reg
));
3312 if (total_size
> 1024
3313 || (!callee_save_size
&& total_size
> 128))
3314 xtensa_emit_adjust_stack_ptr (callee_save_size
- total_size
,
3315 ADJUST_SP_NEED_NOTE
);
3318 if (frame_pointer_needed
)
3320 if (cfun
->machine
->set_frame_ptr_insn
)
3324 push_topmost_sequence ();
3325 first
= get_insns ();
3326 pop_topmost_sequence ();
3328 /* For all instructions prior to set_frame_ptr_insn, replace
3329 hard_frame_pointer references with stack_pointer. */
3331 insn
!= cfun
->machine
->set_frame_ptr_insn
;
3332 insn
= NEXT_INSN (insn
))
3336 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
3337 hard_frame_pointer_rtx
,
3339 df_insn_rescan (insn
);
3345 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
3346 stack_pointer_rtx
));
3347 if (!TARGET_WINDOWED_ABI
)
3349 note_rtx
= gen_rtx_SET (hard_frame_pointer_rtx
,
3351 RTX_FRAME_RELATED_P (insn
) = 1;
3352 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
3357 if (TARGET_WINDOWED_ABI
)
3359 /* Create a note to describe the CFA. Because this is only used to set
3360 DW_AT_frame_base for debug info, don't bother tracking changes through
3361 each instruction in the prologue. It just takes up space. */
3362 note_rtx
= gen_rtx_SET ((frame_pointer_needed
3363 ? hard_frame_pointer_rtx
3364 : stack_pointer_rtx
),
3365 plus_constant (Pmode
, stack_pointer_rtx
,
3367 RTX_FRAME_RELATED_P (insn
) = 1;
3368 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
3373 xtensa_expand_epilogue (bool sibcall_p
)
3375 if (!TARGET_WINDOWED_ABI
)
3378 HOST_WIDE_INT offset
;
3380 if (cfun
->machine
->current_frame_size
> (frame_pointer_needed
? 127 : 1024))
3382 xtensa_emit_adjust_stack_ptr (cfun
->machine
->current_frame_size
-
3383 cfun
->machine
->callee_save_size
,
3384 frame_pointer_needed
3385 ? ADJUST_SP_FRAME_PTR
3387 offset
= cfun
->machine
->callee_save_size
- UNITS_PER_WORD
;
3391 if (frame_pointer_needed
)
3392 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
3393 offset
= cfun
->machine
->current_frame_size
- UNITS_PER_WORD
;
3396 /* Prevent reordering of saved a0 update and loading it back from
3398 if (crtl
->calls_eh_return
)
3399 emit_insn (gen_blockage ());
3401 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
3403 if (xtensa_call_save_reg(regno
))
3405 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
3408 offset
-= UNITS_PER_WORD
;
3409 emit_move_insn (reg
= gen_rtx_REG (SImode
, regno
),
3410 gen_frame_mem (SImode
, x
));
3411 if (regno
== A0_REG
&& sibcall_p
)
3416 if (cfun
->machine
->current_frame_size
> 0)
3418 if (frame_pointer_needed
|| /* always reachable with addi */
3419 cfun
->machine
->current_frame_size
> 1024 ||
3420 cfun
->machine
->current_frame_size
<= 127)
3422 if (cfun
->machine
->current_frame_size
<= 127)
3423 offset
= cfun
->machine
->current_frame_size
;
3425 offset
= cfun
->machine
->callee_save_size
;
3427 xtensa_emit_adjust_stack_ptr (offset
, ADJUST_SP_NONE
);
3430 xtensa_emit_adjust_stack_ptr (cfun
->machine
->current_frame_size
,
3434 if (crtl
->calls_eh_return
)
3435 emit_insn (gen_add3_insn (stack_pointer_rtx
,
3437 EH_RETURN_STACKADJ_RTX
));
3439 cfun
->machine
->epilogue_done
= true;
3441 emit_jump_insn (gen_return ());
3445 xtensa_use_return_instruction_p (void)
3447 if (!reload_completed
)
3449 if (TARGET_WINDOWED_ABI
)
3451 if (compute_frame_size (get_frame_size ()) == 0)
3453 return cfun
->machine
->epilogue_done
;
3457 xtensa_set_return_address (rtx address
, rtx scratch
)
3459 HOST_WIDE_INT total_size
= compute_frame_size (get_frame_size ());
3460 rtx frame
= frame_pointer_needed
?
3461 hard_frame_pointer_rtx
: stack_pointer_rtx
;
3462 rtx a0_addr
= plus_constant (Pmode
, frame
,
3463 total_size
- UNITS_PER_WORD
);
3464 rtx note
= gen_rtx_SET (gen_frame_mem (SImode
, a0_addr
),
3465 gen_rtx_REG (SImode
, A0_REG
));
3468 if (total_size
> 1024) {
3469 emit_move_insn (scratch
, GEN_INT (total_size
- UNITS_PER_WORD
));
3470 emit_insn (gen_addsi3 (scratch
, frame
, scratch
));
3474 insn
= emit_move_insn (gen_frame_mem (SImode
, a0_addr
), address
);
3475 RTX_FRAME_RELATED_P (insn
) = 1;
3476 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
3480 xtensa_return_addr (int count
, rtx frame
)
3482 rtx result
, retaddr
, curaddr
, label
;
3484 if (!TARGET_WINDOWED_ABI
)
3489 return get_hard_reg_initial_val (Pmode
, A0_REG
);
3493 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
3496 rtx addr
= plus_constant (Pmode
, frame
, -4 * UNITS_PER_WORD
);
3497 addr
= memory_address (Pmode
, addr
);
3498 retaddr
= gen_reg_rtx (Pmode
);
3499 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
3502 /* The 2 most-significant bits of the return address on Xtensa hold
3503 the register window size. To get the real return address, these
3504 bits must be replaced with the high bits from some address in the
3507 /* Get the 2 high bits of a local label in the code. */
3508 curaddr
= gen_reg_rtx (Pmode
);
3509 label
= gen_label_rtx ();
3511 LABEL_PRESERVE_P (label
) = 1;
3512 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
3513 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
3514 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
3516 /* Clear the 2 high bits of the return address. */
3517 result
= gen_reg_rtx (Pmode
);
3518 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
3519 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
3521 /* Combine them to get the result. */
3522 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
3526 /* Disable the use of word-sized or smaller complex modes for structures,
3527 and for function arguments in particular, where they cause problems with
3528 register a7. The xtensa_copy_incoming_a7 function assumes that there is
3529 a single reference to an argument in a7, but with small complex modes the
3530 real and imaginary components may be extracted separately, leading to two
3531 uses of the register, only one of which would be replaced. */
3534 xtensa_member_type_forces_blk (const_tree
, machine_mode mode
)
3536 return mode
== CQImode
|| mode
== CHImode
;
3539 /* Create the va_list data type.
3541 This structure is set up by __builtin_saveregs. The __va_reg field
3542 points to a stack-allocated region holding the contents of the
3543 incoming argument registers. The __va_ndx field is an index
3544 initialized to the position of the first unnamed (variable)
3545 argument. This same index is also used to address the arguments
3546 passed in memory. Thus, the __va_stk field is initialized to point
3547 to the position of the first argument in memory offset to account
3548 for the arguments passed in registers and to account for the size
3549 of the argument registers not being 16-byte aligned. E.G., there
3550 are 6 argument registers of 4 bytes each, but we want the __va_ndx
3551 for the first stack argument to have the maximal alignment of 16
3552 bytes, so we offset the __va_stk address by 32 bytes so that
3553 __va_stk[32] references the first argument on the stack. */
3556 xtensa_build_builtin_va_list (void)
3558 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
3560 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
3561 type_decl
= build_decl (BUILTINS_LOCATION
,
3562 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
3564 f_stk
= build_decl (BUILTINS_LOCATION
,
3565 FIELD_DECL
, get_identifier ("__va_stk"),
3567 f_reg
= build_decl (BUILTINS_LOCATION
,
3568 FIELD_DECL
, get_identifier ("__va_reg"),
3570 f_ndx
= build_decl (BUILTINS_LOCATION
,
3571 FIELD_DECL
, get_identifier ("__va_ndx"),
3574 DECL_FIELD_CONTEXT (f_stk
) = record
;
3575 DECL_FIELD_CONTEXT (f_reg
) = record
;
3576 DECL_FIELD_CONTEXT (f_ndx
) = record
;
3578 TYPE_STUB_DECL (record
) = type_decl
;
3579 TYPE_NAME (record
) = type_decl
;
3580 TYPE_FIELDS (record
) = f_stk
;
3581 DECL_CHAIN (f_stk
) = f_reg
;
3582 DECL_CHAIN (f_reg
) = f_ndx
;
3584 layout_type (record
);
3589 /* Save the incoming argument registers on the stack. Returns the
3590 address of the saved registers. */
3593 xtensa_builtin_saveregs (void)
3596 int arg_words
= crtl
->args
.info
.arg_words
;
3597 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
3602 /* Allocate the general-purpose register space. */
3603 gp_regs
= assign_stack_local
3604 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
3605 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
3607 /* Now store the incoming registers. */
3608 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
3609 cfun
->machine
->vararg_a7
= true;
3610 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
3611 adjust_address (gp_regs
, BLKmode
,
3612 arg_words
* UNITS_PER_WORD
),
3614 if (cfun
->machine
->vararg_a7_copy
!= 0)
3615 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
3617 return XEXP (gp_regs
, 0);
3621 /* Implement `va_start' for varargs and stdarg. We look at the
3622 current function to fill in an initial va_list. */
3625 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
3633 arg_words
= crtl
->args
.info
.arg_words
;
3635 f_stk
= TYPE_FIELDS (va_list_type_node
);
3636 f_reg
= DECL_CHAIN (f_stk
);
3637 f_ndx
= DECL_CHAIN (f_reg
);
3639 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
3640 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3642 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3645 /* Call __builtin_saveregs; save the result in __va_reg */
3646 u
= make_tree (sizetype
, expand_builtin_saveregs ());
3647 u
= fold_convert (ptr_type_node
, u
);
3648 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
3649 TREE_SIDE_EFFECTS (t
) = 1;
3650 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3652 /* Set the __va_stk member to ($arg_ptr - 32). */
3653 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
3654 u
= fold_build_pointer_plus_hwi (u
, -32);
3655 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
3656 TREE_SIDE_EFFECTS (t
) = 1;
3657 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3659 /* Set the __va_ndx member. If the first variable argument is on
3660 the stack, adjust __va_ndx by 2 words to account for the extra
3661 alignment offset for __va_stk. */
3662 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
3664 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
3665 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
3666 TREE_SIDE_EFFECTS (t
) = 1;
3667 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3671 /* Implement `va_arg'. */
3674 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
3675 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
3680 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
3681 tree lab_false
, lab_over
, lab_false2
;
3684 indirect
= pass_va_arg_by_reference (type
);
3686 type
= build_pointer_type (type
);
3688 /* Handle complex values as separate real and imaginary parts. */
3689 if (TREE_CODE (type
) == COMPLEX_TYPE
)
3691 tree real_part
, imag_part
;
3693 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
3695 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
3697 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
3700 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
3702 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
3705 f_stk
= TYPE_FIELDS (va_list_type_node
);
3706 f_reg
= DECL_CHAIN (f_stk
);
3707 f_ndx
= DECL_CHAIN (f_reg
);
3709 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
3711 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3713 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3716 type_size
= size_in_bytes (type
);
3717 va_size
= round_up (type_size
, UNITS_PER_WORD
);
3718 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
3721 /* First align __va_ndx if necessary for this arg:
3723 orig_ndx = (AP).__va_ndx;
3724 if (__alignof__ (TYPE) > 4 )
3725 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3726 & -__alignof__ (TYPE)); */
3728 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
3730 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
3732 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
3734 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
3735 build_int_cst (integer_type_node
, align
- 1));
3736 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
3737 build_int_cst (integer_type_node
, -align
));
3738 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
3742 /* Increment __va_ndx to point past the argument:
3744 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3746 t
= fold_convert (integer_type_node
, va_size
);
3747 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
3748 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3751 /* Check if the argument is in registers:
3753 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3754 && !must_pass_in_stack (type))
3755 __array = (AP).__va_reg; */
3757 array
= create_tmp_var (ptr_type_node
);
3760 if (!must_pass_va_arg_in_stack (type
))
3762 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
3763 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
3765 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
3766 build_int_cst (integer_type_node
,
3767 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3768 t
= build3 (COND_EXPR
, void_type_node
, t
,
3769 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
3771 gimplify_and_add (t
, pre_p
);
3773 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
3775 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
3776 gimplify_and_add (t
, pre_p
);
3778 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
3779 gimplify_and_add (t
, pre_p
);
3783 /* ...otherwise, the argument is on the stack (never split between
3784 registers and the stack -- change __va_ndx if necessary):
3788 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3789 (AP).__va_ndx = 32 + __va_size (TYPE);
3790 __array = (AP).__va_stk;
3793 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
3795 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
3796 build_int_cst (integer_type_node
,
3797 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3798 t
= build3 (COND_EXPR
, void_type_node
, t
,
3799 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
3801 gimplify_and_add (t
, pre_p
);
3803 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
3804 t
= fold_convert (integer_type_node
, t
);
3805 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3807 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
3808 gimplify_and_add (t
, pre_p
);
3810 gimplify_assign (array
, stk
, pre_p
);
3814 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
3815 gimplify_and_add (t
, pre_p
);
3819 /* Given the base array pointer (__array) and index to the subsequent
3820 argument (__va_ndx), find the address:
3822 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3826 The results are endian-dependent because values smaller than one word
3827 are aligned differently. */
3830 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
3832 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
3833 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
3834 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
3835 unshare_expr (type_size
));
3839 size
= unshare_expr (va_size
);
3841 t
= fold_convert (sizetype
, unshare_expr (ndx
));
3842 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
3843 addr
= fold_build_pointer_plus (unshare_expr (array
), t
);
3845 addr
= fold_convert (build_pointer_type (type
), addr
);
3847 addr
= build_va_arg_indirect_ref (addr
);
3848 return build_va_arg_indirect_ref (addr
);
3856 XTENSA_BUILTIN_UMULSIDI3
,
3862 xtensa_init_builtins (void)
3866 ftype
= build_function_type_list (unsigned_intDI_type_node
,
3867 unsigned_intSI_type_node
,
3868 unsigned_intSI_type_node
, NULL_TREE
);
3870 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
3871 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
3872 "__umulsidi3", NULL_TREE
);
3873 TREE_NOTHROW (decl
) = 1;
3874 TREE_READONLY (decl
) = 1;
3879 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3880 bool ignore ATTRIBUTE_UNUSED
)
3882 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
3887 case XTENSA_BUILTIN_UMULSIDI3
:
3890 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3891 || TARGET_MUL32_HIGH
)
3892 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3893 fold_convert (unsigned_intDI_type_node
, arg0
),
3894 fold_convert (unsigned_intDI_type_node
, arg1
));
3898 internal_error ("bad builtin code");
3907 xtensa_expand_builtin (tree exp
, rtx target
,
3908 rtx subtarget ATTRIBUTE_UNUSED
,
3909 machine_mode mode ATTRIBUTE_UNUSED
,
3912 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3913 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
3917 case XTENSA_BUILTIN_UMULSIDI3
:
3918 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3919 __umulsidi3 function when the Xtensa configuration can directly
3920 implement it. If not, just call the function. */
3921 return expand_call (exp
, target
, ignore
);
3924 internal_error ("bad builtin code");
3929 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3932 xtensa_preferred_reload_class (rtx x
, reg_class_t rclass
)
3934 if (CONSTANT_P (x
) && CONST_DOUBLE_P (x
))
3937 /* Don't use the stack pointer or hard frame pointer for reloads!
3938 The hard frame pointer would normally be OK except that it may
3939 briefly hold an incoming argument in the prologue, and reload
3940 won't know that it is live because the hard frame pointer is
3941 treated specially. */
3943 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3949 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3952 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED
,
3955 /* Don't use the stack pointer or hard frame pointer for reloads!
3956 The hard frame pointer would normally be OK except that it may
3957 briefly hold an incoming argument in the prologue, and reload
3958 won't know that it is live because the hard frame pointer is
3959 treated specially. */
3961 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3967 /* Worker function for TARGET_SECONDARY_RELOAD. */
3970 xtensa_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass
,
3971 machine_mode mode
, secondary_reload_info
*sri
)
3975 if (in_p
&& constantpool_mem_p (x
))
3977 if (rclass
== FP_REGS
)
3981 sri
->icode
= CODE_FOR_reloadqi_literal
;
3982 else if (mode
== HImode
)
3983 sri
->icode
= CODE_FOR_reloadhi_literal
;
3986 regno
= xt_true_regnum (x
);
3987 if (ACC_REG_P (regno
))
3988 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3989 if (rclass
== ACC_REG
)
3990 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3997 order_regs_for_local_alloc (void)
3999 if (!leaf_function_p ())
4001 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
4003 static const int reg_nonleaf_alloc_order_call0
[FIRST_PSEUDO_REGISTER
] =
4005 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
4007 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
4012 memcpy (reg_alloc_order
, TARGET_WINDOWED_ABI
?
4013 reg_nonleaf_alloc_order
: reg_nonleaf_alloc_order_call0
,
4014 FIRST_PSEUDO_REGISTER
* sizeof (int));
4018 int i
, num_arg_regs
;
4021 /* Use the AR registers in increasing order (skipping a0 and a1)
4022 but save the incoming argument registers for a last resort. */
4023 num_arg_regs
= crtl
->args
.info
.arg_words
;
4024 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
4025 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
4026 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
4027 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
4028 for (i
= 0; i
< num_arg_regs
; i
++)
4029 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
4031 /* List the coprocessor registers in order. */
4032 for (i
= 0; i
< BR_REG_NUM
; i
++)
4033 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
4035 /* List the FP registers in order for now. */
4036 for (i
= 0; i
< 16; i
++)
4037 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
4039 /* GCC requires that we list *all* the registers.... */
4040 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
4041 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
4042 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
4043 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
4045 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
4050 /* Some Xtensa targets support multiple bss sections. If the section
4051 name ends with ".bss", add SECTION_BSS to the flags. */
4054 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
4056 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
4059 suffix
= strrchr (name
, '.');
4060 if (suffix
&& strcmp (suffix
, ".bss") == 0)
4062 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
4063 && DECL_INITIAL (decl
) == NULL_TREE
))
4064 flags
|= SECTION_BSS
; /* @nobits */
4066 warning (0, "only uninitialized variables can be placed in a "
4067 "%<.bss%> section");
4074 /* The literal pool stays with the function. */
4077 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED
,
4078 rtx x ATTRIBUTE_UNUSED
,
4079 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
4081 return function_section (current_function_decl
);
4084 /* Worker function for TARGET_REGISTER_MOVE_COST. */
4087 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
4088 reg_class_t from
, reg_class_t to
)
4090 if (from
== to
&& from
!= BR_REGS
&& to
!= BR_REGS
)
4092 else if (reg_class_subset_p (from
, AR_REGS
)
4093 && reg_class_subset_p (to
, AR_REGS
))
4095 else if (reg_class_subset_p (from
, AR_REGS
) && to
== ACC_REG
)
4097 else if (from
== ACC_REG
&& reg_class_subset_p (to
, AR_REGS
))
4103 /* Worker function for TARGET_MEMORY_MOVE_COST. */
4106 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
4107 reg_class_t rclass ATTRIBUTE_UNUSED
,
4108 bool in ATTRIBUTE_UNUSED
)
4113 /* Compute a (partial) cost for rtx X. Return true if the complete
4114 cost has been computed, and false if subexpressions should be
4115 scanned. In either case, *TOTAL contains the cost result. */
4118 xtensa_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4119 int opno ATTRIBUTE_UNUSED
,
4120 int *total
, bool speed
)
4122 int code
= GET_CODE (x
);
4130 if (xtensa_simm12b (INTVAL (x
)))
4132 *total
= speed
? COSTS_N_INSNS (1) : 0;
4137 if (xtensa_simm8 (INTVAL (x
))
4138 || xtensa_simm8x256 (INTVAL (x
)))
4145 if (xtensa_mask_immediate (INTVAL (x
)))
4152 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
4163 /* No way to tell if X is the 2nd operand so be conservative. */
4166 if (xtensa_simm12b (INTVAL (x
)))
4168 else if (TARGET_CONST16
)
4169 *total
= COSTS_N_INSNS (2);
4178 *total
= COSTS_N_INSNS (2);
4185 *total
= COSTS_N_INSNS (4);
4193 (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
4195 if (memory_address_p (mode
, XEXP ((x
), 0)))
4196 *total
= COSTS_N_INSNS (num_words
);
4198 *total
= COSTS_N_INSNS (2*num_words
);
4204 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
4209 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
4213 *total
= COSTS_N_INSNS (mode
== HImode
? 3 : 5);
4217 *total
= COSTS_N_INSNS (mode
== DImode
? 3 : 2);
4224 *total
= COSTS_N_INSNS (2);
4226 *total
= COSTS_N_INSNS (1);
4233 *total
= COSTS_N_INSNS (50);
4235 *total
= COSTS_N_INSNS (1);
4242 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
4243 else if (mode
== DFmode
)
4244 *total
= COSTS_N_INSNS (50);
4245 else if (mode
== DImode
)
4246 *total
= COSTS_N_INSNS (4);
4248 *total
= COSTS_N_INSNS (1);
4256 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
4257 else if (mode
== DFmode
|| mode
== DImode
)
4258 *total
= COSTS_N_INSNS (50);
4260 *total
= COSTS_N_INSNS (1);
4267 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
4268 else if (mode
== DFmode
)
4269 *total
= COSTS_N_INSNS (50);
4270 else if (mode
== DImode
)
4271 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
4272 else if (TARGET_MUL32
)
4273 *total
= COSTS_N_INSNS (4);
4274 else if (TARGET_MAC16
)
4275 *total
= COSTS_N_INSNS (16);
4276 else if (TARGET_MUL16
)
4277 *total
= COSTS_N_INSNS (12);
4279 *total
= COSTS_N_INSNS (50);
4288 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
4291 else if (mode
== DFmode
)
4293 *total
= COSTS_N_INSNS (50);
4303 *total
= COSTS_N_INSNS (speed
? 100 : 50);
4304 else if (TARGET_DIV32
)
4305 *total
= COSTS_N_INSNS (32);
4307 *total
= COSTS_N_INSNS (speed
? 100 : 50);
4313 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
4315 *total
= COSTS_N_INSNS (50);
4322 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
4327 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
4333 *total
= COSTS_N_INSNS (1);
4342 xtensa_is_insn_L32R_p (const rtx_insn
*insn
)
4344 rtx x
= PATTERN (insn
);
4346 if (GET_CODE (x
) != SET
)
4353 return (SYMBOL_REF_P (x
) || CONST_INT_P (x
))
4354 && CONSTANT_POOL_ADDRESS_P (x
);
4357 /* relaxed MOVI instructions, that will be converted to L32R by the
4360 && ! xtensa_simm12b (INTVAL (x
)))
4366 /* Compute a relative costs of RTL insns. This is necessary in order to
4367 achieve better RTL insn splitting/combination result. */
4370 xtensa_insn_cost (rtx_insn
*insn
, bool speed
)
4372 if (!(recog_memoized (insn
) < 0))
4374 int len
= get_attr_length (insn
), n
= (len
+ 2) / 3;
4377 return COSTS_N_INSNS (0);
4379 if (speed
) /* For speed cost. */
4381 /* "L32R" may be particular slow (implementation-dependent). */
4382 if (xtensa_is_insn_L32R_p (insn
))
4383 return COSTS_N_INSNS (1 + xtensa_extra_l32r_costs
);
4385 /* Cost based on the pipeline model. */
4386 switch (get_attr_type (insn
))
4394 return COSTS_N_INSNS (n
);
4397 return COSTS_N_INSNS (n
- 1 + 2);
4401 return COSTS_N_INSNS (n
- 1 + 3);
4408 return COSTS_N_INSNS (n
* 2);
4411 return COSTS_N_INSNS (n
* 4);
4414 return COSTS_N_INSNS (n
* 16);
4420 else /* For size cost. */
4422 /* Cost based on the instruction length. */
4423 if (get_attr_type (insn
) != TYPE_UNKNOWN
)
4425 /* "L32R" itself plus constant in litpool. */
4426 if (xtensa_is_insn_L32R_p (insn
))
4427 return COSTS_N_INSNS (2) + 1;
4429 /* Consider ".n" short instructions. */
4430 return COSTS_N_INSNS (n
) - (n
* 3 - len
);
4436 return pattern_cost (PATTERN (insn
), speed
);
4439 /* Worker function for TARGET_RETURN_IN_MEMORY. */
4442 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
4444 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
4445 > 4 * UNITS_PER_WORD
);
4448 /* Worker function for TARGET_FUNCTION_VALUE. */
4451 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
4454 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
4455 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
4456 ? SImode
: TYPE_MODE (valtype
),
4457 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
4460 /* Worker function for TARGET_LIBCALL_VALUE. */
4463 xtensa_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
4465 return gen_rtx_REG ((GET_MODE_CLASS (mode
) == MODE_INT
4466 && GET_MODE_SIZE (mode
) < UNITS_PER_WORD
)
4467 ? SImode
: mode
, GP_RETURN
);
4470 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
4473 xtensa_function_value_regno_p (const unsigned int regno
)
4475 return (regno
== GP_RETURN
);
4478 /* The static chain is passed in memory. Provide rtx giving 'mem'
4479 expressions that denote where they are stored. */
4482 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl_or_type
), bool incoming_p
)
4484 if (TARGET_WINDOWED_ABI
)
4486 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
4487 return gen_frame_mem (Pmode
, plus_constant (Pmode
, base
,
4488 -5 * UNITS_PER_WORD
));
4491 return gen_rtx_REG (Pmode
, A8_REG
);
4495 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
4496 instruction with a minimal stack frame in order to get some free
4497 registers. Once the actual call target is known, the proper stack frame
4498 size is extracted from the ENTRY instruction at the target and the
4499 current frame is adjusted to match. The trampoline then transfers
4500 control to the instruction following the ENTRY at the target. Note:
4501 this assumes that the target begins with an ENTRY instruction. */
4504 xtensa_asm_trampoline_template (FILE *stream
)
4506 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
4508 fprintf (stream
, "\t.begin no-transform\n");
4510 if (TARGET_WINDOWED_ABI
)
4512 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
4516 /* Save the return address. */
4517 fprintf (stream
, "\tmov\ta10, a0\n");
4519 /* Use a CALL0 instruction to skip past the constants and in the
4520 process get the PC into A0. This allows PC-relative access to
4521 the constants without relying on L32R. */
4522 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
4525 fprintf (stream
, "\tj\t.Lskipconsts\n");
4527 fprintf (stream
, "\t.align\t4\n");
4528 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
4529 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
4530 fprintf (stream
, ".Lskipconsts:\n");
4532 /* Load the static chain and function address from the trampoline. */
4535 fprintf (stream
, "\taddi\ta0, a0, 3\n");
4536 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
4537 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
4541 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
4542 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
4545 /* Store the static chain. */
4546 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
4548 /* Set the proper stack pointer value. */
4549 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
4550 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
4551 TARGET_BIG_ENDIAN
? 8 : 12);
4552 fprintf (stream
, "\tslli\ta9, a9, 3\n");
4553 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
4554 fprintf (stream
, "\tsub\ta9, sp, a9\n");
4555 fprintf (stream
, "\tmovsp\tsp, a9\n");
4558 /* Restore the return address. */
4559 fprintf (stream
, "\tmov\ta0, a10\n");
4561 /* Jump to the instruction following the ENTRY. */
4562 fprintf (stream
, "\taddi\ta8, a8, 3\n");
4563 fprintf (stream
, "\tjx\ta8\n");
4565 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4567 fprintf (stream
, "\t.byte\t0\n");
4569 fprintf (stream
, "\tnop\n");
4575 /* Save the return address. */
4576 fprintf (stream
, "\tmov\ta10, a0\n");
4578 /* Use a CALL0 instruction to skip past the constants and in the
4579 process get the PC into A0. This allows PC-relative access to
4580 the constants without relying on L32R. */
4581 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
4584 fprintf (stream
, "\tj\t.Lskipconsts\n");
4586 fprintf (stream
, "\t.align\t4\n");
4587 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
4588 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
4589 fprintf (stream
, ".Lskipconsts:\n");
4591 /* Load the static chain and function address from the trampoline. */
4594 fprintf (stream
, "\taddi\ta0, a0, 3\n");
4595 fprintf (stream
, "\tl32i\ta8, a0, 0\n");
4596 fprintf (stream
, "\tl32i\ta9, a0, 4\n");
4597 fprintf (stream
, "\tmov\ta0, a10\n");
4601 fprintf (stream
, "\tl32r\ta8, .Lchainval\n");
4602 fprintf (stream
, "\tl32r\ta9, .Lfnaddr\n");
4604 fprintf (stream
, "\tjx\ta9\n");
4606 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4608 fprintf (stream
, "\t.byte\t0\n");
4610 fprintf (stream
, "\tnop\n");
4612 fprintf (stream
, "\t.end no-transform\n");
4616 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
4618 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
4619 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
4623 if (TARGET_WINDOWED_ABI
)
4625 chain_off
= use_call0
? 12 : 8;
4626 func_off
= use_call0
? 16 : 12;
4630 chain_off
= use_call0
? 8 : 4;
4631 func_off
= use_call0
? 12 : 8;
4634 emit_block_move (m_tramp
, assemble_trampoline_template (),
4635 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4637 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
4638 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
4639 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
4640 LCT_NORMAL
, VOIDmode
, XEXP (m_tramp
, 0), Pmode
);
4643 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
4646 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
4648 return !xtensa_tls_referenced_p (x
);
4651 /* Implement TARGET_CAN_USE_DOLOOP_P. */
4654 xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
4655 unsigned int loop_depth
, bool entered_at_top
)
4657 /* Considering limitations in the hardware, only use doloop
4658 for innermost loops which must be entered from the top. */
4659 if (loop_depth
> 1 || !entered_at_top
)
4665 /* NULL if INSN insn is valid within a low-overhead loop.
4666 Otherwise return why doloop cannot be applied. */
4669 xtensa_invalid_within_doloop (const rtx_insn
*insn
)
4672 return "Function call in the loop.";
4674 if (JUMP_P (insn
) && INSN_CODE (insn
) == CODE_FOR_return
)
4675 return "Return from a call instruction in the loop.";
4680 /* Optimize LOOP. */
4683 hwloop_optimize (hwloop_info loop
)
4687 basic_block entry_bb
;
4689 rtx_insn
*insn
, *seq
, *entry_after
;
4691 if (loop
->depth
> 1)
4694 fprintf (dump_file
, ";; loop %d is not innermost\n",
4699 if (!loop
->incoming_dest
)
4702 fprintf (dump_file
, ";; loop %d has more than one entry\n",
4707 if (loop
->incoming_dest
!= loop
->head
)
4710 fprintf (dump_file
, ";; loop %d is not entered from head\n",
4715 if (loop
->has_call
|| loop
->has_asm
)
4718 fprintf (dump_file
, ";; loop %d has invalid insn\n",
4723 /* Scan all the blocks to make sure they don't use iter_reg. */
4724 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
4727 fprintf (dump_file
, ";; loop %d uses iterator\n",
4732 /* Check if start_label appears before doloop_end. */
4733 insn
= loop
->start_label
;
4734 while (insn
&& insn
!= loop
->loop_end
)
4735 insn
= NEXT_INSN (insn
);
4740 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
4745 /* Get the loop iteration register. */
4746 iter_reg
= loop
->iter_reg
;
4748 gcc_assert (REG_P (iter_reg
));
4752 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
4753 if (entry_edge
->flags
& EDGE_FALLTHRU
)
4756 if (entry_edge
== NULL
)
4759 /* Place the zero_cost_loop_start instruction before the loop. */
4760 entry_bb
= entry_edge
->src
;
4764 insn
= emit_insn (gen_zero_cost_loop_start (loop
->iter_reg
,
4770 entry_after
= BB_END (entry_bb
);
4771 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
4778 emit_insn_before (seq
, BB_HEAD (loop
->head
));
4779 seq
= emit_label_before (gen_label_rtx (), seq
);
4780 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
4781 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
4783 if (!(e
->flags
& EDGE_FALLTHRU
))
4784 redirect_edge_and_branch_force (e
, new_bb
);
4786 redirect_edge_succ (e
, new_bb
);
4789 make_edge (new_bb
, loop
->head
, 0);
4793 while (DEBUG_INSN_P (entry_after
)
4794 || (NOTE_P (entry_after
)
4795 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
))
4796 entry_after
= PREV_INSN (entry_after
);
4798 emit_insn_after (seq
, entry_after
);
4806 /* A callback for the hw-doloop pass. Called when a loop we have discovered
4807 turns out not to be optimizable; we have to split the loop_end pattern into
4808 a subtract and a test. */
4811 hwloop_fail (hwloop_info loop
)
4814 rtx_insn
*insn
= loop
->loop_end
;
4816 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
4821 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
4822 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
4823 loop
->iter_reg
, const0_rtx
,
4827 JUMP_LABEL (insn
) = loop
->start_label
;
4828 LABEL_NUSES (loop
->start_label
)++;
4829 delete_insn (loop
->loop_end
);
4832 /* A callback for the hw-doloop pass. This function examines INSN; if
4833 it is a doloop_end pattern we recognize, return the reg rtx for the
4834 loop counter. Otherwise, return NULL_RTX. */
4837 hwloop_pattern_reg (rtx_insn
*insn
)
4841 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
4844 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
4852 static struct hw_doloop_hooks xtensa_doloop_hooks
=
4859 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
4860 and tries to rewrite the RTL of these loops so that proper Xtensa
4861 hardware loops are generated. */
4864 xtensa_reorg_loops (void)
4867 reorg_loops (false, &xtensa_doloop_hooks
);
4870 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4875 /* We are freeing block_for_insn in the toplev to keep compatibility
4876 with old MDEP_REORGS that are not CFG based. Recompute it now. */
4877 compute_bb_for_insn ();
4881 /* Doloop optimization. */
4882 xtensa_reorg_loops ();
4885 /* Update register usage after having seen the compiler flags. */
4888 xtensa_conditional_register_usage (void)
4892 c_mask
= TARGET_WINDOWED_ABI
? (1 << 1) : (1 << 2);
4894 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4896 /* Set/reset conditionally defined registers from
4897 CALL_USED_REGISTERS initializer. */
4898 if (call_used_regs
[i
] > 1)
4899 call_used_regs
[i
] = !!(call_used_regs
[i
] & c_mask
);
4902 /* Remove hard FP register from the preferred reload registers set. */
4903 CLEAR_HARD_REG_BIT (reg_class_contents
[(int)RL_REGS
],
4904 HARD_FRAME_POINTER_REGNUM
);
4907 /* Map hard register number to register class */
4909 enum reg_class
xtensa_regno_to_class (int regno
)
4911 static const enum reg_class regno_to_class
[FIRST_PSEUDO_REGISTER
] =
4913 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
4914 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4915 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4916 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4917 AR_REGS
, AR_REGS
, BR_REGS
,
4918 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4919 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4920 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4921 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4925 if (regno
== HARD_FRAME_POINTER_REGNUM
)
4928 return regno_to_class
[regno
];
4931 /* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and
4932 constructors to at least a word boundary. The typical use of this
4933 macro is to increase alignment for string constants to be word
4934 aligned so that 'strcpy' calls that copy constants can be done
4937 static HOST_WIDE_INT
4938 xtensa_constant_alignment (const_tree exp
, HOST_WIDE_INT align
)
4940 if ((TREE_CODE (exp
) == STRING_CST
|| TREE_CODE (exp
) == CONSTRUCTOR
)
4942 return MAX (align
, BITS_PER_WORD
);
4947 xtensa_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4949 gcc_assert (from
== ARG_POINTER_REGNUM
|| from
== FRAME_POINTER_REGNUM
);
4951 /* If we need a frame pointer, ARG_POINTER_REGNUM and FRAME_POINTER_REGNUM
4952 can only eliminate to HARD_FRAME_POINTER_REGNUM. */
4953 return to
== HARD_FRAME_POINTER_REGNUM
4954 || (!frame_pointer_needed
&& to
== STACK_POINTER_REGNUM
);
4957 /* Implement TARGET_STARTING_FRAME_OFFSET. */
4959 static HOST_WIDE_INT
4960 xtensa_starting_frame_offset (void)
4962 if (FRAME_GROWS_DOWNWARD
)
4964 return crtl
->outgoing_args_size
;
4967 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
4969 static unsigned HOST_WIDE_INT
4970 xtensa_asan_shadow_offset (void)
4972 return HOST_WIDE_INT_UC (0x10000000);
4975 /* Implement TARGET_FUNCTION_OK_FOR_SIBCALL. */
4977 xtensa_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
, tree exp ATTRIBUTE_UNUSED
)
4979 /* Do not allow sibcalls when windowed registers ABI is in effect. */
4980 if (TARGET_WINDOWED_ABI
)
4987 xtensa_delegitimize_address (rtx op
)
4989 switch (GET_CODE (op
))
4992 return xtensa_delegitimize_address (XEXP (op
, 0));
4995 if (XINT (op
, 1) == UNSPEC_PLT
)
4996 return XVECEXP(op
, 0, 0);
5005 #include "gt-xtensa.h"