1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright (C) 2001-2017 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/>. */
23 #include "coretypes.h"
33 #include "stringpool.h"
39 #include "diagnostic-core.h"
42 #include "fold-const.h"
43 #include "stor-layout.h"
50 #include "langhooks.h"
54 #include "hw-doloop.h"
57 /* This file should be included last. */
58 #include "target-def.h"
60 /* Enumeration for all of the relational tests, so that we can build
61 arrays indexed by the test type, and not worry about the order
79 /* Array giving truth value on whether or not a given hard register
80 can support a given mode. */
81 static char xtensa_hard_regno_mode_ok_p
82 [(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
84 /* Largest block move to handle in-line. */
85 #define LARGEST_MOVE_RATIO 15
87 /* Define the structure for the machine field in struct function. */
88 struct GTY(()) machine_function
90 int accesses_prev_frame
;
94 rtx_insn
*set_frame_ptr_insn
;
95 /* Current frame size calculated by compute_frame_size. */
96 unsigned current_frame_size
;
97 /* Callee-save area size in the current frame calculated by
98 compute_frame_size. */
104 /* Vector, indexed by hard register number, which contains 1 for a
105 register that is allowable in a candidate for leaf function
108 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
110 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
116 static void xtensa_option_override (void);
117 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
118 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
, int *);
119 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
120 static rtx
gen_conditional_move (enum rtx_code
, machine_mode
, rtx
, rtx
);
121 static rtx
fixup_subreg_mem (rtx
);
122 static struct machine_function
* xtensa_init_machine_status (void);
123 static rtx
xtensa_legitimize_tls_address (rtx
);
124 static rtx
xtensa_legitimize_address (rtx
, rtx
, machine_mode
);
125 static bool xtensa_mode_dependent_address_p (const_rtx
, addr_space_t
);
126 static bool xtensa_return_in_msb (const_tree
);
127 static void printx (FILE *, signed int);
128 static rtx
xtensa_builtin_saveregs (void);
129 static bool xtensa_legitimate_address_p (machine_mode
, rtx
, bool);
130 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
131 int) ATTRIBUTE_UNUSED
;
132 static section
*xtensa_select_rtx_section (machine_mode
, rtx
,
133 unsigned HOST_WIDE_INT
);
134 static bool xtensa_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
135 static int xtensa_register_move_cost (machine_mode
, reg_class_t
,
137 static int xtensa_memory_move_cost (machine_mode
, reg_class_t
, bool);
138 static tree
xtensa_build_builtin_va_list (void);
139 static bool xtensa_return_in_memory (const_tree
, const_tree
);
140 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
142 static void xtensa_function_arg_advance (cumulative_args_t
, machine_mode
,
144 static rtx
xtensa_function_arg (cumulative_args_t
, machine_mode
,
146 static rtx
xtensa_function_incoming_arg (cumulative_args_t
,
147 machine_mode
, const_tree
, bool);
148 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
149 static rtx
xtensa_libcall_value (machine_mode
, const_rtx
);
150 static bool xtensa_function_value_regno_p (const unsigned int);
151 static unsigned int xtensa_function_arg_boundary (machine_mode
,
153 static void xtensa_init_builtins (void);
154 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
155 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
156 static void xtensa_va_start (tree
, rtx
);
157 static bool xtensa_frame_pointer_required (void);
158 static rtx
xtensa_static_chain (const_tree
, bool);
159 static void xtensa_asm_trampoline_template (FILE *);
160 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
161 static bool xtensa_output_addr_const_extra (FILE *, rtx
);
162 static bool xtensa_cannot_force_const_mem (machine_mode
, rtx
);
164 static reg_class_t
xtensa_preferred_reload_class (rtx
, reg_class_t
);
165 static reg_class_t
xtensa_preferred_output_reload_class (rtx
, reg_class_t
);
166 static reg_class_t
xtensa_secondary_reload (bool, rtx
, reg_class_t
,
168 struct secondary_reload_info
*);
170 static bool constantpool_address_p (const_rtx addr
);
171 static bool xtensa_legitimate_constant_p (machine_mode
, rtx
);
172 static void xtensa_reorg (void);
173 static bool xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
175 static const char *xtensa_invalid_within_doloop (const rtx_insn
*);
177 static bool xtensa_member_type_forces_blk (const_tree
,
180 static void xtensa_conditional_register_usage (void);
181 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode
);
185 /* These hooks specify assembly directives for creating certain kinds
186 of integer object. */
188 #undef TARGET_ASM_ALIGNED_SI_OP
189 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
191 #undef TARGET_ASM_SELECT_RTX_SECTION
192 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
194 #undef TARGET_LEGITIMIZE_ADDRESS
195 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
196 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
197 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
199 #undef TARGET_REGISTER_MOVE_COST
200 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
201 #undef TARGET_MEMORY_MOVE_COST
202 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
203 #undef TARGET_RTX_COSTS
204 #define TARGET_RTX_COSTS xtensa_rtx_costs
205 #undef TARGET_ADDRESS_COST
206 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
208 #undef TARGET_MEMBER_TYPE_FORCES_BLK
209 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
211 #undef TARGET_BUILD_BUILTIN_VA_LIST
212 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
214 #undef TARGET_EXPAND_BUILTIN_VA_START
215 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
217 #undef TARGET_PROMOTE_FUNCTION_MODE
218 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
219 #undef TARGET_PROMOTE_PROTOTYPES
220 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
222 #undef TARGET_RETURN_IN_MEMORY
223 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
224 #undef TARGET_FUNCTION_VALUE
225 #define TARGET_FUNCTION_VALUE xtensa_function_value
226 #undef TARGET_LIBCALL_VALUE
227 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
228 #undef TARGET_FUNCTION_VALUE_REGNO_P
229 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
231 #undef TARGET_SPLIT_COMPLEX_ARG
232 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
233 #undef TARGET_MUST_PASS_IN_STACK
234 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
235 #undef TARGET_FUNCTION_ARG_ADVANCE
236 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
237 #undef TARGET_FUNCTION_ARG
238 #define TARGET_FUNCTION_ARG xtensa_function_arg
239 #undef TARGET_FUNCTION_INCOMING_ARG
240 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
241 #undef TARGET_FUNCTION_ARG_BOUNDARY
242 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
244 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
245 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
246 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
247 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
249 #undef TARGET_RETURN_IN_MSB
250 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
252 #undef TARGET_INIT_BUILTINS
253 #define TARGET_INIT_BUILTINS xtensa_init_builtins
254 #undef TARGET_FOLD_BUILTIN
255 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
256 #undef TARGET_EXPAND_BUILTIN
257 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
259 #undef TARGET_PREFERRED_RELOAD_CLASS
260 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
261 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
262 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
264 #undef TARGET_SECONDARY_RELOAD
265 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
267 #undef TARGET_HAVE_TLS
268 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
270 #undef TARGET_CANNOT_FORCE_CONST_MEM
271 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
274 #define TARGET_LRA_P hook_bool_void_false
276 #undef TARGET_LEGITIMATE_ADDRESS_P
277 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
279 #undef TARGET_FRAME_POINTER_REQUIRED
280 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
282 #undef TARGET_STATIC_CHAIN
283 #define TARGET_STATIC_CHAIN xtensa_static_chain
284 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
285 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
286 #undef TARGET_TRAMPOLINE_INIT
287 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
289 #undef TARGET_OPTION_OVERRIDE
290 #define TARGET_OPTION_OVERRIDE xtensa_option_override
292 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
293 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
295 #undef TARGET_LEGITIMATE_CONSTANT_P
296 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
298 #undef TARGET_MACHINE_DEPENDENT_REORG
299 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
301 #undef TARGET_CAN_USE_DOLOOP_P
302 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
304 #undef TARGET_INVALID_WITHIN_DOLOOP
305 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
307 #undef TARGET_CONDITIONAL_REGISTER_USAGE
308 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
310 #undef TARGET_HARD_REGNO_MODE_OK
311 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
313 struct gcc_target targetm
= TARGET_INITIALIZER
;
316 /* Functions to test Xtensa immediate operand validity. */
319 xtensa_simm8 (HOST_WIDE_INT v
)
321 return v
>= -128 && v
<= 127;
326 xtensa_simm8x256 (HOST_WIDE_INT v
)
328 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
333 xtensa_simm12b (HOST_WIDE_INT v
)
335 return v
>= -2048 && v
<= 2047;
340 xtensa_uimm8 (HOST_WIDE_INT v
)
342 return v
>= 0 && v
<= 255;
347 xtensa_uimm8x2 (HOST_WIDE_INT v
)
349 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
354 xtensa_uimm8x4 (HOST_WIDE_INT v
)
356 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
361 xtensa_b4const (HOST_WIDE_INT v
)
388 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
392 return xtensa_b4const (v
);
397 xtensa_b4constu (HOST_WIDE_INT v
)
424 xtensa_mask_immediate (HOST_WIDE_INT v
)
426 #define MAX_MASK_SIZE 16
429 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
442 /* This is just like the standard true_regnum() function except that it
443 works even when reg_renumber is not initialized. */
446 xt_true_regnum (rtx x
)
448 if (GET_CODE (x
) == REG
)
451 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
452 && reg_renumber
[REGNO (x
)] >= 0)
453 return reg_renumber
[REGNO (x
)];
456 if (GET_CODE (x
) == SUBREG
)
458 int base
= xt_true_regnum (SUBREG_REG (x
));
459 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
460 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
461 GET_MODE (SUBREG_REG (x
)),
462 SUBREG_BYTE (x
), GET_MODE (x
));
469 xtensa_valid_move (machine_mode mode
, rtx
*operands
)
471 /* Either the destination or source must be a register, and the
472 MAC16 accumulator doesn't count. */
474 if (register_operand (operands
[0], mode
))
476 int dst_regnum
= xt_true_regnum (operands
[0]);
478 if (xtensa_tls_referenced_p (operands
[1]))
481 /* The stack pointer can only be assigned with a MOVSP opcode. */
482 if (dst_regnum
== STACK_POINTER_REGNUM
)
483 return !TARGET_WINDOWED_ABI
485 && register_operand (operands
[1], mode
)
486 && !ACC_REG_P (xt_true_regnum (operands
[1])));
488 if (!ACC_REG_P (dst_regnum
))
491 if (register_operand (operands
[1], mode
))
493 int src_regnum
= xt_true_regnum (operands
[1]);
494 if (!ACC_REG_P (src_regnum
))
502 smalloffset_mem_p (rtx op
)
504 if (GET_CODE (op
) == MEM
)
506 rtx addr
= XEXP (op
, 0);
507 if (GET_CODE (addr
) == REG
)
508 return BASE_REG_P (addr
, 0);
509 if (GET_CODE (addr
) == PLUS
)
511 rtx offset
= XEXP (addr
, 0);
513 if (GET_CODE (offset
) != CONST_INT
)
514 offset
= XEXP (addr
, 1);
515 if (GET_CODE (offset
) != CONST_INT
)
518 val
= INTVAL (offset
);
519 return (val
& 3) == 0 && (val
>= 0 && val
<= 60);
527 constantpool_address_p (const_rtx addr
)
529 const_rtx sym
= addr
;
531 if (GET_CODE (addr
) == CONST
)
535 /* Only handle (PLUS (SYM, OFFSET)) form. */
536 addr
= XEXP (addr
, 0);
537 if (GET_CODE (addr
) != PLUS
)
540 /* Make sure the address is word aligned. */
541 offset
= XEXP (addr
, 1);
542 if ((!CONST_INT_P (offset
))
543 || ((INTVAL (offset
) & 3) != 0))
546 sym
= XEXP (addr
, 0);
549 if ((GET_CODE (sym
) == SYMBOL_REF
)
550 && CONSTANT_POOL_ADDRESS_P (sym
))
557 constantpool_mem_p (rtx op
)
559 if (GET_CODE (op
) == SUBREG
)
560 op
= SUBREG_REG (op
);
561 if (GET_CODE (op
) == MEM
)
562 return constantpool_address_p (XEXP (op
, 0));
567 /* Return TRUE if X is a thread-local symbol. */
570 xtensa_tls_symbol_p (rtx x
)
572 if (! TARGET_HAVE_TLS
)
575 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
580 xtensa_extend_reg (rtx dst
, rtx src
)
582 rtx temp
= gen_reg_rtx (SImode
);
583 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
585 /* Generate paradoxical subregs as needed so that the modes match. */
586 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
587 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
589 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
590 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
595 xtensa_mem_offset (unsigned v
, machine_mode mode
)
600 /* Handle the worst case for block moves. See xtensa_expand_block_move
601 where we emit an optimized block move operation if the block can be
602 moved in < "move_ratio" pieces. The worst case is when the block is
603 aligned but has a size of (3 mod 4) (does this happen?) so that the
604 last piece requires a byte load/store. */
605 return (xtensa_uimm8 (v
)
606 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
609 return xtensa_uimm8 (v
);
612 return xtensa_uimm8x2 (v
);
615 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
621 return xtensa_uimm8x4 (v
);
625 /* Make normal rtx_code into something we can index from an array. */
627 static enum internal_test
628 map_test_to_internal_test (enum rtx_code test_code
)
630 enum internal_test test
= ITEST_MAX
;
635 case EQ
: test
= ITEST_EQ
; break;
636 case NE
: test
= ITEST_NE
; break;
637 case GT
: test
= ITEST_GT
; break;
638 case GE
: test
= ITEST_GE
; break;
639 case LT
: test
= ITEST_LT
; break;
640 case LE
: test
= ITEST_LE
; break;
641 case GTU
: test
= ITEST_GTU
; break;
642 case GEU
: test
= ITEST_GEU
; break;
643 case LTU
: test
= ITEST_LTU
; break;
644 case LEU
: test
= ITEST_LEU
; break;
651 /* Generate the code to compare two integer values. The return value is
652 the comparison expression. */
655 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
656 rtx cmp0
, /* first operand to compare */
657 rtx cmp1
, /* second operand to compare */
658 int *p_invert
/* whether branch needs to reverse test */)
662 enum rtx_code test_code
; /* test code to use in insn */
663 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
664 int const_add
; /* constant to add (convert LE -> LT) */
665 int reverse_regs
; /* reverse registers in test */
666 int invert_const
; /* != 0 if invert value if cmp1 is constant */
667 int invert_reg
; /* != 0 if invert value if cmp1 is register */
668 int unsignedp
; /* != 0 for unsigned comparisons. */
671 static struct cmp_info info
[ (int)ITEST_MAX
] = {
673 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
674 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
676 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
677 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
678 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
679 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
681 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
682 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
683 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
684 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
687 enum internal_test test
;
689 struct cmp_info
*p_info
;
691 test
= map_test_to_internal_test (test_code
);
692 gcc_assert (test
!= ITEST_MAX
);
694 p_info
= &info
[ (int)test
];
696 mode
= GET_MODE (cmp0
);
697 if (mode
== VOIDmode
)
698 mode
= GET_MODE (cmp1
);
700 /* Make sure we can handle any constants given to us. */
701 if (GET_CODE (cmp1
) == CONST_INT
)
703 HOST_WIDE_INT value
= INTVAL (cmp1
);
704 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
706 /* if the immediate overflows or does not fit in the immediate field,
707 spill it to a register */
709 if ((p_info
->unsignedp
?
710 (uvalue
+ p_info
->const_add
> uvalue
) :
711 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
713 cmp1
= force_reg (mode
, cmp1
);
715 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
717 cmp1
= force_reg (mode
, cmp1
);
720 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
722 cmp1
= force_reg (mode
, cmp1
);
725 /* See if we need to invert the result. */
726 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
727 ? p_info
->invert_const
728 : p_info
->invert_reg
);
730 /* Comparison to constants, may involve adding 1 to change a LT into LE.
731 Comparison between two registers, may involve switching operands. */
732 if (GET_CODE (cmp1
) == CONST_INT
)
734 if (p_info
->const_add
!= 0)
735 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
738 else if (p_info
->reverse_regs
)
745 return gen_rtx_fmt_ee (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
749 /* Generate the code to compare two float values. The return value is
750 the comparison expression. */
753 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
754 rtx cmp0
, /* first operand to compare */
755 rtx cmp1
/* second operand to compare */)
757 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
759 int reverse_regs
, invert
;
763 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
764 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
765 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
766 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
767 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
768 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
769 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
770 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
771 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
772 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
773 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
774 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
776 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
778 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
780 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
781 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
791 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
792 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
794 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
799 xtensa_expand_conditional_branch (rtx
*operands
, machine_mode mode
)
801 enum rtx_code test_code
= GET_CODE (operands
[0]);
802 rtx cmp0
= operands
[1];
803 rtx cmp1
= operands
[2];
812 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
816 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
820 if (!TARGET_HARD_FLOAT
)
821 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
,
824 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
828 /* Generate the branch. */
830 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
839 emit_jump_insn (gen_rtx_SET (pc_rtx
,
840 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
847 gen_conditional_move (enum rtx_code code
, machine_mode mode
,
854 /* Jump optimization calls get_condition() which canonicalizes
855 comparisons like (GE x <const>) to (GT x <const-1>).
856 Transform those comparisons back to GE, since that is the
857 comparison supported in Xtensa. We shouldn't have to
858 transform <LE x const> comparisons, because neither
859 xtensa_expand_conditional_branch() nor get_condition() will
862 if ((code
== GT
) && (op1
== constm1_rtx
))
867 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
869 if (boolean_operator (cmp
, VOIDmode
))
871 /* Swap the operands to make const0 second. */
872 if (op0
== const0_rtx
)
878 /* If not comparing against zero, emit a comparison (subtract). */
879 if (op1
!= const0_rtx
)
881 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
882 0, 0, OPTAB_LIB_WIDEN
);
886 else if (branch_operator (cmp
, VOIDmode
))
888 /* Swap the operands to make const0 second. */
889 if (op0
== const0_rtx
)
896 case LT
: code
= GE
; break;
897 case GE
: code
= LT
; break;
898 default: gcc_unreachable ();
902 if (op1
!= const0_rtx
)
908 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
911 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
912 return gen_float_relational (code
, op0
, op1
);
919 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
921 rtx dest
= operands
[0];
922 rtx cmp
= operands
[1];
923 machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
924 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
926 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
927 XEXP (cmp
, 0), XEXP (cmp
, 1))))
931 gen_fn
= (cmp_mode
== SImode
932 ? gen_movsfcc_internal0
933 : gen_movsfcc_internal1
);
935 gen_fn
= (cmp_mode
== SImode
936 ? gen_movsicc_internal0
937 : gen_movsicc_internal1
);
939 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
945 xtensa_expand_scc (rtx operands
[4], machine_mode cmp_mode
)
947 rtx dest
= operands
[0];
949 rtx one_tmp
, zero_tmp
;
950 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
952 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
953 operands
[2], operands
[3])))
956 one_tmp
= gen_reg_rtx (SImode
);
957 zero_tmp
= gen_reg_rtx (SImode
);
958 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
959 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
961 gen_fn
= (cmp_mode
== SImode
962 ? gen_movsicc_internal0
963 : gen_movsicc_internal1
);
964 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
969 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
970 for the output, i.e., the input operands are twice as big as MODE. */
973 xtensa_split_operand_pair (rtx operands
[4], machine_mode mode
)
975 switch (GET_CODE (operands
[1]))
978 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
979 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
983 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
984 operands
[2] = adjust_address (operands
[1], mode
, 0);
989 split_double (operands
[1], &operands
[2], &operands
[3]);
996 switch (GET_CODE (operands
[0]))
999 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
1000 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
1004 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
1005 operands
[0] = adjust_address (operands
[0], mode
, 0);
1014 /* Emit insns to move operands[1] into operands[0].
1015 Return 1 if we have written out everything that needs to be done to
1016 do the move. Otherwise, return 0 and the caller will emit the move
1020 xtensa_emit_move_sequence (rtx
*operands
, machine_mode mode
)
1022 rtx src
= operands
[1];
1024 if (CONSTANT_P (src
)
1025 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
1027 rtx dst
= operands
[0];
1029 if (xtensa_tls_referenced_p (src
))
1033 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
1035 addend
= XEXP (XEXP (src
, 0), 1);
1036 src
= XEXP (XEXP (src
, 0), 0);
1039 src
= xtensa_legitimize_tls_address (src
);
1042 src
= gen_rtx_PLUS (mode
, src
, addend
);
1043 src
= force_operand (src
, dst
);
1045 emit_move_insn (dst
, src
);
1049 if (! TARGET_AUTO_LITPOOLS
&& ! TARGET_CONST16
)
1051 src
= force_const_mem (SImode
, src
);
1055 /* PC-relative loads are always SImode, and CONST16 is only
1056 supported in the movsi pattern, so add a SUBREG for any other
1061 if (register_operand (dst
, mode
))
1063 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
1068 src
= force_reg (SImode
, src
);
1069 src
= gen_lowpart_SUBREG (mode
, src
);
1075 if (!(reload_in_progress
| reload_completed
)
1076 && !xtensa_valid_move (mode
, operands
))
1077 operands
[1] = force_reg (mode
, operands
[1]);
1079 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1081 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1082 instruction won't be recognized after reload, so we remove the
1083 subreg and adjust mem accordingly. */
1084 if (reload_in_progress
)
1086 operands
[0] = fixup_subreg_mem (operands
[0]);
1087 operands
[1] = fixup_subreg_mem (operands
[1]);
1094 fixup_subreg_mem (rtx x
)
1096 if (GET_CODE (x
) == SUBREG
1097 && GET_CODE (SUBREG_REG (x
)) == REG
1098 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1101 gen_rtx_SUBREG (GET_MODE (x
),
1102 reg_equiv_mem (REGNO (SUBREG_REG (x
))),
1104 x
= alter_subreg (&temp
, true);
1110 /* Check if an incoming argument in a7 is expected to be used soon and
1111 if OPND is a register or register pair that includes a7. If so,
1112 create a new pseudo and copy a7 into that pseudo at the very
1113 beginning of the function, followed by the special "set_frame_ptr"
1114 unspec_volatile insn. The return value is either the original
1115 operand, if it is not a7, or the new pseudo containing a copy of
1116 the incoming argument. This is necessary because the register
1117 allocator will ignore conflicts with a7 and may either assign some
1118 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1119 the incoming argument in a7. By copying the argument out of a7 as
1120 the very first thing, and then immediately following that with an
1121 unspec_volatile to keep the scheduler away, we should avoid any
1122 problems. Putting the set_frame_ptr insn at the beginning, with
1123 only the a7 copy before it, also makes it easier for the prologue
1124 expander to initialize the frame pointer after the a7 copy and to
1125 fix up the a7 copy to use the stack pointer instead of the frame
1129 xtensa_copy_incoming_a7 (rtx opnd
)
1131 rtx entry_insns
= 0;
1135 if (!cfun
->machine
->need_a7_copy
)
1138 /* This function should never be called again once a7 has been copied. */
1139 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1141 mode
= GET_MODE (opnd
);
1143 /* The operand using a7 may come in a later instruction, so just return
1144 the original operand if it doesn't use a7. */
1146 if (GET_CODE (reg
) == SUBREG
)
1148 gcc_assert (SUBREG_BYTE (reg
) == 0);
1149 reg
= SUBREG_REG (reg
);
1151 if (GET_CODE (reg
) != REG
1152 || REGNO (reg
) > A7_REG
1153 || REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) <= A7_REG
)
1156 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1157 gcc_assert (REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) - 1 == A7_REG
);
1159 cfun
->machine
->need_a7_copy
= false;
1161 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1162 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1165 tmp
= gen_reg_rtx (mode
);
1171 /* Copy the value out of A7 here but keep the first word in A6 until
1172 after the set_frame_ptr insn. Otherwise, the register allocator
1173 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1175 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1176 gen_raw_REG (SImode
, A7_REG
)));
1179 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1182 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1185 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1188 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1194 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1196 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1197 if (mode
== DFmode
|| mode
== DImode
)
1198 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1199 gen_rtx_REG (SImode
, A7_REG
- 1)));
1200 entry_insns
= get_insns ();
1203 if (cfun
->machine
->vararg_a7
)
1205 /* This is called from within builtin_saveregs, which will insert the
1206 saveregs code at the function entry, ahead of anything placed at
1207 the function entry now. Instead, save the sequence to be inserted
1208 at the beginning of the saveregs code. */
1209 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1213 /* Put entry_insns after the NOTE that starts the function. If
1214 this is inside a start_sequence, make the outer-level insn
1215 chain current, so the code is placed at the start of the
1217 push_topmost_sequence ();
1218 /* Do not use entry_of_function() here. This is called from within
1219 expand_function_start, when the CFG still holds GIMPLE. */
1220 emit_insn_after (entry_insns
, get_insns ());
1221 pop_topmost_sequence ();
1228 /* Try to expand a block move operation to a sequence of RTL move
1229 instructions. If not optimizing, or if the block size is not a
1230 constant, or if the block is too large, the expansion fails and GCC
1231 falls back to calling memcpy().
1233 operands[0] is the destination
1234 operands[1] is the source
1235 operands[2] is the length
1236 operands[3] is the alignment */
1239 xtensa_expand_block_move (rtx
*operands
)
1241 static const machine_mode mode_from_align
[] =
1243 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1246 rtx dst_mem
= operands
[0];
1247 rtx src_mem
= operands
[1];
1248 HOST_WIDE_INT bytes
, align
;
1249 int num_pieces
, move_ratio
;
1251 machine_mode mode
[2];
1260 /* If this is not a fixed size move, just call memcpy. */
1261 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1264 bytes
= INTVAL (operands
[2]);
1265 align
= INTVAL (operands
[3]);
1267 /* Anything to move? */
1271 if (align
> MOVE_MAX
)
1274 /* Decide whether to expand inline based on the optimization level. */
1277 move_ratio
= LARGEST_MOVE_RATIO
;
1278 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* Close enough anyway. */
1279 if (num_pieces
> move_ratio
)
1282 x
= XEXP (dst_mem
, 0);
1285 x
= force_reg (Pmode
, x
);
1286 dst_mem
= replace_equiv_address (dst_mem
, x
);
1289 x
= XEXP (src_mem
, 0);
1292 x
= force_reg (Pmode
, x
);
1293 src_mem
= replace_equiv_address (src_mem
, x
);
1296 active
[0] = active
[1] = false;
1307 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1308 next_amount
= MIN (next_amount
, align
);
1310 amount
[next
] = next_amount
;
1311 mode
[next
] = mode_from_align
[next_amount
];
1312 temp
[next
] = gen_reg_rtx (mode
[next
]);
1314 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1315 emit_insn (gen_rtx_SET (temp
[next
], x
));
1317 offset_ld
+= next_amount
;
1318 bytes
-= next_amount
;
1319 active
[next
] = true;
1324 active
[phase
] = false;
1326 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1327 emit_insn (gen_rtx_SET (x
, temp
[phase
]));
1329 offset_st
+= amount
[phase
];
1332 while (active
[next
]);
1339 xtensa_expand_nonlocal_goto (rtx
*operands
)
1341 rtx goto_handler
= operands
[1];
1342 rtx containing_fp
= operands
[3];
1344 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1345 is too big to generate in-line. */
1347 if (GET_CODE (containing_fp
) != REG
)
1348 containing_fp
= force_reg (Pmode
, containing_fp
);
1350 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1351 LCT_NORMAL
, VOIDmode
,
1352 containing_fp
, Pmode
,
1353 goto_handler
, Pmode
);
1357 static struct machine_function
*
1358 xtensa_init_machine_status (void)
1360 return ggc_cleared_alloc
<machine_function
> ();
1364 /* Shift VAL of mode MODE left by COUNT bits. */
1367 xtensa_expand_mask_and_shift (rtx val
, machine_mode mode
, rtx count
)
1369 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1370 NULL_RTX
, 1, OPTAB_DIRECT
);
1371 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1372 NULL_RTX
, 1, OPTAB_DIRECT
);
1376 /* Structure to hold the initial parameters for a compare_and_swap operation
1377 in HImode and QImode. */
1379 struct alignment_context
1381 rtx memsi
; /* SI aligned memory location. */
1382 rtx shift
; /* Bit offset with regard to lsb. */
1383 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1384 rtx modemaski
; /* ~modemask */
1388 /* Initialize structure AC for word access to HI and QI mode memory. */
1391 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1393 machine_mode mode
= GET_MODE (mem
);
1394 rtx byteoffset
= NULL_RTX
;
1395 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1398 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1401 /* Alignment is unknown. */
1404 /* Force the address into a register. */
1405 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1407 /* Align it to SImode. */
1408 align
= expand_simple_binop (Pmode
, AND
, addr
,
1409 GEN_INT (-GET_MODE_SIZE (SImode
)),
1410 NULL_RTX
, 1, OPTAB_DIRECT
);
1412 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1413 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1414 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1415 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1417 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1418 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1419 NULL_RTX
, 1, OPTAB_DIRECT
);
1422 /* Calculate shiftcount. */
1423 if (TARGET_BIG_ENDIAN
)
1425 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1427 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1428 NULL_RTX
, 1, OPTAB_DIRECT
);
1433 ac
->shift
= NULL_RTX
;
1435 ac
->shift
= byteoffset
;
1438 if (ac
->shift
!= NULL_RTX
)
1440 /* Shift is the byte count, but we need the bitcount. */
1441 gcc_assert (exact_log2 (BITS_PER_UNIT
) >= 0);
1442 ac
->shift
= expand_simple_binop (SImode
, ASHIFT
, ac
->shift
,
1443 GEN_INT (exact_log2 (BITS_PER_UNIT
)),
1444 NULL_RTX
, 1, OPTAB_DIRECT
);
1445 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1446 GEN_INT (GET_MODE_MASK (mode
)),
1448 NULL_RTX
, 1, OPTAB_DIRECT
);
1451 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1453 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1457 /* Expand an atomic compare and swap operation for HImode and QImode.
1458 MEM is the memory location, CMP the old value to compare MEM with
1459 and NEW_RTX the value to set if CMP == MEM. */
1462 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1464 machine_mode mode
= GET_MODE (mem
);
1465 struct alignment_context ac
;
1466 rtx tmp
, cmpv
, newv
, val
;
1467 rtx oldval
= gen_reg_rtx (SImode
);
1468 rtx res
= gen_reg_rtx (SImode
);
1469 rtx_code_label
*csloop
= gen_label_rtx ();
1470 rtx_code_label
*csend
= gen_label_rtx ();
1472 init_alignment_context (&ac
, mem
);
1474 if (ac
.shift
!= NULL_RTX
)
1476 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1477 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1480 /* Load the surrounding word into VAL with the MEM value masked out. */
1481 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1482 ac
.modemaski
, NULL_RTX
, 1,
1484 emit_label (csloop
);
1486 /* Patch CMP and NEW_RTX into VAL at correct position. */
1487 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1488 NULL_RTX
, 1, OPTAB_DIRECT
));
1489 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1490 NULL_RTX
, 1, OPTAB_DIRECT
));
1492 /* Jump to end if we're done. */
1493 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1494 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1496 /* Check for changes outside mode. */
1497 emit_move_insn (oldval
, val
);
1498 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1499 val
, 1, OPTAB_DIRECT
);
1501 emit_move_insn (val
, tmp
);
1503 /* Loop internal if so. */
1504 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1508 /* Return the correct part of the bitfield. */
1509 convert_move (target
,
1510 (ac
.shift
== NULL_RTX
? res
1511 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1512 NULL_RTX
, 1, OPTAB_DIRECT
)),
1517 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1518 the default expansion works fine for SImode). MEM is the memory location
1519 and VAL the value to play with. If AFTER is true then store the value
1520 MEM holds after the operation, if AFTER is false then store the value MEM
1521 holds before the operation. If TARGET is zero then discard that value, else
1522 store it to TARGET. */
1525 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1528 machine_mode mode
= GET_MODE (mem
);
1529 struct alignment_context ac
;
1530 rtx_code_label
*csloop
= gen_label_rtx ();
1532 rtx old
= gen_reg_rtx (SImode
);
1533 rtx new_rtx
= gen_reg_rtx (SImode
);
1534 rtx orig
= NULL_RTX
;
1536 init_alignment_context (&ac
, mem
);
1538 /* Prepare values before the compare-and-swap loop. */
1539 if (ac
.shift
!= NULL_RTX
)
1540 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1545 orig
= gen_reg_rtx (SImode
);
1546 convert_move (orig
, val
, 1);
1554 case MULT
: /* NAND */
1556 /* val = "11..1<val>11..1" */
1557 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1558 NULL_RTX
, 1, OPTAB_DIRECT
);
1565 /* Load full word. Subsequent loads are performed by S32C1I. */
1566 cmp
= force_reg (SImode
, ac
.memsi
);
1568 emit_label (csloop
);
1569 emit_move_insn (old
, cmp
);
1575 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1576 NULL_RTX
, 1, OPTAB_DIRECT
);
1577 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1578 NULL_RTX
, 1, OPTAB_DIRECT
);
1581 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1582 NULL_RTX
, 1, OPTAB_DIRECT
);
1583 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1584 new_rtx
, 1, OPTAB_DIRECT
);
1590 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
1591 new_rtx
, 1, OPTAB_DIRECT
);
1594 case MULT
: /* NAND */
1595 tmp
= expand_simple_binop (SImode
, XOR
, old
, ac
.modemask
,
1596 NULL_RTX
, 1, OPTAB_DIRECT
);
1597 tmp
= expand_simple_binop (SImode
, AND
, tmp
, val
,
1598 new_rtx
, 1, OPTAB_DIRECT
);
1606 emit_move_insn (new_rtx
, tmp
);
1607 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
1608 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
1612 tmp
= (after
? new_rtx
: cmp
);
1613 convert_move (target
,
1614 (ac
.shift
== NULL_RTX
? tmp
1615 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
1616 NULL_RTX
, 1, OPTAB_DIRECT
)),
1623 xtensa_setup_frame_addresses (void)
1625 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1626 cfun
->machine
->accesses_prev_frame
= 1;
1628 if (TARGET_WINDOWED_ABI
)
1630 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1631 LCT_NORMAL
, VOIDmode
);
1635 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1636 a comment showing where the end of the loop is. However, if there is a
1637 label or a branch at the end of the loop then we need to place a nop
1638 there. If the loop ends with a label we need the nop so that branches
1639 targeting that label will target the nop (and thus remain in the loop),
1640 instead of targeting the instruction after the loop (and thus exiting
1641 the loop). If the loop ends with a branch, we need the nop in case the
1642 branch is targeting a location inside the loop. When the branch
1643 executes it will cause the loop count to be decremented even if it is
1644 taken (because it is the last instruction in the loop), so we need to
1645 nop after the branch to prevent the loop count from being decremented
1646 when the branch is taken. */
1649 xtensa_emit_loop_end (rtx_insn
*insn
, rtx
*operands
)
1653 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1655 switch (GET_CODE (insn
))
1662 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1668 rtx body
= PATTERN (insn
);
1672 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1675 else if ((GET_CODE (body
) != USE
)
1676 && (GET_CODE (body
) != CLOBBER
))
1683 output_asm_insn ("%1_LEND:", operands
);
1688 xtensa_emit_branch (bool inverted
, bool immed
, rtx
*operands
)
1690 static char result
[64];
1694 code
= GET_CODE (operands
[3]);
1697 case EQ
: op
= inverted
? "ne" : "eq"; break;
1698 case NE
: op
= inverted
? "eq" : "ne"; break;
1699 case LT
: op
= inverted
? "ge" : "lt"; break;
1700 case GE
: op
= inverted
? "lt" : "ge"; break;
1701 case LTU
: op
= inverted
? "geu" : "ltu"; break;
1702 case GEU
: op
= inverted
? "ltu" : "geu"; break;
1703 default: gcc_unreachable ();
1708 if (INTVAL (operands
[1]) == 0)
1709 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
1710 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
1712 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1715 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1722 xtensa_emit_bit_branch (bool inverted
, bool immed
, rtx
*operands
)
1724 static char result
[64];
1727 switch (GET_CODE (operands
[3]))
1729 case EQ
: op
= inverted
? "bs" : "bc"; break;
1730 case NE
: op
= inverted
? "bc" : "bs"; break;
1731 default: gcc_unreachable ();
1736 unsigned bitnum
= INTVAL (operands
[1]) & 0x1f;
1737 operands
[1] = GEN_INT (bitnum
);
1738 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1741 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1748 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
1750 static char result
[64];
1754 code
= GET_CODE (operands
[4]);
1759 case EQ
: op
= inverted
? "t" : "f"; break;
1760 case NE
: op
= inverted
? "f" : "t"; break;
1761 default: gcc_unreachable ();
1768 case EQ
: op
= inverted
? "nez" : "eqz"; break;
1769 case NE
: op
= inverted
? "eqz" : "nez"; break;
1770 case LT
: op
= inverted
? "gez" : "ltz"; break;
1771 case GE
: op
= inverted
? "ltz" : "gez"; break;
1772 default: gcc_unreachable ();
1776 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
1777 op
, isfp
? ".s" : "", inverted
? 3 : 2);
1783 xtensa_emit_call (int callop
, rtx
*operands
)
1785 static char result
[64];
1786 rtx tgt
= operands
[callop
];
1788 if (GET_CODE (tgt
) == CONST_INT
)
1789 sprintf (result
, "call%d\t" HOST_WIDE_INT_PRINT_HEX
,
1790 WINDOW_SIZE
, INTVAL (tgt
));
1791 else if (register_operand (tgt
, VOIDmode
))
1792 sprintf (result
, "callx%d\t%%%d", WINDOW_SIZE
, callop
);
1794 sprintf (result
, "call%d\t%%%d", WINDOW_SIZE
, callop
);
1801 xtensa_legitimate_address_p (machine_mode mode
, rtx addr
, bool strict
)
1803 /* Allow constant pool addresses. */
1804 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
1805 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
1806 && ! xtensa_tls_referenced_p (addr
))
1809 while (GET_CODE (addr
) == SUBREG
)
1810 addr
= SUBREG_REG (addr
);
1812 /* Allow base registers. */
1813 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
1816 /* Check for "register + offset" addressing. */
1817 if (GET_CODE (addr
) == PLUS
)
1819 rtx xplus0
= XEXP (addr
, 0);
1820 rtx xplus1
= XEXP (addr
, 1);
1821 enum rtx_code code0
;
1822 enum rtx_code code1
;
1824 while (GET_CODE (xplus0
) == SUBREG
)
1825 xplus0
= SUBREG_REG (xplus0
);
1826 code0
= GET_CODE (xplus0
);
1828 while (GET_CODE (xplus1
) == SUBREG
)
1829 xplus1
= SUBREG_REG (xplus1
);
1830 code1
= GET_CODE (xplus1
);
1832 /* Swap operands if necessary so the register is first. */
1833 if (code0
!= REG
&& code1
== REG
)
1835 xplus0
= XEXP (addr
, 1);
1836 xplus1
= XEXP (addr
, 0);
1837 code0
= GET_CODE (xplus0
);
1838 code1
= GET_CODE (xplus1
);
1841 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
1842 && code1
== CONST_INT
1843 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
1851 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1853 static GTY(()) rtx xtensa_tls_module_base_symbol
;
1856 xtensa_tls_module_base (void)
1858 if (! xtensa_tls_module_base_symbol
)
1860 xtensa_tls_module_base_symbol
=
1861 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
1862 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
1863 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
1866 return xtensa_tls_module_base_symbol
;
1871 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
1874 rtx_insn
*call_insn
, *insns
;
1877 fn
= gen_reg_rtx (Pmode
);
1878 arg
= gen_reg_rtx (Pmode
);
1879 a_io
= gen_rtx_REG (Pmode
, WINDOW_SIZE
+ 2);
1881 emit_insn (gen_tls_func (fn
, sym
));
1882 emit_insn (gen_tls_arg (arg
, sym
));
1883 emit_move_insn (a_io
, arg
);
1884 call_insn
= emit_call_insn (gen_tls_call (a_io
, fn
, sym
, const1_rtx
));
1885 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
), a_io
);
1886 insns
= get_insns ();
1895 xtensa_legitimize_tls_address (rtx x
)
1897 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
1898 rtx dest
, tp
, ret
, modbase
, base
, addend
;
1901 dest
= gen_reg_rtx (Pmode
);
1904 case TLS_MODEL_GLOBAL_DYNAMIC
:
1905 insns
= xtensa_call_tls_desc (x
, &ret
);
1906 emit_libcall_block (insns
, dest
, ret
, x
);
1909 case TLS_MODEL_LOCAL_DYNAMIC
:
1910 base
= gen_reg_rtx (Pmode
);
1911 modbase
= xtensa_tls_module_base ();
1912 insns
= xtensa_call_tls_desc (modbase
, &ret
);
1913 emit_libcall_block (insns
, base
, ret
, modbase
);
1914 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
1915 emit_insn (gen_addsi3 (dest
, base
, addend
));
1918 case TLS_MODEL_INITIAL_EXEC
:
1919 case TLS_MODEL_LOCAL_EXEC
:
1920 tp
= gen_reg_rtx (SImode
);
1921 emit_insn (gen_get_thread_pointersi (tp
));
1922 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
1923 emit_insn (gen_addsi3 (dest
, tp
, addend
));
1935 xtensa_legitimize_address (rtx x
,
1936 rtx oldx ATTRIBUTE_UNUSED
,
1939 if (xtensa_tls_symbol_p (x
))
1940 return xtensa_legitimize_tls_address (x
);
1942 if (GET_CODE (x
) == PLUS
)
1944 rtx plus0
= XEXP (x
, 0);
1945 rtx plus1
= XEXP (x
, 1);
1947 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1949 plus0
= XEXP (x
, 1);
1950 plus1
= XEXP (x
, 0);
1953 /* Try to split up the offset to use an ADDMI instruction. */
1954 if (GET_CODE (plus0
) == REG
1955 && GET_CODE (plus1
) == CONST_INT
1956 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
1957 && !xtensa_simm8 (INTVAL (plus1
))
1958 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
1959 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
1961 rtx temp
= gen_reg_rtx (Pmode
);
1962 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
1963 emit_insn (gen_rtx_SET (temp
, gen_rtx_PLUS (Pmode
, plus0
,
1965 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
1972 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
1974 Treat constant-pool references as "mode dependent" since they can
1975 only be accessed with SImode loads. This works around a bug in the
1976 combiner where a constant pool reference is temporarily converted
1977 to an HImode load, which is then assumed to zero-extend based on
1978 our definition of LOAD_EXTEND_OP. This is wrong because the high
1979 bits of a 16-bit value in the constant pool are now sign-extended
1983 xtensa_mode_dependent_address_p (const_rtx addr
,
1984 addr_space_t as ATTRIBUTE_UNUSED
)
1986 return constantpool_address_p (addr
);
1989 /* Return TRUE if X contains any TLS symbol references. */
1992 xtensa_tls_referenced_p (rtx x
)
1994 if (! TARGET_HAVE_TLS
)
1997 subrtx_iterator::array_type array
;
1998 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
2000 const_rtx x
= *iter
;
2001 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0)
2004 /* Ignore TLS references that have already been legitimized. */
2005 if (GET_CODE (x
) == UNSPEC
)
2006 switch (XINT (x
, 1))
2010 case UNSPEC_TLS_FUNC
:
2011 case UNSPEC_TLS_ARG
:
2012 case UNSPEC_TLS_CALL
:
2013 iter
.skip_subrtxes ();
2023 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2026 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2028 return xtensa_tls_referenced_p (x
);
2032 /* Return the debugger register number to use for 'regno'. */
2035 xtensa_dbx_register_number (int regno
)
2039 if (GP_REG_P (regno
))
2041 regno
-= GP_REG_FIRST
;
2044 else if (BR_REG_P (regno
))
2046 regno
-= BR_REG_FIRST
;
2049 else if (FP_REG_P (regno
))
2051 regno
-= FP_REG_FIRST
;
2054 else if (ACC_REG_P (regno
))
2056 first
= 0x200; /* Start of Xtensa special registers. */
2057 regno
= 16; /* ACCLO is special register 16. */
2060 /* When optimizing, we sometimes get asked about pseudo-registers
2061 that don't represent hard registers. Return 0 for these. */
2065 return first
+ regno
;
2069 /* Argument support functions. */
2071 /* Initialize CUMULATIVE_ARGS for a function. */
2074 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
2077 cum
->incoming
= incoming
;
2081 /* Advance the argument to the next argument position. */
2084 xtensa_function_arg_advance (cumulative_args_t cum
, machine_mode mode
,
2085 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2090 arg_words
= &get_cumulative_args (cum
)->arg_words
;
2091 max
= MAX_ARGS_IN_REGISTERS
;
2093 words
= (((mode
!= BLKmode
)
2094 ? (int) GET_MODE_SIZE (mode
)
2095 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2097 if (*arg_words
< max
2098 && (targetm
.calls
.must_pass_in_stack (mode
, type
)
2099 || *arg_words
+ words
> max
))
2102 *arg_words
+= words
;
2106 /* Return an RTL expression containing the register for the given mode,
2107 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2108 if this is an incoming argument to the current function. */
2111 xtensa_function_arg_1 (cumulative_args_t cum_v
, machine_mode mode
,
2112 const_tree type
, bool incoming_p
)
2114 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2115 int regbase
, words
, max
;
2119 arg_words
= &cum
->arg_words
;
2120 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2121 max
= MAX_ARGS_IN_REGISTERS
;
2123 words
= (((mode
!= BLKmode
)
2124 ? (int) GET_MODE_SIZE (mode
)
2125 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2127 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
2129 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2130 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2133 if (*arg_words
+ words
> max
)
2136 regno
= regbase
+ *arg_words
;
2138 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2139 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
2141 return gen_rtx_REG (mode
, regno
);
2144 /* Implement TARGET_FUNCTION_ARG. */
2147 xtensa_function_arg (cumulative_args_t cum
, machine_mode mode
,
2148 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2150 return xtensa_function_arg_1 (cum
, mode
, type
, false);
2153 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2156 xtensa_function_incoming_arg (cumulative_args_t cum
, machine_mode mode
,
2157 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2159 return xtensa_function_arg_1 (cum
, mode
, type
, true);
2163 xtensa_function_arg_boundary (machine_mode mode
, const_tree type
)
2165 unsigned int alignment
;
2167 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2168 if (alignment
< PARM_BOUNDARY
)
2169 alignment
= PARM_BOUNDARY
;
2170 if (alignment
> STACK_BOUNDARY
)
2171 alignment
= STACK_BOUNDARY
;
2177 xtensa_return_in_msb (const_tree valtype
)
2179 return (TARGET_BIG_ENDIAN
2180 && AGGREGATE_TYPE_P (valtype
)
2181 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2186 xtensa_option_override (void)
2191 /* Use CONST16 in the absence of L32R.
2192 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa
2193 configuration in the xtensa-common.c */
2196 target_flags
|= MASK_CONST16
;
2198 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2199 error ("boolean registers required for the floating-point option");
2201 /* Set up array giving whether a given register can hold a given mode. */
2202 for (mode
= VOIDmode
;
2203 mode
!= MAX_MACHINE_MODE
;
2204 mode
= (machine_mode
) ((int) mode
+ 1))
2206 int size
= GET_MODE_SIZE (mode
);
2207 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2209 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2213 if (ACC_REG_P (regno
))
2214 temp
= (TARGET_MAC16
2215 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2216 else if (GP_REG_P (regno
))
2217 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2218 else if (FP_REG_P (regno
))
2219 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2220 else if (BR_REG_P (regno
))
2221 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2225 xtensa_hard_regno_mode_ok_p
[(int) mode
][regno
] = temp
;
2229 init_machine_status
= xtensa_init_machine_status
;
2231 /* Check PIC settings. PIC is only supported when using L32R
2232 instructions, and some targets need to always use PIC. */
2233 if (flag_pic
&& TARGET_CONST16
)
2234 error ("-f%s is not supported with CONST16 instructions",
2235 (flag_pic
> 1 ? "PIC" : "pic"));
2236 else if (TARGET_FORCE_NO_PIC
)
2238 else if (XTENSA_ALWAYS_PIC
)
2241 error ("PIC is required but not supported with CONST16 instructions");
2244 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2247 if (flag_pic
&& !flag_pie
)
2250 /* Hot/cold partitioning does not work on this architecture, because of
2251 constant pools (the load instruction cannot necessarily reach that far).
2252 Therefore disable it on this architecture. */
2253 if (flag_reorder_blocks_and_partition
)
2255 flag_reorder_blocks_and_partition
= 0;
2256 flag_reorder_blocks
= 1;
2260 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2263 xtensa_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
2265 return xtensa_hard_regno_mode_ok_p
[mode
][regno
];
2268 /* A C compound statement to output to stdio stream STREAM the
2269 assembler syntax for an instruction operand X. X is an RTL
2272 CODE is a value that can be used to specify one of several ways
2273 of printing the operand. It is used when identical operands
2274 must be printed differently depending on the context. CODE
2275 comes from the '%' specification that was used to request
2276 printing of the operand. If the specification was just '%DIGIT'
2277 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2278 is the ASCII code for LTR.
2280 If X is a register, this macro should print the register's name.
2281 The names can be found in an array 'reg_names' whose type is
2282 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2284 When the machine description has a specification '%PUNCT' (a '%'
2285 followed by a punctuation character), this macro is called with
2286 a null pointer for X and the punctuation character for CODE.
2288 'a', 'c', 'l', and 'n' are reserved.
2290 The Xtensa specific codes are:
2292 'd' CONST_INT, print as signed decimal
2293 'x' CONST_INT, print as signed hexadecimal
2294 'K' CONST_INT, print number of bits in mask for EXTUI
2295 'R' CONST_INT, print (X & 0x1f)
2296 'L' CONST_INT, print ((32 - X) & 0x1f)
2297 'D' REG, print second register of double-word register operand
2298 'N' MEM, print address of next word following a memory operand
2299 'v' MEM, if memory reference is volatile, output a MEMW before it
2300 't' any constant, add "@h" suffix for top 16 bits
2301 'b' any constant, add "@l" suffix for bottom 16 bits
2305 printx (FILE *file
, signed int val
)
2307 /* Print a hexadecimal value in a nice way. */
2308 if ((val
> -0xa) && (val
< 0xa))
2309 fprintf (file
, "%d", val
);
2311 fprintf (file
, "-0x%x", -val
);
2313 fprintf (file
, "0x%x", val
);
2318 print_operand (FILE *file
, rtx x
, int letter
)
2321 error ("PRINT_OPERAND null pointer");
2326 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2327 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2329 output_operand_lossage ("invalid %%D value");
2333 if (GET_CODE (x
) == MEM
)
2335 /* For a volatile memory reference, emit a MEMW before the
2337 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2338 fprintf (file
, "memw\n\t");
2341 output_operand_lossage ("invalid %%v value");
2345 if (GET_CODE (x
) == MEM
2346 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2348 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? E_SFmode
: E_SImode
,
2350 output_address (GET_MODE (x
), XEXP (x
, 0));
2353 output_operand_lossage ("invalid %%N value");
2357 if (GET_CODE (x
) == CONST_INT
)
2360 unsigned val
= INTVAL (x
);
2366 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2367 fatal_insn ("invalid mask", x
);
2369 fprintf (file
, "%d", num_bits
);
2372 output_operand_lossage ("invalid %%K value");
2376 if (GET_CODE (x
) == CONST_INT
)
2377 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, (32 - INTVAL (x
)) & 0x1f);
2379 output_operand_lossage ("invalid %%L value");
2383 if (GET_CODE (x
) == CONST_INT
)
2384 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) & 0x1f);
2386 output_operand_lossage ("invalid %%R value");
2390 if (GET_CODE (x
) == CONST_INT
)
2391 printx (file
, INTVAL (x
));
2393 output_operand_lossage ("invalid %%x value");
2397 if (GET_CODE (x
) == CONST_INT
)
2398 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2400 output_operand_lossage ("invalid %%d value");
2405 if (GET_CODE (x
) == CONST_INT
)
2407 printx (file
, INTVAL (x
));
2408 fputs (letter
== 't' ? "@h" : "@l", file
);
2410 else if (GET_CODE (x
) == CONST_DOUBLE
)
2412 if (GET_MODE (x
) == SFmode
)
2415 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2416 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2419 output_operand_lossage ("invalid %%t/%%b value");
2421 else if (GET_CODE (x
) == CONST
)
2423 /* X must be a symbolic constant on ELF. Write an expression
2424 suitable for 'const16' that sets the high or low 16 bits. */
2425 if (GET_CODE (XEXP (x
, 0)) != PLUS
2426 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2427 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2428 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2429 output_operand_lossage ("invalid %%t/%%b value");
2430 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2431 fputs (letter
== 't' ? "@h" : "@l", file
);
2432 /* There must be a non-alphanumeric character between 'h' or 'l'
2433 and the number. The '-' is added by print_operand() already. */
2434 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2436 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2440 output_addr_const (file
, x
);
2441 fputs (letter
== 't' ? "@h" : "@l", file
);
2446 if (GET_CODE (x
) == CONST_DOUBLE
&&
2447 GET_MODE (x
) == SFmode
)
2450 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2451 fprintf (file
, "0x%08lx", l
);
2458 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2459 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2460 else if (GET_CODE (x
) == MEM
)
2461 output_address (GET_MODE (x
), XEXP (x
, 0));
2462 else if (GET_CODE (x
) == CONST_INT
)
2463 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
2465 output_addr_const (file
, x
);
2470 /* A C compound statement to output to stdio stream STREAM the
2471 assembler syntax for an instruction operand that is a memory
2472 reference whose address is ADDR. ADDR is an RTL expression. */
2475 print_operand_address (FILE *file
, rtx addr
)
2478 error ("PRINT_OPERAND_ADDRESS, null pointer");
2480 switch (GET_CODE (addr
))
2483 fatal_insn ("invalid address", addr
);
2487 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2493 rtx offset
= (rtx
)0;
2494 rtx arg0
= XEXP (addr
, 0);
2495 rtx arg1
= XEXP (addr
, 1);
2497 if (GET_CODE (arg0
) == REG
)
2502 else if (GET_CODE (arg1
) == REG
)
2508 fatal_insn ("no register in address", addr
);
2510 if (CONSTANT_P (offset
))
2512 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2513 output_addr_const (file
, offset
);
2516 fatal_insn ("address offset not a constant", addr
);
2524 output_addr_const (file
, addr
);
2529 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2532 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2534 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2536 switch (XINT (x
, 1))
2539 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2540 fputs ("@TPOFF", fp
);
2543 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2544 fputs ("@DTPOFF", fp
);
2549 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2562 xtensa_output_integer_literal_parts (FILE *file
, rtx x
, int size
)
2564 if (size
> 4 && !(size
& (size
- 1)))
2568 split_double (x
, &first
, &second
);
2569 xtensa_output_integer_literal_parts (file
, first
, size
/ 2);
2571 xtensa_output_integer_literal_parts (file
, second
, size
/ 2);
2575 output_addr_const (file
, x
);
2584 xtensa_output_literal (FILE *file
, rtx x
, machine_mode mode
, int labelno
)
2588 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2590 switch (GET_MODE_CLASS (mode
))
2593 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
2598 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
),
2600 if (HOST_BITS_PER_LONG
> 32)
2601 value_long
[0] &= 0xffffffff;
2602 fprintf (file
, "0x%08lx\n", value_long
[0]);
2606 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x
),
2608 if (HOST_BITS_PER_LONG
> 32)
2610 value_long
[0] &= 0xffffffff;
2611 value_long
[1] &= 0xffffffff;
2613 fprintf (file
, "0x%08lx, 0x%08lx\n",
2614 value_long
[0], value_long
[1]);
2624 case MODE_PARTIAL_INT
:
2625 xtensa_output_integer_literal_parts (file
, x
, GET_MODE_SIZE (mode
));
2635 xtensa_call_save_reg(int regno
)
2637 if (TARGET_WINDOWED_ABI
)
2640 if (regno
== A0_REG
)
2641 return crtl
->profile
|| !crtl
->is_leaf
|| crtl
->calls_eh_return
||
2642 df_regs_ever_live_p (regno
);
2644 if (crtl
->calls_eh_return
&& regno
>= 2 && regno
< 4)
2647 return !fixed_regs
[regno
] && !call_used_regs
[regno
] &&
2648 df_regs_ever_live_p (regno
);
2651 /* Return the bytes needed to compute the frame pointer from the current
2654 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2655 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2658 compute_frame_size (int size
)
2662 if (reload_completed
&& cfun
->machine
->frame_laid_out
)
2663 return cfun
->machine
->current_frame_size
;
2665 /* Add space for the incoming static chain value. */
2666 if (cfun
->static_chain_decl
!= NULL
)
2667 size
+= (1 * UNITS_PER_WORD
);
2669 cfun
->machine
->callee_save_size
= 0;
2670 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2672 if (xtensa_call_save_reg(regno
))
2673 cfun
->machine
->callee_save_size
+= UNITS_PER_WORD
;
2676 cfun
->machine
->current_frame_size
=
2677 XTENSA_STACK_ALIGN (size
2678 + cfun
->machine
->callee_save_size
2679 + crtl
->outgoing_args_size
2680 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2681 cfun
->machine
->callee_save_size
=
2682 XTENSA_STACK_ALIGN (cfun
->machine
->callee_save_size
);
2683 cfun
->machine
->frame_laid_out
= true;
2684 return cfun
->machine
->current_frame_size
;
2689 xtensa_frame_pointer_required (void)
2691 /* The code to expand builtin_frame_addr and builtin_return_addr
2692 currently uses the hard_frame_pointer instead of frame_pointer.
2693 This seems wrong but maybe it's necessary for other architectures.
2694 This function is derived from the i386 code. */
2696 if (cfun
->machine
->accesses_prev_frame
)
2703 xtensa_initial_elimination_offset (int from
, int to ATTRIBUTE_UNUSED
)
2705 long frame_size
= compute_frame_size (get_frame_size ());
2706 HOST_WIDE_INT offset
;
2710 case FRAME_POINTER_REGNUM
:
2711 if (FRAME_GROWS_DOWNWARD
)
2712 offset
= frame_size
- (WINDOW_SIZE
* UNITS_PER_WORD
)
2713 - cfun
->machine
->callee_save_size
;
2717 case ARG_POINTER_REGNUM
:
2718 offset
= frame_size
;
2727 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2728 and the total number of words must be a multiple of 128 bits. */
2729 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2732 xtensa_expand_prologue (void)
2734 HOST_WIDE_INT total_size
;
2735 rtx_insn
*insn
= NULL
;
2739 total_size
= compute_frame_size (get_frame_size ());
2741 if (flag_stack_usage_info
)
2742 current_function_static_stack_size
= total_size
;
2744 if (TARGET_WINDOWED_ABI
)
2746 if (total_size
< (1 << (12+3)))
2747 insn
= emit_insn (gen_entry (GEN_INT (total_size
)));
2750 /* Use a8 as a temporary since a0-a7 may be live. */
2751 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2752 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
2753 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2754 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2755 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
2761 HOST_WIDE_INT offset
= 0;
2762 int callee_save_size
= cfun
->machine
->callee_save_size
;
2764 /* -128 is a limit of single addi instruction. */
2765 if (total_size
> 0 && total_size
<= 128)
2767 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2768 GEN_INT (-total_size
)));
2769 RTX_FRAME_RELATED_P (insn
) = 1;
2770 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2771 plus_constant (Pmode
, stack_pointer_rtx
,
2773 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2774 offset
= total_size
- UNITS_PER_WORD
;
2776 else if (callee_save_size
)
2778 /* 1020 is maximal s32i offset, if the frame is bigger than that
2779 * we move sp to the end of callee-saved save area, save and then
2780 * move it to its final location. */
2781 if (total_size
> 1024)
2783 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2784 GEN_INT (-callee_save_size
)));
2785 RTX_FRAME_RELATED_P (insn
) = 1;
2786 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2787 plus_constant (Pmode
, stack_pointer_rtx
,
2788 -callee_save_size
));
2789 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2790 offset
= callee_save_size
- UNITS_PER_WORD
;
2794 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2795 emit_move_insn (tmp_reg
, GEN_INT (total_size
));
2796 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2797 stack_pointer_rtx
, tmp_reg
));
2798 RTX_FRAME_RELATED_P (insn
) = 1;
2799 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2800 plus_constant (Pmode
, stack_pointer_rtx
,
2802 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2803 offset
= total_size
- UNITS_PER_WORD
;
2807 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2809 if (xtensa_call_save_reg(regno
))
2811 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2812 rtx mem
= gen_frame_mem (SImode
, x
);
2813 rtx reg
= gen_rtx_REG (SImode
, regno
);
2815 offset
-= UNITS_PER_WORD
;
2816 insn
= emit_move_insn (mem
, reg
);
2817 RTX_FRAME_RELATED_P (insn
) = 1;
2818 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
2819 gen_rtx_SET (mem
, reg
));
2822 if (total_size
> 1024)
2824 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2825 emit_move_insn (tmp_reg
, GEN_INT (total_size
-
2827 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2828 stack_pointer_rtx
, tmp_reg
));
2829 RTX_FRAME_RELATED_P (insn
) = 1;
2830 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2831 plus_constant (Pmode
, stack_pointer_rtx
,
2834 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2838 if (frame_pointer_needed
)
2840 if (cfun
->machine
->set_frame_ptr_insn
)
2844 push_topmost_sequence ();
2845 first
= get_insns ();
2846 pop_topmost_sequence ();
2848 /* For all instructions prior to set_frame_ptr_insn, replace
2849 hard_frame_pointer references with stack_pointer. */
2851 insn
!= cfun
->machine
->set_frame_ptr_insn
;
2852 insn
= NEXT_INSN (insn
))
2856 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2857 hard_frame_pointer_rtx
,
2859 df_insn_rescan (insn
);
2865 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2866 stack_pointer_rtx
));
2867 if (!TARGET_WINDOWED_ABI
)
2869 note_rtx
= gen_rtx_SET (hard_frame_pointer_rtx
,
2871 RTX_FRAME_RELATED_P (insn
) = 1;
2872 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2877 if (TARGET_WINDOWED_ABI
)
2879 /* Create a note to describe the CFA. Because this is only used to set
2880 DW_AT_frame_base for debug info, don't bother tracking changes through
2881 each instruction in the prologue. It just takes up space. */
2882 note_rtx
= gen_rtx_SET ((frame_pointer_needed
2883 ? hard_frame_pointer_rtx
2884 : stack_pointer_rtx
),
2885 plus_constant (Pmode
, stack_pointer_rtx
,
2887 RTX_FRAME_RELATED_P (insn
) = 1;
2888 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2893 xtensa_expand_epilogue (void)
2895 if (!TARGET_WINDOWED_ABI
)
2898 HOST_WIDE_INT offset
;
2900 if (cfun
->machine
->current_frame_size
> (frame_pointer_needed
? 127 : 1024))
2902 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2903 emit_move_insn (tmp_reg
, GEN_INT (cfun
->machine
->current_frame_size
-
2904 cfun
->machine
->callee_save_size
));
2905 emit_insn (gen_addsi3 (stack_pointer_rtx
, frame_pointer_needed
?
2906 hard_frame_pointer_rtx
: stack_pointer_rtx
,
2908 offset
= cfun
->machine
->callee_save_size
- UNITS_PER_WORD
;
2912 if (frame_pointer_needed
)
2913 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
2914 offset
= cfun
->machine
->current_frame_size
- UNITS_PER_WORD
;
2917 /* Prevent reordering of saved a0 update and loading it back from
2919 if (crtl
->calls_eh_return
)
2920 emit_insn (gen_blockage ());
2922 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2924 if (xtensa_call_save_reg(regno
))
2926 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2928 offset
-= UNITS_PER_WORD
;
2929 emit_move_insn (gen_rtx_REG (SImode
, regno
),
2930 gen_frame_mem (SImode
, x
));
2934 if (cfun
->machine
->current_frame_size
> 0)
2936 if (frame_pointer_needed
|| /* always reachable with addi */
2937 cfun
->machine
->current_frame_size
> 1024 ||
2938 cfun
->machine
->current_frame_size
<= 127)
2940 if (cfun
->machine
->current_frame_size
<= 127)
2941 offset
= cfun
->machine
->current_frame_size
;
2943 offset
= cfun
->machine
->callee_save_size
;
2945 emit_insn (gen_addsi3 (stack_pointer_rtx
,
2951 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2952 emit_move_insn (tmp_reg
,
2953 GEN_INT (cfun
->machine
->current_frame_size
));
2954 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2959 if (crtl
->calls_eh_return
)
2960 emit_insn (gen_add3_insn (stack_pointer_rtx
,
2962 EH_RETURN_STACKADJ_RTX
));
2964 cfun
->machine
->epilogue_done
= true;
2965 emit_jump_insn (gen_return ());
2969 xtensa_use_return_instruction_p (void)
2971 if (!reload_completed
)
2973 if (TARGET_WINDOWED_ABI
)
2975 if (compute_frame_size (get_frame_size ()) == 0)
2977 return cfun
->machine
->epilogue_done
;
2981 xtensa_set_return_address (rtx address
, rtx scratch
)
2983 HOST_WIDE_INT total_size
= compute_frame_size (get_frame_size ());
2984 rtx frame
= frame_pointer_needed
?
2985 hard_frame_pointer_rtx
: stack_pointer_rtx
;
2986 rtx a0_addr
= plus_constant (Pmode
, frame
,
2987 total_size
- UNITS_PER_WORD
);
2988 rtx note
= gen_rtx_SET (gen_frame_mem (SImode
, a0_addr
),
2989 gen_rtx_REG (SImode
, A0_REG
));
2992 if (total_size
> 1024) {
2993 emit_move_insn (scratch
, GEN_INT (total_size
- UNITS_PER_WORD
));
2994 emit_insn (gen_addsi3 (scratch
, frame
, scratch
));
2998 insn
= emit_move_insn (gen_frame_mem (SImode
, a0_addr
), address
);
2999 RTX_FRAME_RELATED_P (insn
) = 1;
3000 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
3004 xtensa_return_addr (int count
, rtx frame
)
3006 rtx result
, retaddr
, curaddr
, label
;
3008 if (!TARGET_WINDOWED_ABI
)
3013 return get_hard_reg_initial_val (Pmode
, A0_REG
);
3017 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
3020 rtx addr
= plus_constant (Pmode
, frame
, -4 * UNITS_PER_WORD
);
3021 addr
= memory_address (Pmode
, addr
);
3022 retaddr
= gen_reg_rtx (Pmode
);
3023 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
3026 /* The 2 most-significant bits of the return address on Xtensa hold
3027 the register window size. To get the real return address, these
3028 bits must be replaced with the high bits from some address in the
3031 /* Get the 2 high bits of a local label in the code. */
3032 curaddr
= gen_reg_rtx (Pmode
);
3033 label
= gen_label_rtx ();
3035 LABEL_PRESERVE_P (label
) = 1;
3036 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
3037 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
3038 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
3040 /* Clear the 2 high bits of the return address. */
3041 result
= gen_reg_rtx (Pmode
);
3042 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
3043 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
3045 /* Combine them to get the result. */
3046 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
3050 /* Disable the use of word-sized or smaller complex modes for structures,
3051 and for function arguments in particular, where they cause problems with
3052 register a7. The xtensa_copy_incoming_a7 function assumes that there is
3053 a single reference to an argument in a7, but with small complex modes the
3054 real and imaginary components may be extracted separately, leading to two
3055 uses of the register, only one of which would be replaced. */
3058 xtensa_member_type_forces_blk (const_tree
, machine_mode mode
)
3060 return mode
== CQImode
|| mode
== CHImode
;
3063 /* Create the va_list data type.
3065 This structure is set up by __builtin_saveregs. The __va_reg field
3066 points to a stack-allocated region holding the contents of the
3067 incoming argument registers. The __va_ndx field is an index
3068 initialized to the position of the first unnamed (variable)
3069 argument. This same index is also used to address the arguments
3070 passed in memory. Thus, the __va_stk field is initialized to point
3071 to the position of the first argument in memory offset to account
3072 for the arguments passed in registers and to account for the size
3073 of the argument registers not being 16-byte aligned. E.G., there
3074 are 6 argument registers of 4 bytes each, but we want the __va_ndx
3075 for the first stack argument to have the maximal alignment of 16
3076 bytes, so we offset the __va_stk address by 32 bytes so that
3077 __va_stk[32] references the first argument on the stack. */
3080 xtensa_build_builtin_va_list (void)
3082 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
3084 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
3085 type_decl
= build_decl (BUILTINS_LOCATION
,
3086 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
3088 f_stk
= build_decl (BUILTINS_LOCATION
,
3089 FIELD_DECL
, get_identifier ("__va_stk"),
3091 f_reg
= build_decl (BUILTINS_LOCATION
,
3092 FIELD_DECL
, get_identifier ("__va_reg"),
3094 f_ndx
= build_decl (BUILTINS_LOCATION
,
3095 FIELD_DECL
, get_identifier ("__va_ndx"),
3098 DECL_FIELD_CONTEXT (f_stk
) = record
;
3099 DECL_FIELD_CONTEXT (f_reg
) = record
;
3100 DECL_FIELD_CONTEXT (f_ndx
) = record
;
3102 TYPE_STUB_DECL (record
) = type_decl
;
3103 TYPE_NAME (record
) = type_decl
;
3104 TYPE_FIELDS (record
) = f_stk
;
3105 DECL_CHAIN (f_stk
) = f_reg
;
3106 DECL_CHAIN (f_reg
) = f_ndx
;
3108 layout_type (record
);
3113 /* Save the incoming argument registers on the stack. Returns the
3114 address of the saved registers. */
3117 xtensa_builtin_saveregs (void)
3120 int arg_words
= crtl
->args
.info
.arg_words
;
3121 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
3126 /* Allocate the general-purpose register space. */
3127 gp_regs
= assign_stack_local
3128 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
3129 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
3131 /* Now store the incoming registers. */
3132 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
3133 cfun
->machine
->vararg_a7
= true;
3134 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
3135 adjust_address (gp_regs
, BLKmode
,
3136 arg_words
* UNITS_PER_WORD
),
3138 if (cfun
->machine
->vararg_a7_copy
!= 0)
3139 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
3141 return XEXP (gp_regs
, 0);
3145 /* Implement `va_start' for varargs and stdarg. We look at the
3146 current function to fill in an initial va_list. */
3149 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
3157 arg_words
= crtl
->args
.info
.arg_words
;
3159 f_stk
= TYPE_FIELDS (va_list_type_node
);
3160 f_reg
= DECL_CHAIN (f_stk
);
3161 f_ndx
= DECL_CHAIN (f_reg
);
3163 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
3164 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3166 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3169 /* Call __builtin_saveregs; save the result in __va_reg */
3170 u
= make_tree (sizetype
, expand_builtin_saveregs ());
3171 u
= fold_convert (ptr_type_node
, u
);
3172 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
3173 TREE_SIDE_EFFECTS (t
) = 1;
3174 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3176 /* Set the __va_stk member to ($arg_ptr - 32). */
3177 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
3178 u
= fold_build_pointer_plus_hwi (u
, -32);
3179 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
3180 TREE_SIDE_EFFECTS (t
) = 1;
3181 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3183 /* Set the __va_ndx member. If the first variable argument is on
3184 the stack, adjust __va_ndx by 2 words to account for the extra
3185 alignment offset for __va_stk. */
3186 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
3188 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
3189 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
3190 TREE_SIDE_EFFECTS (t
) = 1;
3191 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3195 /* Implement `va_arg'. */
3198 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
3199 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
3204 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
3205 tree lab_false
, lab_over
, lab_false2
;
3208 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
3210 type
= build_pointer_type (type
);
3212 /* Handle complex values as separate real and imaginary parts. */
3213 if (TREE_CODE (type
) == COMPLEX_TYPE
)
3215 tree real_part
, imag_part
;
3217 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
3219 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
3221 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
3224 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
3226 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
3229 f_stk
= TYPE_FIELDS (va_list_type_node
);
3230 f_reg
= DECL_CHAIN (f_stk
);
3231 f_ndx
= DECL_CHAIN (f_reg
);
3233 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
3235 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3237 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3240 type_size
= size_in_bytes (type
);
3241 va_size
= round_up (type_size
, UNITS_PER_WORD
);
3242 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
3245 /* First align __va_ndx if necessary for this arg:
3247 orig_ndx = (AP).__va_ndx;
3248 if (__alignof__ (TYPE) > 4 )
3249 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3250 & -__alignof__ (TYPE)); */
3252 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
3254 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
3256 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
3258 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
3259 build_int_cst (integer_type_node
, align
- 1));
3260 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
3261 build_int_cst (integer_type_node
, -align
));
3262 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
3266 /* Increment __va_ndx to point past the argument:
3268 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3270 t
= fold_convert (integer_type_node
, va_size
);
3271 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
3272 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3275 /* Check if the argument is in registers:
3277 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3278 && !must_pass_in_stack (type))
3279 __array = (AP).__va_reg; */
3281 array
= create_tmp_var (ptr_type_node
);
3284 if (!targetm
.calls
.must_pass_in_stack (TYPE_MODE (type
), type
))
3286 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
3287 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
3289 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
3290 build_int_cst (integer_type_node
,
3291 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3292 t
= build3 (COND_EXPR
, void_type_node
, t
,
3293 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
3295 gimplify_and_add (t
, pre_p
);
3297 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
3299 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
3300 gimplify_and_add (t
, pre_p
);
3302 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
3303 gimplify_and_add (t
, pre_p
);
3307 /* ...otherwise, the argument is on the stack (never split between
3308 registers and the stack -- change __va_ndx if necessary):
3312 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3313 (AP).__va_ndx = 32 + __va_size (TYPE);
3314 __array = (AP).__va_stk;
3317 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
3319 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
3320 build_int_cst (integer_type_node
,
3321 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3322 t
= build3 (COND_EXPR
, void_type_node
, t
,
3323 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
3325 gimplify_and_add (t
, pre_p
);
3327 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
3328 t
= fold_convert (integer_type_node
, t
);
3329 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3331 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
3332 gimplify_and_add (t
, pre_p
);
3334 gimplify_assign (array
, stk
, pre_p
);
3338 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
3339 gimplify_and_add (t
, pre_p
);
3343 /* Given the base array pointer (__array) and index to the subsequent
3344 argument (__va_ndx), find the address:
3346 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3350 The results are endian-dependent because values smaller than one word
3351 are aligned differently. */
3354 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
3356 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
3357 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
3358 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
3359 unshare_expr (type_size
));
3363 size
= unshare_expr (va_size
);
3365 t
= fold_convert (sizetype
, unshare_expr (ndx
));
3366 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
3367 addr
= fold_build_pointer_plus (unshare_expr (array
), t
);
3369 addr
= fold_convert (build_pointer_type (type
), addr
);
3371 addr
= build_va_arg_indirect_ref (addr
);
3372 return build_va_arg_indirect_ref (addr
);
3380 XTENSA_BUILTIN_UMULSIDI3
,
3386 xtensa_init_builtins (void)
3390 ftype
= build_function_type_list (unsigned_intDI_type_node
,
3391 unsigned_intSI_type_node
,
3392 unsigned_intSI_type_node
, NULL_TREE
);
3394 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
3395 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
3396 "__umulsidi3", NULL_TREE
);
3397 TREE_NOTHROW (decl
) = 1;
3398 TREE_READONLY (decl
) = 1;
3403 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3404 bool ignore ATTRIBUTE_UNUSED
)
3406 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3411 case XTENSA_BUILTIN_UMULSIDI3
:
3414 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3415 || TARGET_MUL32_HIGH
)
3416 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3417 fold_convert (unsigned_intDI_type_node
, arg0
),
3418 fold_convert (unsigned_intDI_type_node
, arg1
));
3422 internal_error ("bad builtin code");
3431 xtensa_expand_builtin (tree exp
, rtx target
,
3432 rtx subtarget ATTRIBUTE_UNUSED
,
3433 machine_mode mode ATTRIBUTE_UNUSED
,
3436 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3437 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3441 case XTENSA_BUILTIN_UMULSIDI3
:
3442 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3443 __umulsidi3 function when the Xtensa configuration can directly
3444 implement it. If not, just call the function. */
3445 return expand_call (exp
, target
, ignore
);
3448 internal_error ("bad builtin code");
3453 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3456 xtensa_preferred_reload_class (rtx x
, reg_class_t rclass
)
3458 if (CONSTANT_P (x
) && CONST_DOUBLE_P (x
))
3461 /* Don't use the stack pointer or hard frame pointer for reloads!
3462 The hard frame pointer would normally be OK except that it may
3463 briefly hold an incoming argument in the prologue, and reload
3464 won't know that it is live because the hard frame pointer is
3465 treated specially. */
3467 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3473 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3476 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED
,
3479 /* Don't use the stack pointer or hard frame pointer for reloads!
3480 The hard frame pointer would normally be OK except that it may
3481 briefly hold an incoming argument in the prologue, and reload
3482 won't know that it is live because the hard frame pointer is
3483 treated specially. */
3485 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3491 /* Worker function for TARGET_SECONDARY_RELOAD. */
3494 xtensa_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass
,
3495 machine_mode mode
, secondary_reload_info
*sri
)
3499 if (in_p
&& constantpool_mem_p (x
))
3501 if (rclass
== FP_REGS
)
3505 sri
->icode
= CODE_FOR_reloadqi_literal
;
3506 else if (mode
== HImode
)
3507 sri
->icode
= CODE_FOR_reloadhi_literal
;
3510 regno
= xt_true_regnum (x
);
3511 if (ACC_REG_P (regno
))
3512 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3513 if (rclass
== ACC_REG
)
3514 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3521 order_regs_for_local_alloc (void)
3523 if (!leaf_function_p ())
3525 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
3527 static const int reg_nonleaf_alloc_order_call0
[FIRST_PSEUDO_REGISTER
] =
3529 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
3531 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
3536 memcpy (reg_alloc_order
, TARGET_WINDOWED_ABI
?
3537 reg_nonleaf_alloc_order
: reg_nonleaf_alloc_order_call0
,
3538 FIRST_PSEUDO_REGISTER
* sizeof (int));
3542 int i
, num_arg_regs
;
3545 /* Use the AR registers in increasing order (skipping a0 and a1)
3546 but save the incoming argument registers for a last resort. */
3547 num_arg_regs
= crtl
->args
.info
.arg_words
;
3548 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
3549 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
3550 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
3551 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
3552 for (i
= 0; i
< num_arg_regs
; i
++)
3553 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
3555 /* List the coprocessor registers in order. */
3556 for (i
= 0; i
< BR_REG_NUM
; i
++)
3557 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
3559 /* List the FP registers in order for now. */
3560 for (i
= 0; i
< 16; i
++)
3561 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
3563 /* GCC requires that we list *all* the registers.... */
3564 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
3565 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
3566 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
3567 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
3569 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
3574 /* Some Xtensa targets support multiple bss sections. If the section
3575 name ends with ".bss", add SECTION_BSS to the flags. */
3578 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
3580 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
3583 suffix
= strrchr (name
, '.');
3584 if (suffix
&& strcmp (suffix
, ".bss") == 0)
3586 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
3587 && DECL_INITIAL (decl
) == NULL_TREE
))
3588 flags
|= SECTION_BSS
; /* @nobits */
3590 warning (0, "only uninitialized variables can be placed in a "
3598 /* The literal pool stays with the function. */
3601 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED
,
3602 rtx x ATTRIBUTE_UNUSED
,
3603 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
3605 return function_section (current_function_decl
);
3608 /* Worker function for TARGET_REGISTER_MOVE_COST. */
3611 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3612 reg_class_t from
, reg_class_t to
)
3614 if (from
== to
&& from
!= BR_REGS
&& to
!= BR_REGS
)
3616 else if (reg_class_subset_p (from
, AR_REGS
)
3617 && reg_class_subset_p (to
, AR_REGS
))
3619 else if (reg_class_subset_p (from
, AR_REGS
) && to
== ACC_REG
)
3621 else if (from
== ACC_REG
&& reg_class_subset_p (to
, AR_REGS
))
3627 /* Worker function for TARGET_MEMORY_MOVE_COST. */
3630 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3631 reg_class_t rclass ATTRIBUTE_UNUSED
,
3632 bool in ATTRIBUTE_UNUSED
)
3637 /* Compute a (partial) cost for rtx X. Return true if the complete
3638 cost has been computed, and false if subexpressions should be
3639 scanned. In either case, *TOTAL contains the cost result. */
3642 xtensa_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
3643 int opno ATTRIBUTE_UNUSED
,
3644 int *total
, bool speed ATTRIBUTE_UNUSED
)
3646 int code
= GET_CODE (x
);
3654 if (xtensa_simm12b (INTVAL (x
)))
3661 if (xtensa_simm8 (INTVAL (x
))
3662 || xtensa_simm8x256 (INTVAL (x
)))
3669 if (xtensa_mask_immediate (INTVAL (x
)))
3676 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
3687 /* No way to tell if X is the 2nd operand so be conservative. */
3690 if (xtensa_simm12b (INTVAL (x
)))
3692 else if (TARGET_CONST16
)
3693 *total
= COSTS_N_INSNS (2);
3702 *total
= COSTS_N_INSNS (2);
3709 *total
= COSTS_N_INSNS (4);
3717 (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3719 if (memory_address_p (mode
, XEXP ((x
), 0)))
3720 *total
= COSTS_N_INSNS (num_words
);
3722 *total
= COSTS_N_INSNS (2*num_words
);
3728 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
3732 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
3736 *total
= COSTS_N_INSNS (mode
== DImode
? 3 : 2);
3743 *total
= COSTS_N_INSNS (2);
3745 *total
= COSTS_N_INSNS (1);
3752 *total
= COSTS_N_INSNS (50);
3754 *total
= COSTS_N_INSNS (1);
3760 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3761 else if (mode
== DFmode
)
3762 *total
= COSTS_N_INSNS (50);
3764 *total
= COSTS_N_INSNS (4);
3772 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3773 else if (mode
== DFmode
|| mode
== DImode
)
3774 *total
= COSTS_N_INSNS (50);
3776 *total
= COSTS_N_INSNS (1);
3781 *total
= COSTS_N_INSNS (mode
== DImode
? 4 : 2);
3787 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3788 else if (mode
== DFmode
)
3789 *total
= COSTS_N_INSNS (50);
3790 else if (mode
== DImode
)
3791 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
3792 else if (TARGET_MUL32
)
3793 *total
= COSTS_N_INSNS (4);
3794 else if (TARGET_MAC16
)
3795 *total
= COSTS_N_INSNS (16);
3796 else if (TARGET_MUL16
)
3797 *total
= COSTS_N_INSNS (12);
3799 *total
= COSTS_N_INSNS (50);
3808 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3811 else if (mode
== DFmode
)
3813 *total
= COSTS_N_INSNS (50);
3823 *total
= COSTS_N_INSNS (50);
3824 else if (TARGET_DIV32
)
3825 *total
= COSTS_N_INSNS (32);
3827 *total
= COSTS_N_INSNS (50);
3833 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3835 *total
= COSTS_N_INSNS (50);
3842 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3847 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3852 *total
= COSTS_N_INSNS (1);
3860 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3863 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3865 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
3866 > 4 * UNITS_PER_WORD
);
3869 /* Worker function for TARGET_FUNCTION_VALUE. */
3872 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
3875 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
3876 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
3877 ? SImode
: TYPE_MODE (valtype
),
3878 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
3881 /* Worker function for TARGET_LIBCALL_VALUE. */
3884 xtensa_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
3886 return gen_rtx_REG ((GET_MODE_CLASS (mode
) == MODE_INT
3887 && GET_MODE_SIZE (mode
) < UNITS_PER_WORD
)
3888 ? SImode
: mode
, GP_RETURN
);
3891 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
3894 xtensa_function_value_regno_p (const unsigned int regno
)
3896 return (regno
== GP_RETURN
);
3899 /* The static chain is passed in memory. Provide rtx giving 'mem'
3900 expressions that denote where they are stored. */
3903 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl_or_type
), bool incoming_p
)
3905 if (TARGET_WINDOWED_ABI
)
3907 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
3908 return gen_frame_mem (Pmode
, plus_constant (Pmode
, base
,
3909 -5 * UNITS_PER_WORD
));
3912 return gen_rtx_REG (Pmode
, A8_REG
);
3916 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3917 instruction with a minimal stack frame in order to get some free
3918 registers. Once the actual call target is known, the proper stack frame
3919 size is extracted from the ENTRY instruction at the target and the
3920 current frame is adjusted to match. The trampoline then transfers
3921 control to the instruction following the ENTRY at the target. Note:
3922 this assumes that the target begins with an ENTRY instruction. */
3925 xtensa_asm_trampoline_template (FILE *stream
)
3927 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3929 fprintf (stream
, "\t.begin no-transform\n");
3931 if (TARGET_WINDOWED_ABI
)
3933 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
3937 /* Save the return address. */
3938 fprintf (stream
, "\tmov\ta10, a0\n");
3940 /* Use a CALL0 instruction to skip past the constants and in the
3941 process get the PC into A0. This allows PC-relative access to
3942 the constants without relying on L32R. */
3943 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
3946 fprintf (stream
, "\tj\t.Lskipconsts\n");
3948 fprintf (stream
, "\t.align\t4\n");
3949 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
3950 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
3951 fprintf (stream
, ".Lskipconsts:\n");
3953 /* Load the static chain and function address from the trampoline. */
3956 fprintf (stream
, "\taddi\ta0, a0, 3\n");
3957 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
3958 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
3962 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
3963 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
3966 /* Store the static chain. */
3967 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
3969 /* Set the proper stack pointer value. */
3970 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
3971 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
3972 TARGET_BIG_ENDIAN
? 8 : 12);
3973 fprintf (stream
, "\tslli\ta9, a9, 3\n");
3974 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
3975 fprintf (stream
, "\tsub\ta9, sp, a9\n");
3976 fprintf (stream
, "\tmovsp\tsp, a9\n");
3979 /* Restore the return address. */
3980 fprintf (stream
, "\tmov\ta0, a10\n");
3982 /* Jump to the instruction following the ENTRY. */
3983 fprintf (stream
, "\taddi\ta8, a8, 3\n");
3984 fprintf (stream
, "\tjx\ta8\n");
3986 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3988 fprintf (stream
, "\t.byte\t0\n");
3990 fprintf (stream
, "\tnop\n");
3996 /* Save the return address. */
3997 fprintf (stream
, "\tmov\ta10, a0\n");
3999 /* Use a CALL0 instruction to skip past the constants and in the
4000 process get the PC into A0. This allows PC-relative access to
4001 the constants without relying on L32R. */
4002 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
4005 fprintf (stream
, "\tj\t.Lskipconsts\n");
4007 fprintf (stream
, "\t.align\t4\n");
4008 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
4009 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
4010 fprintf (stream
, ".Lskipconsts:\n");
4012 /* Load the static chain and function address from the trampoline. */
4015 fprintf (stream
, "\taddi\ta0, a0, 3\n");
4016 fprintf (stream
, "\tl32i\ta8, a0, 0\n");
4017 fprintf (stream
, "\tl32i\ta9, a0, 4\n");
4018 fprintf (stream
, "\tmov\ta0, a10\n");
4022 fprintf (stream
, "\tl32r\ta8, .Lchainval\n");
4023 fprintf (stream
, "\tl32r\ta9, .Lfnaddr\n");
4025 fprintf (stream
, "\tjx\ta9\n");
4027 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4029 fprintf (stream
, "\t.byte\t0\n");
4031 fprintf (stream
, "\tnop\n");
4033 fprintf (stream
, "\t.end no-transform\n");
4037 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
4039 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
4040 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
4044 if (TARGET_WINDOWED_ABI
)
4046 chain_off
= use_call0
? 12 : 8;
4047 func_off
= use_call0
? 16 : 12;
4051 chain_off
= use_call0
? 8 : 4;
4052 func_off
= use_call0
? 12 : 8;
4055 emit_block_move (m_tramp
, assemble_trampoline_template (),
4056 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4058 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
4059 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
4060 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
4061 LCT_NORMAL
, VOIDmode
, XEXP (m_tramp
, 0), Pmode
);
4064 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
4067 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
4069 return !xtensa_tls_referenced_p (x
);
4072 /* Implement TARGET_CAN_USE_DOLOOP_P. */
4075 xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
4076 unsigned int loop_depth
, bool entered_at_top
)
4078 /* Considering limitations in the hardware, only use doloop
4079 for innermost loops which must be entered from the top. */
4080 if (loop_depth
> 1 || !entered_at_top
)
4086 /* NULL if INSN insn is valid within a low-overhead loop.
4087 Otherwise return why doloop cannot be applied. */
4090 xtensa_invalid_within_doloop (const rtx_insn
*insn
)
4093 return "Function call in the loop.";
4095 if (JUMP_P (insn
) && INSN_CODE (insn
) == CODE_FOR_return
)
4096 return "Return from a call instruction in the loop.";
4101 /* Optimize LOOP. */
4104 hwloop_optimize (hwloop_info loop
)
4108 basic_block entry_bb
;
4110 rtx_insn
*insn
, *seq
, *entry_after
;
4112 if (loop
->depth
> 1)
4115 fprintf (dump_file
, ";; loop %d is not innermost\n",
4120 if (!loop
->incoming_dest
)
4123 fprintf (dump_file
, ";; loop %d has more than one entry\n",
4128 if (loop
->incoming_dest
!= loop
->head
)
4131 fprintf (dump_file
, ";; loop %d is not entered from head\n",
4136 if (loop
->has_call
|| loop
->has_asm
)
4139 fprintf (dump_file
, ";; loop %d has invalid insn\n",
4144 /* Scan all the blocks to make sure they don't use iter_reg. */
4145 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
4148 fprintf (dump_file
, ";; loop %d uses iterator\n",
4153 /* Check if start_label appears before doloop_end. */
4154 insn
= loop
->start_label
;
4155 while (insn
&& insn
!= loop
->loop_end
)
4156 insn
= NEXT_INSN (insn
);
4161 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
4166 /* Get the loop iteration register. */
4167 iter_reg
= loop
->iter_reg
;
4169 gcc_assert (REG_P (iter_reg
));
4173 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
4174 if (entry_edge
->flags
& EDGE_FALLTHRU
)
4177 if (entry_edge
== NULL
)
4180 /* Place the zero_cost_loop_start instruction before the loop. */
4181 entry_bb
= entry_edge
->src
;
4185 insn
= emit_insn (gen_zero_cost_loop_start (loop
->iter_reg
,
4191 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1)
4197 emit_insn_before (seq
, BB_HEAD (loop
->head
));
4198 seq
= emit_label_before (gen_label_rtx (), seq
);
4199 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
4200 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
4202 if (!(e
->flags
& EDGE_FALLTHRU
))
4203 redirect_edge_and_branch_force (e
, new_bb
);
4205 redirect_edge_succ (e
, new_bb
);
4208 make_edge (new_bb
, loop
->head
, 0);
4212 entry_after
= BB_END (entry_bb
);
4213 while (DEBUG_INSN_P (entry_after
)
4214 || (NOTE_P (entry_after
)
4215 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
4216 /* Make sure we don't split a call and its corresponding
4217 CALL_ARG_LOCATION note. */
4218 && NOTE_KIND (entry_after
) != NOTE_INSN_CALL_ARG_LOCATION
))
4219 entry_after
= PREV_INSN (entry_after
);
4221 emit_insn_after (seq
, entry_after
);
4229 /* A callback for the hw-doloop pass. Called when a loop we have discovered
4230 turns out not to be optimizable; we have to split the loop_end pattern into
4231 a subtract and a test. */
4234 hwloop_fail (hwloop_info loop
)
4237 rtx_insn
*insn
= loop
->loop_end
;
4239 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
4244 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
4245 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
4246 loop
->iter_reg
, const0_rtx
,
4250 JUMP_LABEL (insn
) = loop
->start_label
;
4251 LABEL_NUSES (loop
->start_label
)++;
4252 delete_insn (loop
->loop_end
);
4255 /* A callback for the hw-doloop pass. This function examines INSN; if
4256 it is a doloop_end pattern we recognize, return the reg rtx for the
4257 loop counter. Otherwise, return NULL_RTX. */
4260 hwloop_pattern_reg (rtx_insn
*insn
)
4264 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
4267 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
4275 static struct hw_doloop_hooks xtensa_doloop_hooks
=
4282 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
4283 and tries to rewrite the RTL of these loops so that proper Xtensa
4284 hardware loops are generated. */
4287 xtensa_reorg_loops (void)
4290 reorg_loops (false, &xtensa_doloop_hooks
);
4293 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4298 /* We are freeing block_for_insn in the toplev to keep compatibility
4299 with old MDEP_REORGS that are not CFG based. Recompute it now. */
4300 compute_bb_for_insn ();
4304 /* Doloop optimization. */
4305 xtensa_reorg_loops ();
4308 /* Update register usage after having seen the compiler flags. */
4311 xtensa_conditional_register_usage (void)
4315 c_mask
= TARGET_WINDOWED_ABI
? (1 << 1) : (1 << 2);
4317 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4319 /* Set/reset conditionally defined registers from
4320 CALL_USED_REGISTERS initializer. */
4321 if (call_used_regs
[i
] > 1)
4322 call_used_regs
[i
] = !!(call_used_regs
[i
] & c_mask
);
4325 /* Remove hard FP register from the preferred reload registers set. */
4326 CLEAR_HARD_REG_BIT (reg_class_contents
[(int)RL_REGS
],
4327 HARD_FRAME_POINTER_REGNUM
);
4330 /* Map hard register number to register class */
4332 enum reg_class
xtensa_regno_to_class (int regno
)
4334 static const enum reg_class regno_to_class
[FIRST_PSEUDO_REGISTER
] =
4336 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
4337 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4338 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4339 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4340 AR_REGS
, AR_REGS
, BR_REGS
,
4341 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4342 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4343 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4344 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4348 if (regno
== HARD_FRAME_POINTER_REGNUM
)
4351 return regno_to_class
[regno
];
4354 #include "gt-xtensa.h"