1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright (C) 2001-2016 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"
32 #include "stringpool.h"
37 #include "diagnostic-core.h"
40 #include "fold-const.h"
41 #include "stor-layout.h"
48 #include "langhooks.h"
52 #include "hw-doloop.h"
55 /* This file should be included last. */
56 #include "target-def.h"
58 /* Enumeration for all of the relational tests, so that we can build
59 arrays indexed by the test type, and not worry about the order
77 /* Array giving truth value on whether or not a given hard register
78 can support a given mode. */
79 char xtensa_hard_regno_mode_ok
[(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
81 /* Current frame size calculated by compute_frame_size. */
82 unsigned xtensa_current_frame_size
;
83 /* Callee-save area size in the current frame calculated by compute_frame_size. */
84 int xtensa_callee_save_size
;
86 /* Largest block move to handle in-line. */
87 #define LARGEST_MOVE_RATIO 15
89 /* Define the structure for the machine field in struct function. */
90 struct GTY(()) machine_function
92 int accesses_prev_frame
;
96 rtx_insn
*set_frame_ptr_insn
;
99 /* Vector, indexed by hard register number, which contains 1 for a
100 register that is allowable in a candidate for leaf function
103 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
107 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
111 static void xtensa_option_override (void);
112 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
113 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
, int *);
114 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
115 static rtx
gen_conditional_move (enum rtx_code
, machine_mode
, rtx
, rtx
);
116 static rtx
fixup_subreg_mem (rtx
);
117 static struct machine_function
* xtensa_init_machine_status (void);
118 static rtx
xtensa_legitimize_tls_address (rtx
);
119 static rtx
xtensa_legitimize_address (rtx
, rtx
, machine_mode
);
120 static bool xtensa_mode_dependent_address_p (const_rtx
, addr_space_t
);
121 static bool xtensa_return_in_msb (const_tree
);
122 static void printx (FILE *, signed int);
123 static rtx
xtensa_builtin_saveregs (void);
124 static bool xtensa_legitimate_address_p (machine_mode
, rtx
, bool);
125 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
126 int) ATTRIBUTE_UNUSED
;
127 static section
*xtensa_select_rtx_section (machine_mode
, rtx
,
128 unsigned HOST_WIDE_INT
);
129 static bool xtensa_rtx_costs (rtx
, machine_mode
, int, int, int *, bool);
130 static int xtensa_register_move_cost (machine_mode
, reg_class_t
,
132 static int xtensa_memory_move_cost (machine_mode
, reg_class_t
, bool);
133 static tree
xtensa_build_builtin_va_list (void);
134 static bool xtensa_return_in_memory (const_tree
, const_tree
);
135 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
137 static void xtensa_function_arg_advance (cumulative_args_t
, machine_mode
,
139 static rtx
xtensa_function_arg (cumulative_args_t
, machine_mode
,
141 static rtx
xtensa_function_incoming_arg (cumulative_args_t
,
142 machine_mode
, const_tree
, bool);
143 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
144 static rtx
xtensa_libcall_value (machine_mode
, const_rtx
);
145 static bool xtensa_function_value_regno_p (const unsigned int);
146 static unsigned int xtensa_function_arg_boundary (machine_mode
,
148 static void xtensa_init_builtins (void);
149 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
150 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
151 static void xtensa_va_start (tree
, rtx
);
152 static bool xtensa_frame_pointer_required (void);
153 static rtx
xtensa_static_chain (const_tree
, bool);
154 static void xtensa_asm_trampoline_template (FILE *);
155 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
156 static bool xtensa_output_addr_const_extra (FILE *, rtx
);
157 static bool xtensa_cannot_force_const_mem (machine_mode
, rtx
);
159 static reg_class_t
xtensa_preferred_reload_class (rtx
, reg_class_t
);
160 static reg_class_t
xtensa_preferred_output_reload_class (rtx
, reg_class_t
);
161 static reg_class_t
xtensa_secondary_reload (bool, rtx
, reg_class_t
,
163 struct secondary_reload_info
*);
165 static bool constantpool_address_p (const_rtx addr
);
166 static bool xtensa_legitimate_constant_p (machine_mode
, rtx
);
167 static void xtensa_reorg (void);
168 static bool xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
170 static const char *xtensa_invalid_within_doloop (const rtx_insn
*);
172 static bool xtensa_member_type_forces_blk (const_tree
,
175 static void xtensa_conditional_register_usage (void);
179 /* These hooks specify assembly directives for creating certain kinds
180 of integer object. */
182 #undef TARGET_ASM_ALIGNED_SI_OP
183 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
185 #undef TARGET_ASM_SELECT_RTX_SECTION
186 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
188 #undef TARGET_LEGITIMIZE_ADDRESS
189 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
190 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
191 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
193 #undef TARGET_REGISTER_MOVE_COST
194 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
195 #undef TARGET_MEMORY_MOVE_COST
196 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
197 #undef TARGET_RTX_COSTS
198 #define TARGET_RTX_COSTS xtensa_rtx_costs
199 #undef TARGET_ADDRESS_COST
200 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
202 #undef TARGET_MEMBER_TYPE_FORCES_BLK
203 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
205 #undef TARGET_BUILD_BUILTIN_VA_LIST
206 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
208 #undef TARGET_EXPAND_BUILTIN_VA_START
209 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
211 #undef TARGET_PROMOTE_FUNCTION_MODE
212 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
213 #undef TARGET_PROMOTE_PROTOTYPES
214 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
216 #undef TARGET_RETURN_IN_MEMORY
217 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
218 #undef TARGET_FUNCTION_VALUE
219 #define TARGET_FUNCTION_VALUE xtensa_function_value
220 #undef TARGET_LIBCALL_VALUE
221 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
222 #undef TARGET_FUNCTION_VALUE_REGNO_P
223 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
225 #undef TARGET_SPLIT_COMPLEX_ARG
226 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
227 #undef TARGET_MUST_PASS_IN_STACK
228 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
229 #undef TARGET_FUNCTION_ARG_ADVANCE
230 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
231 #undef TARGET_FUNCTION_ARG
232 #define TARGET_FUNCTION_ARG xtensa_function_arg
233 #undef TARGET_FUNCTION_INCOMING_ARG
234 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
235 #undef TARGET_FUNCTION_ARG_BOUNDARY
236 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
238 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
239 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
240 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
241 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
243 #undef TARGET_RETURN_IN_MSB
244 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
246 #undef TARGET_INIT_BUILTINS
247 #define TARGET_INIT_BUILTINS xtensa_init_builtins
248 #undef TARGET_FOLD_BUILTIN
249 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
250 #undef TARGET_EXPAND_BUILTIN
251 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
253 #undef TARGET_PREFERRED_RELOAD_CLASS
254 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
255 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
256 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
258 #undef TARGET_SECONDARY_RELOAD
259 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
261 #undef TARGET_HAVE_TLS
262 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
264 #undef TARGET_CANNOT_FORCE_CONST_MEM
265 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
267 #undef TARGET_LEGITIMATE_ADDRESS_P
268 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
270 #undef TARGET_FRAME_POINTER_REQUIRED
271 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
273 #undef TARGET_STATIC_CHAIN
274 #define TARGET_STATIC_CHAIN xtensa_static_chain
275 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
276 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
277 #undef TARGET_TRAMPOLINE_INIT
278 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
280 #undef TARGET_OPTION_OVERRIDE
281 #define TARGET_OPTION_OVERRIDE xtensa_option_override
283 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
284 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
286 #undef TARGET_LEGITIMATE_CONSTANT_P
287 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
289 #undef TARGET_MACHINE_DEPENDENT_REORG
290 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
292 #undef TARGET_CAN_USE_DOLOOP_P
293 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
295 #undef TARGET_INVALID_WITHIN_DOLOOP
296 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
298 #undef TARGET_CONDITIONAL_REGISTER_USAGE
299 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
301 struct gcc_target targetm
= TARGET_INITIALIZER
;
304 /* Functions to test Xtensa immediate operand validity. */
307 xtensa_simm8 (HOST_WIDE_INT v
)
309 return v
>= -128 && v
<= 127;
314 xtensa_simm8x256 (HOST_WIDE_INT v
)
316 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
321 xtensa_simm12b (HOST_WIDE_INT v
)
323 return v
>= -2048 && v
<= 2047;
328 xtensa_uimm8 (HOST_WIDE_INT v
)
330 return v
>= 0 && v
<= 255;
335 xtensa_uimm8x2 (HOST_WIDE_INT v
)
337 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
342 xtensa_uimm8x4 (HOST_WIDE_INT v
)
344 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
349 xtensa_b4const (HOST_WIDE_INT v
)
376 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
380 return xtensa_b4const (v
);
385 xtensa_b4constu (HOST_WIDE_INT v
)
412 xtensa_mask_immediate (HOST_WIDE_INT v
)
414 #define MAX_MASK_SIZE 16
417 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
430 /* This is just like the standard true_regnum() function except that it
431 works even when reg_renumber is not initialized. */
434 xt_true_regnum (rtx x
)
436 if (GET_CODE (x
) == REG
)
439 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
440 && reg_renumber
[REGNO (x
)] >= 0)
441 return reg_renumber
[REGNO (x
)];
444 if (GET_CODE (x
) == SUBREG
)
446 int base
= xt_true_regnum (SUBREG_REG (x
));
447 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
448 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
449 GET_MODE (SUBREG_REG (x
)),
450 SUBREG_BYTE (x
), GET_MODE (x
));
457 xtensa_valid_move (machine_mode mode
, rtx
*operands
)
459 /* Either the destination or source must be a register, and the
460 MAC16 accumulator doesn't count. */
462 if (register_operand (operands
[0], mode
))
464 int dst_regnum
= xt_true_regnum (operands
[0]);
466 if (xtensa_tls_referenced_p (operands
[1]))
469 /* The stack pointer can only be assigned with a MOVSP opcode. */
470 if (dst_regnum
== STACK_POINTER_REGNUM
)
471 return !TARGET_WINDOWED_ABI
473 && register_operand (operands
[1], mode
)
474 && !ACC_REG_P (xt_true_regnum (operands
[1])));
476 if (!ACC_REG_P (dst_regnum
))
479 if (register_operand (operands
[1], mode
))
481 int src_regnum
= xt_true_regnum (operands
[1]);
482 if (!ACC_REG_P (src_regnum
))
490 smalloffset_mem_p (rtx op
)
492 if (GET_CODE (op
) == MEM
)
494 rtx addr
= XEXP (op
, 0);
495 if (GET_CODE (addr
) == REG
)
496 return BASE_REG_P (addr
, 0);
497 if (GET_CODE (addr
) == PLUS
)
499 rtx offset
= XEXP (addr
, 0);
501 if (GET_CODE (offset
) != CONST_INT
)
502 offset
= XEXP (addr
, 1);
503 if (GET_CODE (offset
) != CONST_INT
)
506 val
= INTVAL (offset
);
507 return (val
& 3) == 0 && (val
>= 0 && val
<= 60);
515 constantpool_address_p (const_rtx addr
)
517 const_rtx sym
= addr
;
519 if (GET_CODE (addr
) == CONST
)
523 /* Only handle (PLUS (SYM, OFFSET)) form. */
524 addr
= XEXP (addr
, 0);
525 if (GET_CODE (addr
) != PLUS
)
528 /* Make sure the address is word aligned. */
529 offset
= XEXP (addr
, 1);
530 if ((!CONST_INT_P (offset
))
531 || ((INTVAL (offset
) & 3) != 0))
534 sym
= XEXP (addr
, 0);
537 if ((GET_CODE (sym
) == SYMBOL_REF
)
538 && CONSTANT_POOL_ADDRESS_P (sym
))
545 constantpool_mem_p (rtx op
)
547 if (GET_CODE (op
) == SUBREG
)
548 op
= SUBREG_REG (op
);
549 if (GET_CODE (op
) == MEM
)
550 return constantpool_address_p (XEXP (op
, 0));
555 /* Return TRUE if X is a thread-local symbol. */
558 xtensa_tls_symbol_p (rtx x
)
560 if (! TARGET_HAVE_TLS
)
563 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
568 xtensa_extend_reg (rtx dst
, rtx src
)
570 rtx temp
= gen_reg_rtx (SImode
);
571 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
573 /* Generate paradoxical subregs as needed so that the modes match. */
574 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
575 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
577 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
578 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
583 xtensa_mem_offset (unsigned v
, machine_mode mode
)
588 /* Handle the worst case for block moves. See xtensa_expand_block_move
589 where we emit an optimized block move operation if the block can be
590 moved in < "move_ratio" pieces. The worst case is when the block is
591 aligned but has a size of (3 mod 4) (does this happen?) so that the
592 last piece requires a byte load/store. */
593 return (xtensa_uimm8 (v
)
594 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
597 return xtensa_uimm8 (v
);
600 return xtensa_uimm8x2 (v
);
603 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
609 return xtensa_uimm8x4 (v
);
613 /* Make normal rtx_code into something we can index from an array. */
615 static enum internal_test
616 map_test_to_internal_test (enum rtx_code test_code
)
618 enum internal_test test
= ITEST_MAX
;
623 case EQ
: test
= ITEST_EQ
; break;
624 case NE
: test
= ITEST_NE
; break;
625 case GT
: test
= ITEST_GT
; break;
626 case GE
: test
= ITEST_GE
; break;
627 case LT
: test
= ITEST_LT
; break;
628 case LE
: test
= ITEST_LE
; break;
629 case GTU
: test
= ITEST_GTU
; break;
630 case GEU
: test
= ITEST_GEU
; break;
631 case LTU
: test
= ITEST_LTU
; break;
632 case LEU
: test
= ITEST_LEU
; break;
639 /* Generate the code to compare two integer values. The return value is
640 the comparison expression. */
643 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
644 rtx cmp0
, /* first operand to compare */
645 rtx cmp1
, /* second operand to compare */
646 int *p_invert
/* whether branch needs to reverse test */)
650 enum rtx_code test_code
; /* test code to use in insn */
651 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
652 int const_add
; /* constant to add (convert LE -> LT) */
653 int reverse_regs
; /* reverse registers in test */
654 int invert_const
; /* != 0 if invert value if cmp1 is constant */
655 int invert_reg
; /* != 0 if invert value if cmp1 is register */
656 int unsignedp
; /* != 0 for unsigned comparisons. */
659 static struct cmp_info info
[ (int)ITEST_MAX
] = {
661 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
662 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
664 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
665 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
666 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
667 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
669 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
670 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
671 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
672 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
675 enum internal_test test
;
677 struct cmp_info
*p_info
;
679 test
= map_test_to_internal_test (test_code
);
680 gcc_assert (test
!= ITEST_MAX
);
682 p_info
= &info
[ (int)test
];
684 mode
= GET_MODE (cmp0
);
685 if (mode
== VOIDmode
)
686 mode
= GET_MODE (cmp1
);
688 /* Make sure we can handle any constants given to us. */
689 if (GET_CODE (cmp1
) == CONST_INT
)
691 HOST_WIDE_INT value
= INTVAL (cmp1
);
692 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
694 /* if the immediate overflows or does not fit in the immediate field,
695 spill it to a register */
697 if ((p_info
->unsignedp
?
698 (uvalue
+ p_info
->const_add
> uvalue
) :
699 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
701 cmp1
= force_reg (mode
, cmp1
);
703 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
705 cmp1
= force_reg (mode
, cmp1
);
708 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
710 cmp1
= force_reg (mode
, cmp1
);
713 /* See if we need to invert the result. */
714 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
715 ? p_info
->invert_const
716 : p_info
->invert_reg
);
718 /* Comparison to constants, may involve adding 1 to change a LT into LE.
719 Comparison between two registers, may involve switching operands. */
720 if (GET_CODE (cmp1
) == CONST_INT
)
722 if (p_info
->const_add
!= 0)
723 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
726 else if (p_info
->reverse_regs
)
733 return gen_rtx_fmt_ee (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
737 /* Generate the code to compare two float values. The return value is
738 the comparison expression. */
741 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
742 rtx cmp0
, /* first operand to compare */
743 rtx cmp1
/* second operand to compare */)
745 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
747 int reverse_regs
, invert
;
751 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
752 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
753 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
754 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
755 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
756 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
757 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
758 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
759 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
760 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
761 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
762 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
764 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
766 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
768 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
769 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
779 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
780 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
782 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
787 xtensa_expand_conditional_branch (rtx
*operands
, machine_mode mode
)
789 enum rtx_code test_code
= GET_CODE (operands
[0]);
790 rtx cmp0
= operands
[1];
791 rtx cmp1
= operands
[2];
800 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
804 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
808 if (!TARGET_HARD_FLOAT
)
809 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
,
812 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
816 /* Generate the branch. */
818 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
827 emit_jump_insn (gen_rtx_SET (pc_rtx
,
828 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
835 gen_conditional_move (enum rtx_code code
, machine_mode mode
,
842 /* Jump optimization calls get_condition() which canonicalizes
843 comparisons like (GE x <const>) to (GT x <const-1>).
844 Transform those comparisons back to GE, since that is the
845 comparison supported in Xtensa. We shouldn't have to
846 transform <LE x const> comparisons, because neither
847 xtensa_expand_conditional_branch() nor get_condition() will
850 if ((code
== GT
) && (op1
== constm1_rtx
))
855 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
857 if (boolean_operator (cmp
, VOIDmode
))
859 /* Swap the operands to make const0 second. */
860 if (op0
== const0_rtx
)
866 /* If not comparing against zero, emit a comparison (subtract). */
867 if (op1
!= const0_rtx
)
869 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
870 0, 0, OPTAB_LIB_WIDEN
);
874 else if (branch_operator (cmp
, VOIDmode
))
876 /* Swap the operands to make const0 second. */
877 if (op0
== const0_rtx
)
884 case LT
: code
= GE
; break;
885 case GE
: code
= LT
; break;
886 default: gcc_unreachable ();
890 if (op1
!= const0_rtx
)
896 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
899 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
900 return gen_float_relational (code
, op0
, op1
);
907 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
909 rtx dest
= operands
[0];
910 rtx cmp
= operands
[1];
911 machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
912 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
914 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
915 XEXP (cmp
, 0), XEXP (cmp
, 1))))
919 gen_fn
= (cmp_mode
== SImode
920 ? gen_movsfcc_internal0
921 : gen_movsfcc_internal1
);
923 gen_fn
= (cmp_mode
== SImode
924 ? gen_movsicc_internal0
925 : gen_movsicc_internal1
);
927 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
933 xtensa_expand_scc (rtx operands
[4], machine_mode cmp_mode
)
935 rtx dest
= operands
[0];
937 rtx one_tmp
, zero_tmp
;
938 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
940 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
941 operands
[2], operands
[3])))
944 one_tmp
= gen_reg_rtx (SImode
);
945 zero_tmp
= gen_reg_rtx (SImode
);
946 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
947 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
949 gen_fn
= (cmp_mode
== SImode
950 ? gen_movsicc_internal0
951 : gen_movsicc_internal1
);
952 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
957 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
958 for the output, i.e., the input operands are twice as big as MODE. */
961 xtensa_split_operand_pair (rtx operands
[4], machine_mode mode
)
963 switch (GET_CODE (operands
[1]))
966 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
967 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
971 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
972 operands
[2] = adjust_address (operands
[1], mode
, 0);
977 split_double (operands
[1], &operands
[2], &operands
[3]);
984 switch (GET_CODE (operands
[0]))
987 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
988 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
992 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
993 operands
[0] = adjust_address (operands
[0], mode
, 0);
1002 /* Emit insns to move operands[1] into operands[0].
1003 Return 1 if we have written out everything that needs to be done to
1004 do the move. Otherwise, return 0 and the caller will emit the move
1008 xtensa_emit_move_sequence (rtx
*operands
, machine_mode mode
)
1010 rtx src
= operands
[1];
1012 if (CONSTANT_P (src
)
1013 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
1015 rtx dst
= operands
[0];
1017 if (xtensa_tls_referenced_p (src
))
1021 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
1023 addend
= XEXP (XEXP (src
, 0), 1);
1024 src
= XEXP (XEXP (src
, 0), 0);
1027 src
= xtensa_legitimize_tls_address (src
);
1030 src
= gen_rtx_PLUS (mode
, src
, addend
);
1031 src
= force_operand (src
, dst
);
1033 emit_move_insn (dst
, src
);
1037 if (! TARGET_AUTO_LITPOOLS
&& ! TARGET_CONST16
)
1039 src
= force_const_mem (SImode
, src
);
1043 /* PC-relative loads are always SImode, and CONST16 is only
1044 supported in the movsi pattern, so add a SUBREG for any other
1049 if (register_operand (dst
, mode
))
1051 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
1056 src
= force_reg (SImode
, src
);
1057 src
= gen_lowpart_SUBREG (mode
, src
);
1063 if (!(reload_in_progress
| reload_completed
)
1064 && !xtensa_valid_move (mode
, operands
))
1065 operands
[1] = force_reg (mode
, operands
[1]);
1067 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1069 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1070 instruction won't be recognized after reload, so we remove the
1071 subreg and adjust mem accordingly. */
1072 if (reload_in_progress
)
1074 operands
[0] = fixup_subreg_mem (operands
[0]);
1075 operands
[1] = fixup_subreg_mem (operands
[1]);
1082 fixup_subreg_mem (rtx x
)
1084 if (GET_CODE (x
) == SUBREG
1085 && GET_CODE (SUBREG_REG (x
)) == REG
1086 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1089 gen_rtx_SUBREG (GET_MODE (x
),
1090 reg_equiv_mem (REGNO (SUBREG_REG (x
))),
1092 x
= alter_subreg (&temp
, true);
1098 /* Check if an incoming argument in a7 is expected to be used soon and
1099 if OPND is a register or register pair that includes a7. If so,
1100 create a new pseudo and copy a7 into that pseudo at the very
1101 beginning of the function, followed by the special "set_frame_ptr"
1102 unspec_volatile insn. The return value is either the original
1103 operand, if it is not a7, or the new pseudo containing a copy of
1104 the incoming argument. This is necessary because the register
1105 allocator will ignore conflicts with a7 and may either assign some
1106 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1107 the incoming argument in a7. By copying the argument out of a7 as
1108 the very first thing, and then immediately following that with an
1109 unspec_volatile to keep the scheduler away, we should avoid any
1110 problems. Putting the set_frame_ptr insn at the beginning, with
1111 only the a7 copy before it, also makes it easier for the prologue
1112 expander to initialize the frame pointer after the a7 copy and to
1113 fix up the a7 copy to use the stack pointer instead of the frame
1117 xtensa_copy_incoming_a7 (rtx opnd
)
1119 rtx entry_insns
= 0;
1123 if (!cfun
->machine
->need_a7_copy
)
1126 /* This function should never be called again once a7 has been copied. */
1127 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1129 mode
= GET_MODE (opnd
);
1131 /* The operand using a7 may come in a later instruction, so just return
1132 the original operand if it doesn't use a7. */
1134 if (GET_CODE (reg
) == SUBREG
)
1136 gcc_assert (SUBREG_BYTE (reg
) == 0);
1137 reg
= SUBREG_REG (reg
);
1139 if (GET_CODE (reg
) != REG
1140 || REGNO (reg
) > A7_REG
1141 || REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) <= A7_REG
)
1144 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1145 gcc_assert (REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) - 1 == A7_REG
);
1147 cfun
->machine
->need_a7_copy
= false;
1149 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1150 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1153 tmp
= gen_reg_rtx (mode
);
1159 /* Copy the value out of A7 here but keep the first word in A6 until
1160 after the set_frame_ptr insn. Otherwise, the register allocator
1161 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1163 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1164 gen_raw_REG (SImode
, A7_REG
)));
1167 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1170 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1173 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1176 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1182 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1184 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1185 if (mode
== DFmode
|| mode
== DImode
)
1186 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1187 gen_rtx_REG (SImode
, A7_REG
- 1)));
1188 entry_insns
= get_insns ();
1191 if (cfun
->machine
->vararg_a7
)
1193 /* This is called from within builtin_saveregs, which will insert the
1194 saveregs code at the function entry, ahead of anything placed at
1195 the function entry now. Instead, save the sequence to be inserted
1196 at the beginning of the saveregs code. */
1197 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1201 /* Put entry_insns after the NOTE that starts the function. If
1202 this is inside a start_sequence, make the outer-level insn
1203 chain current, so the code is placed at the start of the
1205 push_topmost_sequence ();
1206 /* Do not use entry_of_function() here. This is called from within
1207 expand_function_start, when the CFG still holds GIMPLE. */
1208 emit_insn_after (entry_insns
, get_insns ());
1209 pop_topmost_sequence ();
1216 /* Try to expand a block move operation to a sequence of RTL move
1217 instructions. If not optimizing, or if the block size is not a
1218 constant, or if the block is too large, the expansion fails and GCC
1219 falls back to calling memcpy().
1221 operands[0] is the destination
1222 operands[1] is the source
1223 operands[2] is the length
1224 operands[3] is the alignment */
1227 xtensa_expand_block_move (rtx
*operands
)
1229 static const machine_mode mode_from_align
[] =
1231 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1234 rtx dst_mem
= operands
[0];
1235 rtx src_mem
= operands
[1];
1236 HOST_WIDE_INT bytes
, align
;
1237 int num_pieces
, move_ratio
;
1239 machine_mode mode
[2];
1248 /* If this is not a fixed size move, just call memcpy. */
1249 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1252 bytes
= INTVAL (operands
[2]);
1253 align
= INTVAL (operands
[3]);
1255 /* Anything to move? */
1259 if (align
> MOVE_MAX
)
1262 /* Decide whether to expand inline based on the optimization level. */
1265 move_ratio
= LARGEST_MOVE_RATIO
;
1266 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* Close enough anyway. */
1267 if (num_pieces
> move_ratio
)
1270 x
= XEXP (dst_mem
, 0);
1273 x
= force_reg (Pmode
, x
);
1274 dst_mem
= replace_equiv_address (dst_mem
, x
);
1277 x
= XEXP (src_mem
, 0);
1280 x
= force_reg (Pmode
, x
);
1281 src_mem
= replace_equiv_address (src_mem
, x
);
1284 active
[0] = active
[1] = false;
1295 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1296 next_amount
= MIN (next_amount
, align
);
1298 amount
[next
] = next_amount
;
1299 mode
[next
] = mode_from_align
[next_amount
];
1300 temp
[next
] = gen_reg_rtx (mode
[next
]);
1302 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1303 emit_insn (gen_rtx_SET (temp
[next
], x
));
1305 offset_ld
+= next_amount
;
1306 bytes
-= next_amount
;
1307 active
[next
] = true;
1312 active
[phase
] = false;
1314 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1315 emit_insn (gen_rtx_SET (x
, temp
[phase
]));
1317 offset_st
+= amount
[phase
];
1320 while (active
[next
]);
1327 xtensa_expand_nonlocal_goto (rtx
*operands
)
1329 rtx goto_handler
= operands
[1];
1330 rtx containing_fp
= operands
[3];
1332 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1333 is too big to generate in-line. */
1335 if (GET_CODE (containing_fp
) != REG
)
1336 containing_fp
= force_reg (Pmode
, containing_fp
);
1338 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1339 LCT_NORMAL
, VOIDmode
, 2,
1340 containing_fp
, Pmode
,
1341 goto_handler
, Pmode
);
1345 static struct machine_function
*
1346 xtensa_init_machine_status (void)
1348 return ggc_cleared_alloc
<machine_function
> ();
1352 /* Shift VAL of mode MODE left by COUNT bits. */
1355 xtensa_expand_mask_and_shift (rtx val
, machine_mode mode
, rtx count
)
1357 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1358 NULL_RTX
, 1, OPTAB_DIRECT
);
1359 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1360 NULL_RTX
, 1, OPTAB_DIRECT
);
1364 /* Structure to hold the initial parameters for a compare_and_swap operation
1365 in HImode and QImode. */
1367 struct alignment_context
1369 rtx memsi
; /* SI aligned memory location. */
1370 rtx shift
; /* Bit offset with regard to lsb. */
1371 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1372 rtx modemaski
; /* ~modemask */
1376 /* Initialize structure AC for word access to HI and QI mode memory. */
1379 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1381 machine_mode mode
= GET_MODE (mem
);
1382 rtx byteoffset
= NULL_RTX
;
1383 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1386 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1389 /* Alignment is unknown. */
1392 /* Force the address into a register. */
1393 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1395 /* Align it to SImode. */
1396 align
= expand_simple_binop (Pmode
, AND
, addr
,
1397 GEN_INT (-GET_MODE_SIZE (SImode
)),
1398 NULL_RTX
, 1, OPTAB_DIRECT
);
1400 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1401 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1402 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1403 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1405 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1406 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1407 NULL_RTX
, 1, OPTAB_DIRECT
);
1410 /* Calculate shiftcount. */
1411 if (TARGET_BIG_ENDIAN
)
1413 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1415 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1416 NULL_RTX
, 1, OPTAB_DIRECT
);
1421 ac
->shift
= NULL_RTX
;
1423 ac
->shift
= byteoffset
;
1426 if (ac
->shift
!= NULL_RTX
)
1428 /* Shift is the byte count, but we need the bitcount. */
1429 gcc_assert (exact_log2 (BITS_PER_UNIT
) >= 0);
1430 ac
->shift
= expand_simple_binop (SImode
, ASHIFT
, ac
->shift
,
1431 GEN_INT (exact_log2 (BITS_PER_UNIT
)),
1432 NULL_RTX
, 1, OPTAB_DIRECT
);
1433 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1434 GEN_INT (GET_MODE_MASK (mode
)),
1436 NULL_RTX
, 1, OPTAB_DIRECT
);
1439 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1441 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1445 /* Expand an atomic compare and swap operation for HImode and QImode.
1446 MEM is the memory location, CMP the old value to compare MEM with
1447 and NEW_RTX the value to set if CMP == MEM. */
1450 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1452 machine_mode mode
= GET_MODE (mem
);
1453 struct alignment_context ac
;
1454 rtx tmp
, cmpv
, newv
, val
;
1455 rtx oldval
= gen_reg_rtx (SImode
);
1456 rtx res
= gen_reg_rtx (SImode
);
1457 rtx_code_label
*csloop
= gen_label_rtx ();
1458 rtx_code_label
*csend
= gen_label_rtx ();
1460 init_alignment_context (&ac
, mem
);
1462 if (ac
.shift
!= NULL_RTX
)
1464 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1465 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1468 /* Load the surrounding word into VAL with the MEM value masked out. */
1469 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1470 ac
.modemaski
, NULL_RTX
, 1,
1472 emit_label (csloop
);
1474 /* Patch CMP and NEW_RTX into VAL at correct position. */
1475 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1476 NULL_RTX
, 1, OPTAB_DIRECT
));
1477 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1478 NULL_RTX
, 1, OPTAB_DIRECT
));
1480 /* Jump to end if we're done. */
1481 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1482 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1484 /* Check for changes outside mode. */
1485 emit_move_insn (oldval
, val
);
1486 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1487 val
, 1, OPTAB_DIRECT
);
1489 emit_move_insn (val
, tmp
);
1491 /* Loop internal if so. */
1492 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1496 /* Return the correct part of the bitfield. */
1497 convert_move (target
,
1498 (ac
.shift
== NULL_RTX
? res
1499 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1500 NULL_RTX
, 1, OPTAB_DIRECT
)),
1505 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1506 the default expansion works fine for SImode). MEM is the memory location
1507 and VAL the value to play with. If AFTER is true then store the value
1508 MEM holds after the operation, if AFTER is false then store the value MEM
1509 holds before the operation. If TARGET is zero then discard that value, else
1510 store it to TARGET. */
1513 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1516 machine_mode mode
= GET_MODE (mem
);
1517 struct alignment_context ac
;
1518 rtx_code_label
*csloop
= gen_label_rtx ();
1520 rtx old
= gen_reg_rtx (SImode
);
1521 rtx new_rtx
= gen_reg_rtx (SImode
);
1522 rtx orig
= NULL_RTX
;
1524 init_alignment_context (&ac
, mem
);
1526 /* Prepare values before the compare-and-swap loop. */
1527 if (ac
.shift
!= NULL_RTX
)
1528 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1533 orig
= gen_reg_rtx (SImode
);
1534 convert_move (orig
, val
, 1);
1542 case MULT
: /* NAND */
1544 /* val = "11..1<val>11..1" */
1545 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1546 NULL_RTX
, 1, OPTAB_DIRECT
);
1553 /* Load full word. Subsequent loads are performed by S32C1I. */
1554 cmp
= force_reg (SImode
, ac
.memsi
);
1556 emit_label (csloop
);
1557 emit_move_insn (old
, cmp
);
1563 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1564 NULL_RTX
, 1, OPTAB_DIRECT
);
1565 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1566 NULL_RTX
, 1, OPTAB_DIRECT
);
1569 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1570 NULL_RTX
, 1, OPTAB_DIRECT
);
1571 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1572 new_rtx
, 1, OPTAB_DIRECT
);
1578 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
1579 new_rtx
, 1, OPTAB_DIRECT
);
1582 case MULT
: /* NAND */
1583 tmp
= expand_simple_binop (SImode
, XOR
, old
, ac
.modemask
,
1584 NULL_RTX
, 1, OPTAB_DIRECT
);
1585 tmp
= expand_simple_binop (SImode
, AND
, tmp
, val
,
1586 new_rtx
, 1, OPTAB_DIRECT
);
1594 emit_move_insn (new_rtx
, tmp
);
1595 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
1596 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
1600 tmp
= (after
? new_rtx
: cmp
);
1601 convert_move (target
,
1602 (ac
.shift
== NULL_RTX
? tmp
1603 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
1604 NULL_RTX
, 1, OPTAB_DIRECT
)),
1611 xtensa_setup_frame_addresses (void)
1613 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1614 cfun
->machine
->accesses_prev_frame
= 1;
1616 if (TARGET_WINDOWED_ABI
)
1618 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1619 LCT_NORMAL
, VOIDmode
, 0);
1623 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1624 a comment showing where the end of the loop is. However, if there is a
1625 label or a branch at the end of the loop then we need to place a nop
1626 there. If the loop ends with a label we need the nop so that branches
1627 targeting that label will target the nop (and thus remain in the loop),
1628 instead of targeting the instruction after the loop (and thus exiting
1629 the loop). If the loop ends with a branch, we need the nop in case the
1630 branch is targeting a location inside the loop. When the branch
1631 executes it will cause the loop count to be decremented even if it is
1632 taken (because it is the last instruction in the loop), so we need to
1633 nop after the branch to prevent the loop count from being decremented
1634 when the branch is taken. */
1637 xtensa_emit_loop_end (rtx_insn
*insn
, rtx
*operands
)
1641 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1643 switch (GET_CODE (insn
))
1650 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1656 rtx body
= PATTERN (insn
);
1660 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1663 else if ((GET_CODE (body
) != USE
)
1664 && (GET_CODE (body
) != CLOBBER
))
1671 output_asm_insn ("%1_LEND:", operands
);
1676 xtensa_emit_branch (bool inverted
, bool immed
, rtx
*operands
)
1678 static char result
[64];
1682 code
= GET_CODE (operands
[3]);
1685 case EQ
: op
= inverted
? "ne" : "eq"; break;
1686 case NE
: op
= inverted
? "eq" : "ne"; break;
1687 case LT
: op
= inverted
? "ge" : "lt"; break;
1688 case GE
: op
= inverted
? "lt" : "ge"; break;
1689 case LTU
: op
= inverted
? "geu" : "ltu"; break;
1690 case GEU
: op
= inverted
? "ltu" : "geu"; break;
1691 default: gcc_unreachable ();
1696 if (INTVAL (operands
[1]) == 0)
1697 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
1698 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
1700 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1703 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1710 xtensa_emit_bit_branch (bool inverted
, bool immed
, rtx
*operands
)
1712 static char result
[64];
1715 switch (GET_CODE (operands
[3]))
1717 case EQ
: op
= inverted
? "bs" : "bc"; break;
1718 case NE
: op
= inverted
? "bc" : "bs"; break;
1719 default: gcc_unreachable ();
1724 unsigned bitnum
= INTVAL (operands
[1]) & 0x1f;
1725 operands
[1] = GEN_INT (bitnum
);
1726 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1729 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1736 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
1738 static char result
[64];
1742 code
= GET_CODE (operands
[4]);
1747 case EQ
: op
= inverted
? "t" : "f"; break;
1748 case NE
: op
= inverted
? "f" : "t"; break;
1749 default: gcc_unreachable ();
1756 case EQ
: op
= inverted
? "nez" : "eqz"; break;
1757 case NE
: op
= inverted
? "eqz" : "nez"; break;
1758 case LT
: op
= inverted
? "gez" : "ltz"; break;
1759 case GE
: op
= inverted
? "ltz" : "gez"; break;
1760 default: gcc_unreachable ();
1764 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
1765 op
, isfp
? ".s" : "", inverted
? 3 : 2);
1771 xtensa_emit_call (int callop
, rtx
*operands
)
1773 static char result
[64];
1774 rtx tgt
= operands
[callop
];
1776 if (GET_CODE (tgt
) == CONST_INT
)
1777 sprintf (result
, "call%d\t0x%lx", WINDOW_SIZE
, INTVAL (tgt
));
1778 else if (register_operand (tgt
, VOIDmode
))
1779 sprintf (result
, "callx%d\t%%%d", WINDOW_SIZE
, callop
);
1781 sprintf (result
, "call%d\t%%%d", WINDOW_SIZE
, callop
);
1788 xtensa_legitimate_address_p (machine_mode mode
, rtx addr
, bool strict
)
1790 /* Allow constant pool addresses. */
1791 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
1792 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
1793 && ! xtensa_tls_referenced_p (addr
))
1796 while (GET_CODE (addr
) == SUBREG
)
1797 addr
= SUBREG_REG (addr
);
1799 /* Allow base registers. */
1800 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
1803 /* Check for "register + offset" addressing. */
1804 if (GET_CODE (addr
) == PLUS
)
1806 rtx xplus0
= XEXP (addr
, 0);
1807 rtx xplus1
= XEXP (addr
, 1);
1808 enum rtx_code code0
;
1809 enum rtx_code code1
;
1811 while (GET_CODE (xplus0
) == SUBREG
)
1812 xplus0
= SUBREG_REG (xplus0
);
1813 code0
= GET_CODE (xplus0
);
1815 while (GET_CODE (xplus1
) == SUBREG
)
1816 xplus1
= SUBREG_REG (xplus1
);
1817 code1
= GET_CODE (xplus1
);
1819 /* Swap operands if necessary so the register is first. */
1820 if (code0
!= REG
&& code1
== REG
)
1822 xplus0
= XEXP (addr
, 1);
1823 xplus1
= XEXP (addr
, 0);
1824 code0
= GET_CODE (xplus0
);
1825 code1
= GET_CODE (xplus1
);
1828 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
1829 && code1
== CONST_INT
1830 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
1838 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1840 static GTY(()) rtx xtensa_tls_module_base_symbol
;
1843 xtensa_tls_module_base (void)
1845 if (! xtensa_tls_module_base_symbol
)
1847 xtensa_tls_module_base_symbol
=
1848 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
1849 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
1850 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
1853 return xtensa_tls_module_base_symbol
;
1858 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
1861 rtx_insn
*call_insn
, *insns
;
1864 fn
= gen_reg_rtx (Pmode
);
1865 arg
= gen_reg_rtx (Pmode
);
1866 a_io
= gen_rtx_REG (Pmode
, WINDOW_SIZE
+ 2);
1868 emit_insn (gen_tls_func (fn
, sym
));
1869 emit_insn (gen_tls_arg (arg
, sym
));
1870 emit_move_insn (a_io
, arg
);
1871 call_insn
= emit_call_insn (gen_tls_call (a_io
, fn
, sym
, const1_rtx
));
1872 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn
), a_io
);
1873 insns
= get_insns ();
1882 xtensa_legitimize_tls_address (rtx x
)
1884 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
1885 rtx dest
, tp
, ret
, modbase
, base
, addend
;
1888 dest
= gen_reg_rtx (Pmode
);
1891 case TLS_MODEL_GLOBAL_DYNAMIC
:
1892 insns
= xtensa_call_tls_desc (x
, &ret
);
1893 emit_libcall_block (insns
, dest
, ret
, x
);
1896 case TLS_MODEL_LOCAL_DYNAMIC
:
1897 base
= gen_reg_rtx (Pmode
);
1898 modbase
= xtensa_tls_module_base ();
1899 insns
= xtensa_call_tls_desc (modbase
, &ret
);
1900 emit_libcall_block (insns
, base
, ret
, modbase
);
1901 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
1902 emit_insn (gen_addsi3 (dest
, base
, addend
));
1905 case TLS_MODEL_INITIAL_EXEC
:
1906 case TLS_MODEL_LOCAL_EXEC
:
1907 tp
= gen_reg_rtx (SImode
);
1908 emit_insn (gen_get_thread_pointersi (tp
));
1909 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
1910 emit_insn (gen_addsi3 (dest
, tp
, addend
));
1922 xtensa_legitimize_address (rtx x
,
1923 rtx oldx ATTRIBUTE_UNUSED
,
1926 if (xtensa_tls_symbol_p (x
))
1927 return xtensa_legitimize_tls_address (x
);
1929 if (GET_CODE (x
) == PLUS
)
1931 rtx plus0
= XEXP (x
, 0);
1932 rtx plus1
= XEXP (x
, 1);
1934 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1936 plus0
= XEXP (x
, 1);
1937 plus1
= XEXP (x
, 0);
1940 /* Try to split up the offset to use an ADDMI instruction. */
1941 if (GET_CODE (plus0
) == REG
1942 && GET_CODE (plus1
) == CONST_INT
1943 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
1944 && !xtensa_simm8 (INTVAL (plus1
))
1945 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
1946 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
1948 rtx temp
= gen_reg_rtx (Pmode
);
1949 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
1950 emit_insn (gen_rtx_SET (temp
, gen_rtx_PLUS (Pmode
, plus0
,
1952 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
1959 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
1961 Treat constant-pool references as "mode dependent" since they can
1962 only be accessed with SImode loads. This works around a bug in the
1963 combiner where a constant pool reference is temporarily converted
1964 to an HImode load, which is then assumed to zero-extend based on
1965 our definition of LOAD_EXTEND_OP. This is wrong because the high
1966 bits of a 16-bit value in the constant pool are now sign-extended
1970 xtensa_mode_dependent_address_p (const_rtx addr
,
1971 addr_space_t as ATTRIBUTE_UNUSED
)
1973 return constantpool_address_p (addr
);
1976 /* Return TRUE if X contains any TLS symbol references. */
1979 xtensa_tls_referenced_p (rtx x
)
1981 if (! TARGET_HAVE_TLS
)
1984 subrtx_iterator::array_type array
;
1985 FOR_EACH_SUBRTX (iter
, array
, x
, ALL
)
1987 const_rtx x
= *iter
;
1988 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0)
1991 /* Ignore TLS references that have already been legitimized. */
1992 if (GET_CODE (x
) == UNSPEC
)
1993 switch (XINT (x
, 1))
1997 case UNSPEC_TLS_FUNC
:
1998 case UNSPEC_TLS_ARG
:
1999 case UNSPEC_TLS_CALL
:
2000 iter
.skip_subrtxes ();
2010 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2013 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
2015 return xtensa_tls_referenced_p (x
);
2019 /* Return the debugger register number to use for 'regno'. */
2022 xtensa_dbx_register_number (int regno
)
2026 if (GP_REG_P (regno
))
2028 regno
-= GP_REG_FIRST
;
2031 else if (BR_REG_P (regno
))
2033 regno
-= BR_REG_FIRST
;
2036 else if (FP_REG_P (regno
))
2038 regno
-= FP_REG_FIRST
;
2041 else if (ACC_REG_P (regno
))
2043 first
= 0x200; /* Start of Xtensa special registers. */
2044 regno
= 16; /* ACCLO is special register 16. */
2047 /* When optimizing, we sometimes get asked about pseudo-registers
2048 that don't represent hard registers. Return 0 for these. */
2052 return first
+ regno
;
2056 /* Argument support functions. */
2058 /* Initialize CUMULATIVE_ARGS for a function. */
2061 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
2064 cum
->incoming
= incoming
;
2068 /* Advance the argument to the next argument position. */
2071 xtensa_function_arg_advance (cumulative_args_t cum
, machine_mode mode
,
2072 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2077 arg_words
= &get_cumulative_args (cum
)->arg_words
;
2078 max
= MAX_ARGS_IN_REGISTERS
;
2080 words
= (((mode
!= BLKmode
)
2081 ? (int) GET_MODE_SIZE (mode
)
2082 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2084 if (*arg_words
< max
2085 && (targetm
.calls
.must_pass_in_stack (mode
, type
)
2086 || *arg_words
+ words
> max
))
2089 *arg_words
+= words
;
2093 /* Return an RTL expression containing the register for the given mode,
2094 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2095 if this is an incoming argument to the current function. */
2098 xtensa_function_arg_1 (cumulative_args_t cum_v
, machine_mode mode
,
2099 const_tree type
, bool incoming_p
)
2101 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
2102 int regbase
, words
, max
;
2106 arg_words
= &cum
->arg_words
;
2107 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2108 max
= MAX_ARGS_IN_REGISTERS
;
2110 words
= (((mode
!= BLKmode
)
2111 ? (int) GET_MODE_SIZE (mode
)
2112 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2114 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
2116 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2117 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2120 if (*arg_words
+ words
> max
)
2123 regno
= regbase
+ *arg_words
;
2125 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2126 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
2128 return gen_rtx_REG (mode
, regno
);
2131 /* Implement TARGET_FUNCTION_ARG. */
2134 xtensa_function_arg (cumulative_args_t cum
, machine_mode mode
,
2135 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2137 return xtensa_function_arg_1 (cum
, mode
, type
, false);
2140 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2143 xtensa_function_incoming_arg (cumulative_args_t cum
, machine_mode mode
,
2144 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2146 return xtensa_function_arg_1 (cum
, mode
, type
, true);
2150 xtensa_function_arg_boundary (machine_mode mode
, const_tree type
)
2152 unsigned int alignment
;
2154 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2155 if (alignment
< PARM_BOUNDARY
)
2156 alignment
= PARM_BOUNDARY
;
2157 if (alignment
> STACK_BOUNDARY
)
2158 alignment
= STACK_BOUNDARY
;
2164 xtensa_return_in_msb (const_tree valtype
)
2166 return (TARGET_BIG_ENDIAN
2167 && AGGREGATE_TYPE_P (valtype
)
2168 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2173 xtensa_option_override (void)
2178 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2179 error ("boolean registers required for the floating-point option");
2181 /* Set up array giving whether a given register can hold a given mode. */
2182 for (mode
= VOIDmode
;
2183 mode
!= MAX_MACHINE_MODE
;
2184 mode
= (machine_mode
) ((int) mode
+ 1))
2186 int size
= GET_MODE_SIZE (mode
);
2187 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2189 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2193 if (ACC_REG_P (regno
))
2194 temp
= (TARGET_MAC16
2195 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2196 else if (GP_REG_P (regno
))
2197 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2198 else if (FP_REG_P (regno
))
2199 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2200 else if (BR_REG_P (regno
))
2201 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2205 xtensa_hard_regno_mode_ok
[(int) mode
][regno
] = temp
;
2209 init_machine_status
= xtensa_init_machine_status
;
2211 /* Check PIC settings. PIC is only supported when using L32R
2212 instructions, and some targets need to always use PIC. */
2213 if (flag_pic
&& TARGET_CONST16
)
2214 error ("-f%s is not supported with CONST16 instructions",
2215 (flag_pic
> 1 ? "PIC" : "pic"));
2216 else if (TARGET_FORCE_NO_PIC
)
2218 else if (XTENSA_ALWAYS_PIC
)
2221 error ("PIC is required but not supported with CONST16 instructions");
2224 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2227 if (flag_pic
&& !flag_pie
)
2230 /* Hot/cold partitioning does not work on this architecture, because of
2231 constant pools (the load instruction cannot necessarily reach that far).
2232 Therefore disable it on this architecture. */
2233 if (flag_reorder_blocks_and_partition
)
2235 flag_reorder_blocks_and_partition
= 0;
2236 flag_reorder_blocks
= 1;
2240 /* A C compound statement to output to stdio stream STREAM the
2241 assembler syntax for an instruction operand X. X is an RTL
2244 CODE is a value that can be used to specify one of several ways
2245 of printing the operand. It is used when identical operands
2246 must be printed differently depending on the context. CODE
2247 comes from the '%' specification that was used to request
2248 printing of the operand. If the specification was just '%DIGIT'
2249 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2250 is the ASCII code for LTR.
2252 If X is a register, this macro should print the register's name.
2253 The names can be found in an array 'reg_names' whose type is
2254 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2256 When the machine description has a specification '%PUNCT' (a '%'
2257 followed by a punctuation character), this macro is called with
2258 a null pointer for X and the punctuation character for CODE.
2260 'a', 'c', 'l', and 'n' are reserved.
2262 The Xtensa specific codes are:
2264 'd' CONST_INT, print as signed decimal
2265 'x' CONST_INT, print as signed hexadecimal
2266 'K' CONST_INT, print number of bits in mask for EXTUI
2267 'R' CONST_INT, print (X & 0x1f)
2268 'L' CONST_INT, print ((32 - X) & 0x1f)
2269 'D' REG, print second register of double-word register operand
2270 'N' MEM, print address of next word following a memory operand
2271 'v' MEM, if memory reference is volatile, output a MEMW before it
2272 't' any constant, add "@h" suffix for top 16 bits
2273 'b' any constant, add "@l" suffix for bottom 16 bits
2277 printx (FILE *file
, signed int val
)
2279 /* Print a hexadecimal value in a nice way. */
2280 if ((val
> -0xa) && (val
< 0xa))
2281 fprintf (file
, "%d", val
);
2283 fprintf (file
, "-0x%x", -val
);
2285 fprintf (file
, "0x%x", val
);
2290 print_operand (FILE *file
, rtx x
, int letter
)
2293 error ("PRINT_OPERAND null pointer");
2298 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2299 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2301 output_operand_lossage ("invalid %%D value");
2305 if (GET_CODE (x
) == MEM
)
2307 /* For a volatile memory reference, emit a MEMW before the
2309 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2310 fprintf (file
, "memw\n\t");
2313 output_operand_lossage ("invalid %%v value");
2317 if (GET_CODE (x
) == MEM
2318 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2320 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? SFmode
: SImode
, 4);
2321 output_address (GET_MODE (x
), XEXP (x
, 0));
2324 output_operand_lossage ("invalid %%N value");
2328 if (GET_CODE (x
) == CONST_INT
)
2331 unsigned val
= INTVAL (x
);
2337 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2338 fatal_insn ("invalid mask", x
);
2340 fprintf (file
, "%d", num_bits
);
2343 output_operand_lossage ("invalid %%K value");
2347 if (GET_CODE (x
) == CONST_INT
)
2348 fprintf (file
, "%ld", (32 - INTVAL (x
)) & 0x1f);
2350 output_operand_lossage ("invalid %%L value");
2354 if (GET_CODE (x
) == CONST_INT
)
2355 fprintf (file
, "%ld", INTVAL (x
) & 0x1f);
2357 output_operand_lossage ("invalid %%R value");
2361 if (GET_CODE (x
) == CONST_INT
)
2362 printx (file
, INTVAL (x
));
2364 output_operand_lossage ("invalid %%x value");
2368 if (GET_CODE (x
) == CONST_INT
)
2369 fprintf (file
, "%ld", INTVAL (x
));
2371 output_operand_lossage ("invalid %%d value");
2376 if (GET_CODE (x
) == CONST_INT
)
2378 printx (file
, INTVAL (x
));
2379 fputs (letter
== 't' ? "@h" : "@l", file
);
2381 else if (GET_CODE (x
) == CONST_DOUBLE
)
2383 if (GET_MODE (x
) == SFmode
)
2386 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2387 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2390 output_operand_lossage ("invalid %%t/%%b value");
2392 else if (GET_CODE (x
) == CONST
)
2394 /* X must be a symbolic constant on ELF. Write an expression
2395 suitable for 'const16' that sets the high or low 16 bits. */
2396 if (GET_CODE (XEXP (x
, 0)) != PLUS
2397 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2398 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2399 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2400 output_operand_lossage ("invalid %%t/%%b value");
2401 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2402 fputs (letter
== 't' ? "@h" : "@l", file
);
2403 /* There must be a non-alphanumeric character between 'h' or 'l'
2404 and the number. The '-' is added by print_operand() already. */
2405 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2407 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2411 output_addr_const (file
, x
);
2412 fputs (letter
== 't' ? "@h" : "@l", file
);
2417 if (GET_CODE (x
) == CONST_DOUBLE
&&
2418 GET_MODE (x
) == SFmode
)
2421 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
2422 fprintf (file
, "0x%08lx", l
);
2429 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2430 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2431 else if (GET_CODE (x
) == MEM
)
2432 output_address (GET_MODE (x
), XEXP (x
, 0));
2433 else if (GET_CODE (x
) == CONST_INT
)
2434 fprintf (file
, "%ld", INTVAL (x
));
2436 output_addr_const (file
, x
);
2441 /* A C compound statement to output to stdio stream STREAM the
2442 assembler syntax for an instruction operand that is a memory
2443 reference whose address is ADDR. ADDR is an RTL expression. */
2446 print_operand_address (FILE *file
, rtx addr
)
2449 error ("PRINT_OPERAND_ADDRESS, null pointer");
2451 switch (GET_CODE (addr
))
2454 fatal_insn ("invalid address", addr
);
2458 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2464 rtx offset
= (rtx
)0;
2465 rtx arg0
= XEXP (addr
, 0);
2466 rtx arg1
= XEXP (addr
, 1);
2468 if (GET_CODE (arg0
) == REG
)
2473 else if (GET_CODE (arg1
) == REG
)
2479 fatal_insn ("no register in address", addr
);
2481 if (CONSTANT_P (offset
))
2483 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2484 output_addr_const (file
, offset
);
2487 fatal_insn ("address offset not a constant", addr
);
2495 output_addr_const (file
, addr
);
2500 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2503 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2505 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2507 switch (XINT (x
, 1))
2510 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2511 fputs ("@TPOFF", fp
);
2514 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2515 fputs ("@DTPOFF", fp
);
2520 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2534 xtensa_output_literal (FILE *file
, rtx x
, machine_mode mode
, int labelno
)
2540 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2542 switch (GET_MODE_CLASS (mode
))
2545 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
2550 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
),
2552 if (HOST_BITS_PER_LONG
> 32)
2553 value_long
[0] &= 0xffffffff;
2554 fprintf (file
, "0x%08lx\n", value_long
[0]);
2558 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x
),
2560 if (HOST_BITS_PER_LONG
> 32)
2562 value_long
[0] &= 0xffffffff;
2563 value_long
[1] &= 0xffffffff;
2565 fprintf (file
, "0x%08lx, 0x%08lx\n",
2566 value_long
[0], value_long
[1]);
2576 case MODE_PARTIAL_INT
:
2577 size
= GET_MODE_SIZE (mode
);
2581 output_addr_const (file
, x
);
2586 split_double (x
, &first
, &second
);
2587 output_addr_const (file
, first
);
2589 output_addr_const (file
, second
);
2604 xtensa_call_save_reg(int regno
)
2606 if (TARGET_WINDOWED_ABI
)
2609 if (regno
== A0_REG
)
2610 return crtl
->profile
|| !crtl
->is_leaf
|| crtl
->calls_eh_return
||
2611 df_regs_ever_live_p (regno
);
2613 if (crtl
->calls_eh_return
&& regno
>= 2 && regno
< 4)
2616 return !fixed_regs
[regno
] && !call_used_regs
[regno
] &&
2617 df_regs_ever_live_p (regno
);
2620 /* Return the bytes needed to compute the frame pointer from the current
2623 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2624 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2627 compute_frame_size (int size
)
2631 /* Add space for the incoming static chain value. */
2632 if (cfun
->static_chain_decl
!= NULL
)
2633 size
+= (1 * UNITS_PER_WORD
);
2635 xtensa_callee_save_size
= 0;
2636 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2638 if (xtensa_call_save_reg(regno
))
2639 xtensa_callee_save_size
+= UNITS_PER_WORD
;
2642 xtensa_current_frame_size
=
2643 XTENSA_STACK_ALIGN (size
2644 + xtensa_callee_save_size
2645 + crtl
->outgoing_args_size
2646 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2647 xtensa_callee_save_size
= XTENSA_STACK_ALIGN (xtensa_callee_save_size
);
2648 return xtensa_current_frame_size
;
2653 xtensa_frame_pointer_required (void)
2655 /* The code to expand builtin_frame_addr and builtin_return_addr
2656 currently uses the hard_frame_pointer instead of frame_pointer.
2657 This seems wrong but maybe it's necessary for other architectures.
2658 This function is derived from the i386 code. */
2660 if (cfun
->machine
->accesses_prev_frame
)
2667 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2668 and the total number of words must be a multiple of 128 bits. */
2669 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2672 xtensa_expand_prologue (void)
2674 HOST_WIDE_INT total_size
;
2675 rtx_insn
*insn
= NULL
;
2679 total_size
= compute_frame_size (get_frame_size ());
2681 if (TARGET_WINDOWED_ABI
)
2683 if (total_size
< (1 << (12+3)))
2684 insn
= emit_insn (gen_entry (GEN_INT (total_size
)));
2687 /* Use a8 as a temporary since a0-a7 may be live. */
2688 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2689 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
2690 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2691 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2692 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
2698 HOST_WIDE_INT offset
= 0;
2700 /* -128 is a limit of single addi instruction. */
2701 if (total_size
> 0 && total_size
<= 128)
2703 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2704 GEN_INT (-total_size
)));
2705 RTX_FRAME_RELATED_P (insn
) = 1;
2706 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2707 plus_constant (Pmode
, stack_pointer_rtx
,
2709 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2710 offset
= total_size
- UNITS_PER_WORD
;
2712 else if (xtensa_callee_save_size
)
2714 /* 1020 is maximal s32i offset, if the frame is bigger than that
2715 * we move sp to the end of callee-saved save area, save and then
2716 * move it to its final location. */
2717 if (total_size
> 1024)
2719 insn
= emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2720 GEN_INT (-xtensa_callee_save_size
)));
2721 RTX_FRAME_RELATED_P (insn
) = 1;
2722 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2723 plus_constant (Pmode
, stack_pointer_rtx
,
2724 -xtensa_callee_save_size
));
2725 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2726 offset
= xtensa_callee_save_size
- UNITS_PER_WORD
;
2730 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2731 emit_move_insn (tmp_reg
, GEN_INT (total_size
));
2732 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2733 stack_pointer_rtx
, tmp_reg
));
2734 RTX_FRAME_RELATED_P (insn
) = 1;
2735 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2736 plus_constant (Pmode
, stack_pointer_rtx
,
2738 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2739 offset
= total_size
- UNITS_PER_WORD
;
2743 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2745 if (xtensa_call_save_reg(regno
))
2747 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2748 rtx mem
= gen_frame_mem (SImode
, x
);
2749 rtx reg
= gen_rtx_REG (SImode
, regno
);
2751 offset
-= UNITS_PER_WORD
;
2752 insn
= emit_move_insn (mem
, reg
);
2753 RTX_FRAME_RELATED_P (insn
) = 1;
2754 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
,
2755 gen_rtx_SET (mem
, reg
));
2758 if (total_size
> 1024)
2760 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2761 emit_move_insn (tmp_reg
, GEN_INT (total_size
-
2762 xtensa_callee_save_size
));
2763 insn
= emit_insn (gen_subsi3 (stack_pointer_rtx
,
2764 stack_pointer_rtx
, tmp_reg
));
2765 RTX_FRAME_RELATED_P (insn
) = 1;
2766 note_rtx
= gen_rtx_SET (stack_pointer_rtx
,
2767 plus_constant (Pmode
, stack_pointer_rtx
,
2768 xtensa_callee_save_size
-
2770 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2774 if (frame_pointer_needed
)
2776 if (cfun
->machine
->set_frame_ptr_insn
)
2780 push_topmost_sequence ();
2781 first
= get_insns ();
2782 pop_topmost_sequence ();
2784 /* For all instructions prior to set_frame_ptr_insn, replace
2785 hard_frame_pointer references with stack_pointer. */
2787 insn
!= cfun
->machine
->set_frame_ptr_insn
;
2788 insn
= NEXT_INSN (insn
))
2792 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2793 hard_frame_pointer_rtx
,
2795 df_insn_rescan (insn
);
2801 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2802 stack_pointer_rtx
));
2803 if (!TARGET_WINDOWED_ABI
)
2805 note_rtx
= gen_rtx_SET (hard_frame_pointer_rtx
,
2807 RTX_FRAME_RELATED_P (insn
) = 1;
2808 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2813 if (TARGET_WINDOWED_ABI
)
2815 /* Create a note to describe the CFA. Because this is only used to set
2816 DW_AT_frame_base for debug info, don't bother tracking changes through
2817 each instruction in the prologue. It just takes up space. */
2818 note_rtx
= gen_rtx_SET ((frame_pointer_needed
2819 ? hard_frame_pointer_rtx
2820 : stack_pointer_rtx
),
2821 plus_constant (Pmode
, stack_pointer_rtx
,
2823 RTX_FRAME_RELATED_P (insn
) = 1;
2824 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2829 xtensa_expand_epilogue (void)
2831 if (!TARGET_WINDOWED_ABI
)
2834 HOST_WIDE_INT offset
;
2836 if (xtensa_current_frame_size
> (frame_pointer_needed
? 127 : 1024))
2838 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2839 emit_move_insn (tmp_reg
, GEN_INT (xtensa_current_frame_size
-
2840 xtensa_callee_save_size
));
2841 emit_insn (gen_addsi3 (stack_pointer_rtx
, frame_pointer_needed
?
2842 hard_frame_pointer_rtx
: stack_pointer_rtx
,
2844 offset
= xtensa_callee_save_size
- UNITS_PER_WORD
;
2848 if (frame_pointer_needed
)
2849 emit_move_insn (stack_pointer_rtx
, hard_frame_pointer_rtx
);
2850 offset
= xtensa_current_frame_size
- UNITS_PER_WORD
;
2853 /* Prevent reordering of saved a0 update and loading it back from
2855 if (crtl
->calls_eh_return
)
2856 emit_insn (gen_blockage ());
2858 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++regno
)
2860 if (xtensa_call_save_reg(regno
))
2862 rtx x
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, GEN_INT (offset
));
2864 offset
-= UNITS_PER_WORD
;
2865 emit_move_insn (gen_rtx_REG (SImode
, regno
),
2866 gen_frame_mem (SImode
, x
));
2870 if (xtensa_current_frame_size
> 0)
2872 if (frame_pointer_needed
|| /* always reachable with addi */
2873 xtensa_current_frame_size
> 1024 ||
2874 xtensa_current_frame_size
<= 127)
2876 if (xtensa_current_frame_size
<= 127)
2877 offset
= xtensa_current_frame_size
;
2879 offset
= xtensa_callee_save_size
;
2881 emit_insn (gen_addsi3 (stack_pointer_rtx
,
2887 rtx tmp_reg
= gen_rtx_REG (Pmode
, A9_REG
);
2888 emit_move_insn (tmp_reg
, GEN_INT (xtensa_current_frame_size
));
2889 emit_insn (gen_addsi3 (stack_pointer_rtx
, stack_pointer_rtx
,
2894 if (crtl
->calls_eh_return
)
2895 emit_insn (gen_add3_insn (stack_pointer_rtx
,
2897 EH_RETURN_STACKADJ_RTX
));
2899 xtensa_current_frame_size
= 0;
2900 xtensa_callee_save_size
= 0;
2901 emit_jump_insn (gen_return ());
2905 xtensa_set_return_address (rtx address
, rtx scratch
)
2907 HOST_WIDE_INT total_size
= compute_frame_size (get_frame_size ());
2908 rtx frame
= frame_pointer_needed
?
2909 hard_frame_pointer_rtx
: stack_pointer_rtx
;
2910 rtx a0_addr
= plus_constant (Pmode
, frame
,
2911 total_size
- UNITS_PER_WORD
);
2912 rtx note
= gen_rtx_SET (gen_frame_mem (SImode
, a0_addr
),
2913 gen_rtx_REG (SImode
, A0_REG
));
2916 if (total_size
> 1024) {
2917 emit_move_insn (scratch
, GEN_INT (total_size
- UNITS_PER_WORD
));
2918 emit_insn (gen_addsi3 (scratch
, frame
, scratch
));
2922 insn
= emit_move_insn (gen_frame_mem (SImode
, a0_addr
), address
);
2923 RTX_FRAME_RELATED_P (insn
) = 1;
2924 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note
);
2928 xtensa_return_addr (int count
, rtx frame
)
2930 rtx result
, retaddr
, curaddr
, label
;
2932 if (!TARGET_WINDOWED_ABI
)
2937 return get_hard_reg_initial_val (Pmode
, A0_REG
);
2941 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
2944 rtx addr
= plus_constant (Pmode
, frame
, -4 * UNITS_PER_WORD
);
2945 addr
= memory_address (Pmode
, addr
);
2946 retaddr
= gen_reg_rtx (Pmode
);
2947 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
2950 /* The 2 most-significant bits of the return address on Xtensa hold
2951 the register window size. To get the real return address, these
2952 bits must be replaced with the high bits from some address in the
2955 /* Get the 2 high bits of a local label in the code. */
2956 curaddr
= gen_reg_rtx (Pmode
);
2957 label
= gen_label_rtx ();
2959 LABEL_PRESERVE_P (label
) = 1;
2960 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
2961 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
2962 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
2964 /* Clear the 2 high bits of the return address. */
2965 result
= gen_reg_rtx (Pmode
);
2966 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
2967 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
2969 /* Combine them to get the result. */
2970 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
2974 /* Disable the use of word-sized or smaller complex modes for structures,
2975 and for function arguments in particular, where they cause problems with
2976 register a7. The xtensa_copy_incoming_a7 function assumes that there is
2977 a single reference to an argument in a7, but with small complex modes the
2978 real and imaginary components may be extracted separately, leading to two
2979 uses of the register, only one of which would be replaced. */
2982 xtensa_member_type_forces_blk (const_tree
, machine_mode mode
)
2984 return mode
== CQImode
|| mode
== CHImode
;
2987 /* Create the va_list data type.
2989 This structure is set up by __builtin_saveregs. The __va_reg field
2990 points to a stack-allocated region holding the contents of the
2991 incoming argument registers. The __va_ndx field is an index
2992 initialized to the position of the first unnamed (variable)
2993 argument. This same index is also used to address the arguments
2994 passed in memory. Thus, the __va_stk field is initialized to point
2995 to the position of the first argument in memory offset to account
2996 for the arguments passed in registers and to account for the size
2997 of the argument registers not being 16-byte aligned. E.G., there
2998 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2999 for the first stack argument to have the maximal alignment of 16
3000 bytes, so we offset the __va_stk address by 32 bytes so that
3001 __va_stk[32] references the first argument on the stack. */
3004 xtensa_build_builtin_va_list (void)
3006 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
3008 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
3009 type_decl
= build_decl (BUILTINS_LOCATION
,
3010 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
3012 f_stk
= build_decl (BUILTINS_LOCATION
,
3013 FIELD_DECL
, get_identifier ("__va_stk"),
3015 f_reg
= build_decl (BUILTINS_LOCATION
,
3016 FIELD_DECL
, get_identifier ("__va_reg"),
3018 f_ndx
= build_decl (BUILTINS_LOCATION
,
3019 FIELD_DECL
, get_identifier ("__va_ndx"),
3022 DECL_FIELD_CONTEXT (f_stk
) = record
;
3023 DECL_FIELD_CONTEXT (f_reg
) = record
;
3024 DECL_FIELD_CONTEXT (f_ndx
) = record
;
3026 TYPE_STUB_DECL (record
) = type_decl
;
3027 TYPE_NAME (record
) = type_decl
;
3028 TYPE_FIELDS (record
) = f_stk
;
3029 DECL_CHAIN (f_stk
) = f_reg
;
3030 DECL_CHAIN (f_reg
) = f_ndx
;
3032 layout_type (record
);
3037 /* Save the incoming argument registers on the stack. Returns the
3038 address of the saved registers. */
3041 xtensa_builtin_saveregs (void)
3044 int arg_words
= crtl
->args
.info
.arg_words
;
3045 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
3050 /* Allocate the general-purpose register space. */
3051 gp_regs
= assign_stack_local
3052 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
3053 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
3055 /* Now store the incoming registers. */
3056 cfun
->machine
->need_a7_copy
= TARGET_WINDOWED_ABI
;
3057 cfun
->machine
->vararg_a7
= true;
3058 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
3059 adjust_address (gp_regs
, BLKmode
,
3060 arg_words
* UNITS_PER_WORD
),
3062 if (cfun
->machine
->vararg_a7_copy
!= 0)
3063 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
3065 return XEXP (gp_regs
, 0);
3069 /* Implement `va_start' for varargs and stdarg. We look at the
3070 current function to fill in an initial va_list. */
3073 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
3081 arg_words
= crtl
->args
.info
.arg_words
;
3083 f_stk
= TYPE_FIELDS (va_list_type_node
);
3084 f_reg
= DECL_CHAIN (f_stk
);
3085 f_ndx
= DECL_CHAIN (f_reg
);
3087 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
3088 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3090 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3093 /* Call __builtin_saveregs; save the result in __va_reg */
3094 u
= make_tree (sizetype
, expand_builtin_saveregs ());
3095 u
= fold_convert (ptr_type_node
, u
);
3096 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
3097 TREE_SIDE_EFFECTS (t
) = 1;
3098 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3100 /* Set the __va_stk member to ($arg_ptr - 32). */
3101 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
3102 u
= fold_build_pointer_plus_hwi (u
, -32);
3103 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
3104 TREE_SIDE_EFFECTS (t
) = 1;
3105 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3107 /* Set the __va_ndx member. If the first variable argument is on
3108 the stack, adjust __va_ndx by 2 words to account for the extra
3109 alignment offset for __va_stk. */
3110 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
3112 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
3113 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
3114 TREE_SIDE_EFFECTS (t
) = 1;
3115 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
3119 /* Implement `va_arg'. */
3122 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
3123 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
3128 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
3129 tree lab_false
, lab_over
, lab_false2
;
3132 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
3134 type
= build_pointer_type (type
);
3136 /* Handle complex values as separate real and imaginary parts. */
3137 if (TREE_CODE (type
) == COMPLEX_TYPE
)
3139 tree real_part
, imag_part
;
3141 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
3143 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
3145 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
3148 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
3150 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
3153 f_stk
= TYPE_FIELDS (va_list_type_node
);
3154 f_reg
= DECL_CHAIN (f_stk
);
3155 f_ndx
= DECL_CHAIN (f_reg
);
3157 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
3159 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
3161 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
3164 type_size
= size_in_bytes (type
);
3165 va_size
= round_up (type_size
, UNITS_PER_WORD
);
3166 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
3169 /* First align __va_ndx if necessary for this arg:
3171 orig_ndx = (AP).__va_ndx;
3172 if (__alignof__ (TYPE) > 4 )
3173 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3174 & -__alignof__ (TYPE)); */
3176 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
3178 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
3180 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
3182 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
3183 build_int_cst (integer_type_node
, align
- 1));
3184 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
3185 build_int_cst (integer_type_node
, -align
));
3186 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
3190 /* Increment __va_ndx to point past the argument:
3192 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3194 t
= fold_convert (integer_type_node
, va_size
);
3195 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
3196 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3199 /* Check if the argument is in registers:
3201 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3202 && !must_pass_in_stack (type))
3203 __array = (AP).__va_reg; */
3205 array
= create_tmp_var (ptr_type_node
);
3208 if (!targetm
.calls
.must_pass_in_stack (TYPE_MODE (type
), type
))
3210 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
3211 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
3213 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
3214 build_int_cst (integer_type_node
,
3215 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3216 t
= build3 (COND_EXPR
, void_type_node
, t
,
3217 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
3219 gimplify_and_add (t
, pre_p
);
3221 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
3223 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
3224 gimplify_and_add (t
, pre_p
);
3226 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
3227 gimplify_and_add (t
, pre_p
);
3231 /* ...otherwise, the argument is on the stack (never split between
3232 registers and the stack -- change __va_ndx if necessary):
3236 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3237 (AP).__va_ndx = 32 + __va_size (TYPE);
3238 __array = (AP).__va_stk;
3241 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
3243 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
3244 build_int_cst (integer_type_node
,
3245 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
3246 t
= build3 (COND_EXPR
, void_type_node
, t
,
3247 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
3249 gimplify_and_add (t
, pre_p
);
3251 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
3252 t
= fold_convert (integer_type_node
, t
);
3253 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
3255 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
3256 gimplify_and_add (t
, pre_p
);
3258 gimplify_assign (array
, stk
, pre_p
);
3262 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
3263 gimplify_and_add (t
, pre_p
);
3267 /* Given the base array pointer (__array) and index to the subsequent
3268 argument (__va_ndx), find the address:
3270 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3274 The results are endian-dependent because values smaller than one word
3275 are aligned differently. */
3278 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
3280 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
3281 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
3282 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
3283 unshare_expr (type_size
));
3287 size
= unshare_expr (va_size
);
3289 t
= fold_convert (sizetype
, unshare_expr (ndx
));
3290 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
3291 addr
= fold_build_pointer_plus (unshare_expr (array
), t
);
3293 addr
= fold_convert (build_pointer_type (type
), addr
);
3295 addr
= build_va_arg_indirect_ref (addr
);
3296 return build_va_arg_indirect_ref (addr
);
3304 XTENSA_BUILTIN_UMULSIDI3
,
3310 xtensa_init_builtins (void)
3314 ftype
= build_function_type_list (unsigned_intDI_type_node
,
3315 unsigned_intSI_type_node
,
3316 unsigned_intSI_type_node
, NULL_TREE
);
3318 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
3319 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
3320 "__umulsidi3", NULL_TREE
);
3321 TREE_NOTHROW (decl
) = 1;
3322 TREE_READONLY (decl
) = 1;
3327 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3328 bool ignore ATTRIBUTE_UNUSED
)
3330 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3335 case XTENSA_BUILTIN_UMULSIDI3
:
3338 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3339 || TARGET_MUL32_HIGH
)
3340 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3341 fold_convert (unsigned_intDI_type_node
, arg0
),
3342 fold_convert (unsigned_intDI_type_node
, arg1
));
3346 internal_error ("bad builtin code");
3355 xtensa_expand_builtin (tree exp
, rtx target
,
3356 rtx subtarget ATTRIBUTE_UNUSED
,
3357 machine_mode mode ATTRIBUTE_UNUSED
,
3360 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3361 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3365 case XTENSA_BUILTIN_UMULSIDI3
:
3366 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3367 __umulsidi3 function when the Xtensa configuration can directly
3368 implement it. If not, just call the function. */
3369 return expand_call (exp
, target
, ignore
);
3372 internal_error ("bad builtin code");
3377 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3380 xtensa_preferred_reload_class (rtx x
, reg_class_t rclass
)
3382 if (CONSTANT_P (x
) && CONST_DOUBLE_P (x
))
3385 /* Don't use the stack pointer or hard frame pointer for reloads!
3386 The hard frame pointer would normally be OK except that it may
3387 briefly hold an incoming argument in the prologue, and reload
3388 won't know that it is live because the hard frame pointer is
3389 treated specially. */
3391 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3397 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3400 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED
,
3403 /* Don't use the stack pointer or hard frame pointer for reloads!
3404 The hard frame pointer would normally be OK except that it may
3405 briefly hold an incoming argument in the prologue, and reload
3406 won't know that it is live because the hard frame pointer is
3407 treated specially. */
3409 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3415 /* Worker function for TARGET_SECONDARY_RELOAD. */
3418 xtensa_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass
,
3419 machine_mode mode
, secondary_reload_info
*sri
)
3423 if (in_p
&& constantpool_mem_p (x
))
3425 if (rclass
== FP_REGS
)
3429 sri
->icode
= CODE_FOR_reloadqi_literal
;
3430 else if (mode
== HImode
)
3431 sri
->icode
= CODE_FOR_reloadhi_literal
;
3434 regno
= xt_true_regnum (x
);
3435 if (ACC_REG_P (regno
))
3436 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3437 if (rclass
== ACC_REG
)
3438 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3445 order_regs_for_local_alloc (void)
3447 if (!leaf_function_p ())
3449 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
3451 static const int reg_nonleaf_alloc_order_call0
[FIRST_PSEUDO_REGISTER
] =
3453 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
3455 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
3460 memcpy (reg_alloc_order
, TARGET_WINDOWED_ABI
?
3461 reg_nonleaf_alloc_order
: reg_nonleaf_alloc_order_call0
,
3462 FIRST_PSEUDO_REGISTER
* sizeof (int));
3466 int i
, num_arg_regs
;
3469 /* Use the AR registers in increasing order (skipping a0 and a1)
3470 but save the incoming argument registers for a last resort. */
3471 num_arg_regs
= crtl
->args
.info
.arg_words
;
3472 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
3473 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
3474 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
3475 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
3476 for (i
= 0; i
< num_arg_regs
; i
++)
3477 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
3479 /* List the coprocessor registers in order. */
3480 for (i
= 0; i
< BR_REG_NUM
; i
++)
3481 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
3483 /* List the FP registers in order for now. */
3484 for (i
= 0; i
< 16; i
++)
3485 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
3487 /* GCC requires that we list *all* the registers.... */
3488 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
3489 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
3490 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
3491 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
3493 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
3498 /* Some Xtensa targets support multiple bss sections. If the section
3499 name ends with ".bss", add SECTION_BSS to the flags. */
3502 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
3504 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
3507 suffix
= strrchr (name
, '.');
3508 if (suffix
&& strcmp (suffix
, ".bss") == 0)
3510 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
3511 && DECL_INITIAL (decl
) == NULL_TREE
))
3512 flags
|= SECTION_BSS
; /* @nobits */
3514 warning (0, "only uninitialized variables can be placed in a "
3522 /* The literal pool stays with the function. */
3525 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED
,
3526 rtx x ATTRIBUTE_UNUSED
,
3527 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
3529 return function_section (current_function_decl
);
3532 /* Worker function for TARGET_REGISTER_MOVE_COST. */
3535 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3536 reg_class_t from
, reg_class_t to
)
3538 if (from
== to
&& from
!= BR_REGS
&& to
!= BR_REGS
)
3540 else if (reg_class_subset_p (from
, AR_REGS
)
3541 && reg_class_subset_p (to
, AR_REGS
))
3543 else if (reg_class_subset_p (from
, AR_REGS
) && to
== ACC_REG
)
3545 else if (from
== ACC_REG
&& reg_class_subset_p (to
, AR_REGS
))
3551 /* Worker function for TARGET_MEMORY_MOVE_COST. */
3554 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED
,
3555 reg_class_t rclass ATTRIBUTE_UNUSED
,
3556 bool in ATTRIBUTE_UNUSED
)
3561 /* Compute a (partial) cost for rtx X. Return true if the complete
3562 cost has been computed, and false if subexpressions should be
3563 scanned. In either case, *TOTAL contains the cost result. */
3566 xtensa_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
3567 int opno ATTRIBUTE_UNUSED
,
3568 int *total
, bool speed ATTRIBUTE_UNUSED
)
3570 int code
= GET_CODE (x
);
3578 if (xtensa_simm12b (INTVAL (x
)))
3585 if (xtensa_simm8 (INTVAL (x
))
3586 || xtensa_simm8x256 (INTVAL (x
)))
3593 if (xtensa_mask_immediate (INTVAL (x
)))
3600 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
3611 /* No way to tell if X is the 2nd operand so be conservative. */
3614 if (xtensa_simm12b (INTVAL (x
)))
3616 else if (TARGET_CONST16
)
3617 *total
= COSTS_N_INSNS (2);
3626 *total
= COSTS_N_INSNS (2);
3633 *total
= COSTS_N_INSNS (4);
3641 (GET_MODE_SIZE (mode
) > UNITS_PER_WORD
) ? 2 : 1;
3643 if (memory_address_p (mode
, XEXP ((x
), 0)))
3644 *total
= COSTS_N_INSNS (num_words
);
3646 *total
= COSTS_N_INSNS (2*num_words
);
3652 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
3656 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
3660 *total
= COSTS_N_INSNS (mode
== DImode
? 3 : 2);
3667 *total
= COSTS_N_INSNS (2);
3669 *total
= COSTS_N_INSNS (1);
3676 *total
= COSTS_N_INSNS (50);
3678 *total
= COSTS_N_INSNS (1);
3684 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3685 else if (mode
== DFmode
)
3686 *total
= COSTS_N_INSNS (50);
3688 *total
= COSTS_N_INSNS (4);
3696 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3697 else if (mode
== DFmode
|| mode
== DImode
)
3698 *total
= COSTS_N_INSNS (50);
3700 *total
= COSTS_N_INSNS (1);
3705 *total
= COSTS_N_INSNS (mode
== DImode
? 4 : 2);
3711 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3712 else if (mode
== DFmode
)
3713 *total
= COSTS_N_INSNS (50);
3714 else if (mode
== DImode
)
3715 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
3716 else if (TARGET_MUL32
)
3717 *total
= COSTS_N_INSNS (4);
3718 else if (TARGET_MAC16
)
3719 *total
= COSTS_N_INSNS (16);
3720 else if (TARGET_MUL16
)
3721 *total
= COSTS_N_INSNS (12);
3723 *total
= COSTS_N_INSNS (50);
3732 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3735 else if (mode
== DFmode
)
3737 *total
= COSTS_N_INSNS (50);
3747 *total
= COSTS_N_INSNS (50);
3748 else if (TARGET_DIV32
)
3749 *total
= COSTS_N_INSNS (32);
3751 *total
= COSTS_N_INSNS (50);
3757 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3759 *total
= COSTS_N_INSNS (50);
3766 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3771 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3776 *total
= COSTS_N_INSNS (1);
3784 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3787 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3789 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
3790 > 4 * UNITS_PER_WORD
);
3793 /* Worker function for TARGET_FUNCTION_VALUE. */
3796 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
3799 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
3800 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
3801 ? SImode
: TYPE_MODE (valtype
),
3802 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
3805 /* Worker function for TARGET_LIBCALL_VALUE. */
3808 xtensa_libcall_value (machine_mode mode
, const_rtx fun ATTRIBUTE_UNUSED
)
3810 return gen_rtx_REG ((GET_MODE_CLASS (mode
) == MODE_INT
3811 && GET_MODE_SIZE (mode
) < UNITS_PER_WORD
)
3812 ? SImode
: mode
, GP_RETURN
);
3815 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
3818 xtensa_function_value_regno_p (const unsigned int regno
)
3820 return (regno
== GP_RETURN
);
3823 /* The static chain is passed in memory. Provide rtx giving 'mem'
3824 expressions that denote where they are stored. */
3827 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl_or_type
), bool incoming_p
)
3829 if (TARGET_WINDOWED_ABI
)
3831 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
3832 return gen_frame_mem (Pmode
, plus_constant (Pmode
, base
,
3833 -5 * UNITS_PER_WORD
));
3836 return gen_rtx_REG (Pmode
, A8_REG
);
3840 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3841 instruction with a minimal stack frame in order to get some free
3842 registers. Once the actual call target is known, the proper stack frame
3843 size is extracted from the ENTRY instruction at the target and the
3844 current frame is adjusted to match. The trampoline then transfers
3845 control to the instruction following the ENTRY at the target. Note:
3846 this assumes that the target begins with an ENTRY instruction. */
3849 xtensa_asm_trampoline_template (FILE *stream
)
3851 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3853 fprintf (stream
, "\t.begin no-transform\n");
3855 if (TARGET_WINDOWED_ABI
)
3857 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
3861 /* Save the return address. */
3862 fprintf (stream
, "\tmov\ta10, a0\n");
3864 /* Use a CALL0 instruction to skip past the constants and in the
3865 process get the PC into A0. This allows PC-relative access to
3866 the constants without relying on L32R. */
3867 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
3870 fprintf (stream
, "\tj\t.Lskipconsts\n");
3872 fprintf (stream
, "\t.align\t4\n");
3873 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
3874 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
3875 fprintf (stream
, ".Lskipconsts:\n");
3877 /* Load the static chain and function address from the trampoline. */
3880 fprintf (stream
, "\taddi\ta0, a0, 3\n");
3881 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
3882 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
3886 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
3887 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
3890 /* Store the static chain. */
3891 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
3893 /* Set the proper stack pointer value. */
3894 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
3895 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
3896 TARGET_BIG_ENDIAN
? 8 : 12);
3897 fprintf (stream
, "\tslli\ta9, a9, 3\n");
3898 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
3899 fprintf (stream
, "\tsub\ta9, sp, a9\n");
3900 fprintf (stream
, "\tmovsp\tsp, a9\n");
3903 /* Restore the return address. */
3904 fprintf (stream
, "\tmov\ta0, a10\n");
3906 /* Jump to the instruction following the ENTRY. */
3907 fprintf (stream
, "\taddi\ta8, a8, 3\n");
3908 fprintf (stream
, "\tjx\ta8\n");
3910 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3912 fprintf (stream
, "\t.byte\t0\n");
3914 fprintf (stream
, "\tnop\n");
3920 /* Save the return address. */
3921 fprintf (stream
, "\tmov\ta10, a0\n");
3923 /* Use a CALL0 instruction to skip past the constants and in the
3924 process get the PC into A0. This allows PC-relative access to
3925 the constants without relying on L32R. */
3926 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
3929 fprintf (stream
, "\tj\t.Lskipconsts\n");
3931 fprintf (stream
, "\t.align\t4\n");
3932 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
3933 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
3934 fprintf (stream
, ".Lskipconsts:\n");
3936 /* Load the static chain and function address from the trampoline. */
3939 fprintf (stream
, "\taddi\ta0, a0, 3\n");
3940 fprintf (stream
, "\tl32i\ta8, a0, 0\n");
3941 fprintf (stream
, "\tl32i\ta9, a0, 4\n");
3942 fprintf (stream
, "\tmov\ta0, a10\n");
3946 fprintf (stream
, "\tl32r\ta8, .Lchainval\n");
3947 fprintf (stream
, "\tl32r\ta9, .Lfnaddr\n");
3949 fprintf (stream
, "\tjx\ta9\n");
3951 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3953 fprintf (stream
, "\t.byte\t0\n");
3955 fprintf (stream
, "\tnop\n");
3957 fprintf (stream
, "\t.end no-transform\n");
3961 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
3963 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
3964 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3968 if (TARGET_WINDOWED_ABI
)
3970 chain_off
= use_call0
? 12 : 8;
3971 func_off
= use_call0
? 16 : 12;
3975 chain_off
= use_call0
? 8 : 4;
3976 func_off
= use_call0
? 12 : 8;
3979 emit_block_move (m_tramp
, assemble_trampoline_template (),
3980 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3982 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
3983 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
3984 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
3985 LCT_NORMAL
, VOIDmode
, 1, XEXP (m_tramp
, 0), Pmode
);
3988 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
3991 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED
, rtx x
)
3993 return !xtensa_tls_referenced_p (x
);
3996 /* Implement TARGET_CAN_USE_DOLOOP_P. */
3999 xtensa_can_use_doloop_p (const widest_int
&, const widest_int
&,
4000 unsigned int loop_depth
, bool entered_at_top
)
4002 /* Considering limitations in the hardware, only use doloop
4003 for innermost loops which must be entered from the top. */
4004 if (loop_depth
> 1 || !entered_at_top
)
4010 /* NULL if INSN insn is valid within a low-overhead loop.
4011 Otherwise return why doloop cannot be applied. */
4014 xtensa_invalid_within_doloop (const rtx_insn
*insn
)
4017 return "Function call in the loop.";
4019 if (JUMP_P (insn
) && INSN_CODE (insn
) == CODE_FOR_return
)
4020 return "Return from a call instruction in the loop.";
4025 /* Optimize LOOP. */
4030 hwloop_optimize (hwloop_info loop
)
4034 basic_block entry_bb
;
4036 rtx_insn
*insn
, *seq
, *entry_after
;
4038 if (loop
->depth
> 1)
4041 fprintf (dump_file
, ";; loop %d is not innermost\n",
4046 if (!loop
->incoming_dest
)
4049 fprintf (dump_file
, ";; loop %d has more than one entry\n",
4054 if (loop
->incoming_dest
!= loop
->head
)
4057 fprintf (dump_file
, ";; loop %d is not entered from head\n",
4062 if (loop
->has_call
|| loop
->has_asm
)
4065 fprintf (dump_file
, ";; loop %d has invalid insn\n",
4070 /* Scan all the blocks to make sure they don't use iter_reg. */
4071 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
4074 fprintf (dump_file
, ";; loop %d uses iterator\n",
4079 /* Check if start_label appears before doloop_end. */
4080 insn
= loop
->start_label
;
4081 while (insn
&& insn
!= loop
->loop_end
)
4082 insn
= NEXT_INSN (insn
);
4087 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
4092 /* Get the loop iteration register. */
4093 iter_reg
= loop
->iter_reg
;
4095 gcc_assert (REG_P (iter_reg
));
4099 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
4100 if (entry_edge
->flags
& EDGE_FALLTHRU
)
4103 if (entry_edge
== NULL
)
4106 /* Place the zero_cost_loop_start instruction before the loop. */
4107 entry_bb
= entry_edge
->src
;
4111 insn
= emit_insn (gen_zero_cost_loop_start (loop
->iter_reg
,
4117 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1)
4123 emit_insn_before (seq
, BB_HEAD (loop
->head
));
4124 seq
= emit_label_before (gen_label_rtx (), seq
);
4125 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
4126 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
4128 if (!(e
->flags
& EDGE_FALLTHRU
))
4129 redirect_edge_and_branch_force (e
, new_bb
);
4131 redirect_edge_succ (e
, new_bb
);
4134 make_edge (new_bb
, loop
->head
, 0);
4138 entry_after
= BB_END (entry_bb
);
4139 while (DEBUG_INSN_P (entry_after
)
4140 || (NOTE_P (entry_after
)
4141 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
))
4142 entry_after
= PREV_INSN (entry_after
);
4144 emit_insn_after (seq
, entry_after
);
4152 /* A callback for the hw-doloop pass. Called when a loop we have discovered
4153 turns out not to be optimizable; we have to split the loop_end pattern into
4154 a subtract and a test. */
4157 hwloop_fail (hwloop_info loop
)
4160 rtx_insn
*insn
= loop
->loop_end
;
4162 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
4167 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
4168 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
4169 loop
->iter_reg
, const0_rtx
,
4173 JUMP_LABEL (insn
) = loop
->start_label
;
4174 LABEL_NUSES (loop
->start_label
)++;
4175 delete_insn (loop
->loop_end
);
4178 /* A callback for the hw-doloop pass. This function examines INSN; if
4179 it is a doloop_end pattern we recognize, return the reg rtx for the
4180 loop counter. Otherwise, return NULL_RTX. */
4183 hwloop_pattern_reg (rtx_insn
*insn
)
4187 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
4190 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
4198 static struct hw_doloop_hooks xtensa_doloop_hooks
=
4205 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
4206 and tries to rewrite the RTL of these loops so that proper Xtensa
4207 hardware loops are generated. */
4210 xtensa_reorg_loops (void)
4212 reorg_loops (false, &xtensa_doloop_hooks
);
4216 xtensa_reorg_loops (void)
4221 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4226 /* We are freeing block_for_insn in the toplev to keep compatibility
4227 with old MDEP_REORGS that are not CFG based. Recompute it now. */
4228 compute_bb_for_insn ();
4232 /* Doloop optimization. */
4233 xtensa_reorg_loops ();
4236 /* Update register usage after having seen the compiler flags. */
4239 xtensa_conditional_register_usage (void)
4243 c_mask
= TARGET_WINDOWED_ABI
? (1 << 1) : (1 << 2);
4245 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
4247 /* Set/reset conditionally defined registers from
4248 CALL_USED_REGISTERS initializer. */
4249 if (call_used_regs
[i
] > 1)
4250 call_used_regs
[i
] = !!(call_used_regs
[i
] & c_mask
);
4253 /* Remove hard FP register from the preferred reload registers set. */
4254 CLEAR_HARD_REG_BIT (reg_class_contents
[(int)RL_REGS
],
4255 HARD_FRAME_POINTER_REGNUM
);
4258 /* Map hard register number to register class */
4260 enum reg_class
xtensa_regno_to_class (int regno
)
4262 static const enum reg_class regno_to_class
[FIRST_PSEUDO_REGISTER
] =
4264 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
4265 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4266 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4267 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
4268 AR_REGS
, AR_REGS
, BR_REGS
,
4269 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4270 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4271 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4272 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
4276 if (regno
== HARD_FRAME_POINTER_REGNUM
)
4279 return regno_to_class
[regno
];
4282 #include "gt-xtensa.h"