RISC-V: Error if function declared with different interrupt modes.
[official-gcc.git] / gcc / config / xtensa / xtensa.c
blob7cfe64d4289594364c8318855bd61759632c3f78
1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright (C) 2001-2018 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
10 version.
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
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 #define IN_TARGET_CODE 1
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "backend.h"
27 #include "target.h"
28 #include "rtl.h"
29 #include "tree.h"
30 #include "gimple.h"
31 #include "cfghooks.h"
32 #include "df.h"
33 #include "memmodel.h"
34 #include "tm_p.h"
35 #include "stringpool.h"
36 #include "attribs.h"
37 #include "optabs.h"
38 #include "regs.h"
39 #include "emit-rtl.h"
40 #include "recog.h"
41 #include "diagnostic-core.h"
42 #include "cfgrtl.h"
43 #include "output.h"
44 #include "fold-const.h"
45 #include "stor-layout.h"
46 #include "calls.h"
47 #include "varasm.h"
48 #include "alias.h"
49 #include "explow.h"
50 #include "expr.h"
51 #include "reload.h"
52 #include "langhooks.h"
53 #include "gimplify.h"
54 #include "builtins.h"
55 #include "dumpfile.h"
56 #include "hw-doloop.h"
57 #include "rtl-iter.h"
59 /* This file should be included last. */
60 #include "target-def.h"
62 /* Enumeration for all of the relational tests, so that we can build
63 arrays indexed by the test type, and not worry about the order
64 of EQ, NE, etc. */
66 enum internal_test
68 ITEST_EQ,
69 ITEST_NE,
70 ITEST_GT,
71 ITEST_GE,
72 ITEST_LT,
73 ITEST_LE,
74 ITEST_GTU,
75 ITEST_GEU,
76 ITEST_LTU,
77 ITEST_LEU,
78 ITEST_MAX
81 /* Array giving truth value on whether or not a given hard register
82 can support a given mode. */
83 static char xtensa_hard_regno_mode_ok_p
84 [(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
86 /* Largest block move to handle in-line. */
87 #define LARGEST_MOVE_RATIO 15
89 /* Define the structure for the machine field in struct function. */
90 struct GTY(()) machine_function
92 int accesses_prev_frame;
93 bool need_a7_copy;
94 bool vararg_a7;
95 rtx vararg_a7_copy;
96 rtx_insn *set_frame_ptr_insn;
97 /* Current frame size calculated by compute_frame_size. */
98 unsigned current_frame_size;
99 /* Callee-save area size in the current frame calculated by
100 compute_frame_size. */
101 int callee_save_size;
102 bool frame_laid_out;
103 bool epilogue_done;
106 /* Vector, indexed by hard register number, which contains 1 for a
107 register that is allowable in a candidate for leaf function
108 treatment. */
110 const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
112 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
113 1, 1, 1,
114 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
118 static void xtensa_option_override (void);
119 static enum internal_test map_test_to_internal_test (enum rtx_code);
120 static rtx gen_int_relational (enum rtx_code, rtx, rtx, int *);
121 static rtx gen_float_relational (enum rtx_code, rtx, rtx);
122 static rtx gen_conditional_move (enum rtx_code, machine_mode, rtx, rtx);
123 static rtx fixup_subreg_mem (rtx);
124 static struct machine_function * xtensa_init_machine_status (void);
125 static rtx xtensa_legitimize_tls_address (rtx);
126 static rtx xtensa_legitimize_address (rtx, rtx, machine_mode);
127 static bool xtensa_mode_dependent_address_p (const_rtx, addr_space_t);
128 static bool xtensa_return_in_msb (const_tree);
129 static void printx (FILE *, signed int);
130 static rtx xtensa_builtin_saveregs (void);
131 static bool xtensa_legitimate_address_p (machine_mode, rtx, bool);
132 static unsigned int xtensa_multibss_section_type_flags (tree, const char *,
133 int) ATTRIBUTE_UNUSED;
134 static section *xtensa_select_rtx_section (machine_mode, rtx,
135 unsigned HOST_WIDE_INT);
136 static bool xtensa_rtx_costs (rtx, machine_mode, int, int, int *, bool);
137 static int xtensa_register_move_cost (machine_mode, reg_class_t,
138 reg_class_t);
139 static int xtensa_memory_move_cost (machine_mode, reg_class_t, bool);
140 static tree xtensa_build_builtin_va_list (void);
141 static bool xtensa_return_in_memory (const_tree, const_tree);
142 static tree xtensa_gimplify_va_arg_expr (tree, tree, gimple_seq *,
143 gimple_seq *);
144 static void xtensa_function_arg_advance (cumulative_args_t, machine_mode,
145 const_tree, bool);
146 static rtx xtensa_function_arg (cumulative_args_t, machine_mode,
147 const_tree, bool);
148 static rtx xtensa_function_incoming_arg (cumulative_args_t,
149 machine_mode, const_tree, bool);
150 static rtx xtensa_function_value (const_tree, const_tree, bool);
151 static rtx xtensa_libcall_value (machine_mode, const_rtx);
152 static bool xtensa_function_value_regno_p (const unsigned int);
153 static unsigned int xtensa_function_arg_boundary (machine_mode,
154 const_tree);
155 static void xtensa_init_builtins (void);
156 static tree xtensa_fold_builtin (tree, int, tree *, bool);
157 static rtx xtensa_expand_builtin (tree, rtx, rtx, machine_mode, int);
158 static void xtensa_va_start (tree, rtx);
159 static bool xtensa_frame_pointer_required (void);
160 static rtx xtensa_static_chain (const_tree, bool);
161 static void xtensa_asm_trampoline_template (FILE *);
162 static void xtensa_trampoline_init (rtx, tree, rtx);
163 static bool xtensa_output_addr_const_extra (FILE *, rtx);
164 static bool xtensa_cannot_force_const_mem (machine_mode, rtx);
166 static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t);
167 static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t);
168 static reg_class_t xtensa_secondary_reload (bool, rtx, reg_class_t,
169 machine_mode,
170 struct secondary_reload_info *);
172 static bool constantpool_address_p (const_rtx addr);
173 static bool xtensa_legitimate_constant_p (machine_mode, rtx);
174 static void xtensa_reorg (void);
175 static bool xtensa_can_use_doloop_p (const widest_int &, const widest_int &,
176 unsigned int, bool);
177 static const char *xtensa_invalid_within_doloop (const rtx_insn *);
179 static bool xtensa_member_type_forces_blk (const_tree,
180 machine_mode mode);
182 static void xtensa_conditional_register_usage (void);
183 static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode);
184 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode);
185 static bool xtensa_modes_tieable_p (machine_mode, machine_mode);
186 static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT);
187 static HOST_WIDE_INT xtensa_starting_frame_offset (void);
188 static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void);
192 /* These hooks specify assembly directives for creating certain kinds
193 of integer object. */
195 #undef TARGET_ASM_ALIGNED_SI_OP
196 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
198 #undef TARGET_ASM_SELECT_RTX_SECTION
199 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
201 #undef TARGET_LEGITIMIZE_ADDRESS
202 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
203 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
204 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
206 #undef TARGET_REGISTER_MOVE_COST
207 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
208 #undef TARGET_MEMORY_MOVE_COST
209 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
210 #undef TARGET_RTX_COSTS
211 #define TARGET_RTX_COSTS xtensa_rtx_costs
212 #undef TARGET_ADDRESS_COST
213 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
215 #undef TARGET_MEMBER_TYPE_FORCES_BLK
216 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
218 #undef TARGET_BUILD_BUILTIN_VA_LIST
219 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
221 #undef TARGET_EXPAND_BUILTIN_VA_START
222 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
224 #undef TARGET_PROMOTE_FUNCTION_MODE
225 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
226 #undef TARGET_PROMOTE_PROTOTYPES
227 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
229 #undef TARGET_RETURN_IN_MEMORY
230 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
231 #undef TARGET_FUNCTION_VALUE
232 #define TARGET_FUNCTION_VALUE xtensa_function_value
233 #undef TARGET_LIBCALL_VALUE
234 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
235 #undef TARGET_FUNCTION_VALUE_REGNO_P
236 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
238 #undef TARGET_SPLIT_COMPLEX_ARG
239 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
240 #undef TARGET_MUST_PASS_IN_STACK
241 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
242 #undef TARGET_FUNCTION_ARG_ADVANCE
243 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
244 #undef TARGET_FUNCTION_ARG
245 #define TARGET_FUNCTION_ARG xtensa_function_arg
246 #undef TARGET_FUNCTION_INCOMING_ARG
247 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
248 #undef TARGET_FUNCTION_ARG_BOUNDARY
249 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
251 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
252 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
253 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
254 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
256 #undef TARGET_RETURN_IN_MSB
257 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
259 #undef TARGET_INIT_BUILTINS
260 #define TARGET_INIT_BUILTINS xtensa_init_builtins
261 #undef TARGET_FOLD_BUILTIN
262 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
263 #undef TARGET_EXPAND_BUILTIN
264 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
266 #undef TARGET_PREFERRED_RELOAD_CLASS
267 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
268 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
269 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
271 #undef TARGET_SECONDARY_RELOAD
272 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
274 #undef TARGET_HAVE_TLS
275 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
277 #undef TARGET_CANNOT_FORCE_CONST_MEM
278 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
280 #undef TARGET_LRA_P
281 #define TARGET_LRA_P hook_bool_void_false
283 #undef TARGET_LEGITIMATE_ADDRESS_P
284 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
286 #undef TARGET_FRAME_POINTER_REQUIRED
287 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
289 #undef TARGET_STATIC_CHAIN
290 #define TARGET_STATIC_CHAIN xtensa_static_chain
291 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
292 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
293 #undef TARGET_TRAMPOLINE_INIT
294 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
296 #undef TARGET_OPTION_OVERRIDE
297 #define TARGET_OPTION_OVERRIDE xtensa_option_override
299 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
300 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
302 #undef TARGET_LEGITIMATE_CONSTANT_P
303 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
305 #undef TARGET_MACHINE_DEPENDENT_REORG
306 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
308 #undef TARGET_CAN_USE_DOLOOP_P
309 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
311 #undef TARGET_INVALID_WITHIN_DOLOOP
312 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
314 #undef TARGET_CONDITIONAL_REGISTER_USAGE
315 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
317 #undef TARGET_HARD_REGNO_NREGS
318 #define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
319 #undef TARGET_HARD_REGNO_MODE_OK
320 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
322 #undef TARGET_MODES_TIEABLE_P
323 #define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p
325 #undef TARGET_CONSTANT_ALIGNMENT
326 #define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment
328 #undef TARGET_STARTING_FRAME_OFFSET
329 #define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset
331 #undef TARGET_ASAN_SHADOW_OFFSET
332 #define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset
334 struct gcc_target targetm = TARGET_INITIALIZER;
337 /* Functions to test Xtensa immediate operand validity. */
339 bool
340 xtensa_simm8 (HOST_WIDE_INT v)
342 return v >= -128 && v <= 127;
346 bool
347 xtensa_simm8x256 (HOST_WIDE_INT v)
349 return (v & 255) == 0 && (v >= -32768 && v <= 32512);
353 bool
354 xtensa_simm12b (HOST_WIDE_INT v)
356 return v >= -2048 && v <= 2047;
360 static bool
361 xtensa_uimm8 (HOST_WIDE_INT v)
363 return v >= 0 && v <= 255;
367 static bool
368 xtensa_uimm8x2 (HOST_WIDE_INT v)
370 return (v & 1) == 0 && (v >= 0 && v <= 510);
374 static bool
375 xtensa_uimm8x4 (HOST_WIDE_INT v)
377 return (v & 3) == 0 && (v >= 0 && v <= 1020);
381 static bool
382 xtensa_b4const (HOST_WIDE_INT v)
384 switch (v)
386 case -1:
387 case 1:
388 case 2:
389 case 3:
390 case 4:
391 case 5:
392 case 6:
393 case 7:
394 case 8:
395 case 10:
396 case 12:
397 case 16:
398 case 32:
399 case 64:
400 case 128:
401 case 256:
402 return true;
404 return false;
408 bool
409 xtensa_b4const_or_zero (HOST_WIDE_INT v)
411 if (v == 0)
412 return true;
413 return xtensa_b4const (v);
417 bool
418 xtensa_b4constu (HOST_WIDE_INT v)
420 switch (v)
422 case 32768:
423 case 65536:
424 case 2:
425 case 3:
426 case 4:
427 case 5:
428 case 6:
429 case 7:
430 case 8:
431 case 10:
432 case 12:
433 case 16:
434 case 32:
435 case 64:
436 case 128:
437 case 256:
438 return true;
440 return false;
444 bool
445 xtensa_mask_immediate (HOST_WIDE_INT v)
447 #define MAX_MASK_SIZE 16
448 int mask_size;
450 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
452 if ((v & 1) == 0)
453 return false;
454 v = v >> 1;
455 if (v == 0)
456 return true;
459 return false;
463 /* This is just like the standard true_regnum() function except that it
464 works even when reg_renumber is not initialized. */
467 xt_true_regnum (rtx x)
469 if (GET_CODE (x) == REG)
471 if (reg_renumber
472 && REGNO (x) >= FIRST_PSEUDO_REGISTER
473 && reg_renumber[REGNO (x)] >= 0)
474 return reg_renumber[REGNO (x)];
475 return REGNO (x);
477 if (GET_CODE (x) == SUBREG)
479 int base = xt_true_regnum (SUBREG_REG (x));
480 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
481 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
482 GET_MODE (SUBREG_REG (x)),
483 SUBREG_BYTE (x), GET_MODE (x));
485 return -1;
490 xtensa_valid_move (machine_mode mode, rtx *operands)
492 /* Either the destination or source must be a register, and the
493 MAC16 accumulator doesn't count. */
495 if (register_operand (operands[0], mode))
497 int dst_regnum = xt_true_regnum (operands[0]);
499 if (xtensa_tls_referenced_p (operands[1]))
500 return FALSE;
502 /* The stack pointer can only be assigned with a MOVSP opcode. */
503 if (dst_regnum == STACK_POINTER_REGNUM)
504 return !TARGET_WINDOWED_ABI
505 || (mode == SImode
506 && register_operand (operands[1], mode)
507 && !ACC_REG_P (xt_true_regnum (operands[1])));
509 if (!ACC_REG_P (dst_regnum))
510 return true;
512 if (register_operand (operands[1], mode))
514 int src_regnum = xt_true_regnum (operands[1]);
515 if (!ACC_REG_P (src_regnum))
516 return true;
518 return FALSE;
523 smalloffset_mem_p (rtx op)
525 if (GET_CODE (op) == MEM)
527 rtx addr = XEXP (op, 0);
528 if (GET_CODE (addr) == REG)
529 return BASE_REG_P (addr, 0);
530 if (GET_CODE (addr) == PLUS)
532 rtx offset = XEXP (addr, 0);
533 HOST_WIDE_INT val;
534 if (GET_CODE (offset) != CONST_INT)
535 offset = XEXP (addr, 1);
536 if (GET_CODE (offset) != CONST_INT)
537 return FALSE;
539 val = INTVAL (offset);
540 return (val & 3) == 0 && (val >= 0 && val <= 60);
543 return FALSE;
547 static bool
548 constantpool_address_p (const_rtx addr)
550 const_rtx sym = addr;
552 if (GET_CODE (addr) == CONST)
554 rtx offset;
556 /* Only handle (PLUS (SYM, OFFSET)) form. */
557 addr = XEXP (addr, 0);
558 if (GET_CODE (addr) != PLUS)
559 return false;
561 /* Make sure the address is word aligned. */
562 offset = XEXP (addr, 1);
563 if ((!CONST_INT_P (offset))
564 || ((INTVAL (offset) & 3) != 0))
565 return false;
567 sym = XEXP (addr, 0);
570 if ((GET_CODE (sym) == SYMBOL_REF)
571 && CONSTANT_POOL_ADDRESS_P (sym))
572 return true;
573 return false;
578 constantpool_mem_p (rtx op)
580 if (GET_CODE (op) == SUBREG)
581 op = SUBREG_REG (op);
582 if (GET_CODE (op) == MEM)
583 return constantpool_address_p (XEXP (op, 0));
584 return FALSE;
588 /* Return TRUE if X is a thread-local symbol. */
590 static bool
591 xtensa_tls_symbol_p (rtx x)
593 if (! TARGET_HAVE_TLS)
594 return false;
596 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
600 void
601 xtensa_extend_reg (rtx dst, rtx src)
603 rtx temp = gen_reg_rtx (SImode);
604 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
606 /* Generate paradoxical subregs as needed so that the modes match. */
607 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
608 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
610 emit_insn (gen_ashlsi3 (temp, src, shift));
611 emit_insn (gen_ashrsi3 (dst, temp, shift));
615 bool
616 xtensa_mem_offset (unsigned v, machine_mode mode)
618 switch (mode)
620 case E_BLKmode:
621 /* Handle the worst case for block moves. See xtensa_expand_block_move
622 where we emit an optimized block move operation if the block can be
623 moved in < "move_ratio" pieces. The worst case is when the block is
624 aligned but has a size of (3 mod 4) (does this happen?) so that the
625 last piece requires a byte load/store. */
626 return (xtensa_uimm8 (v)
627 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
629 case E_QImode:
630 return xtensa_uimm8 (v);
632 case E_HImode:
633 return xtensa_uimm8x2 (v);
635 case E_DImode:
636 case E_DFmode:
637 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
639 default:
640 break;
643 return xtensa_uimm8x4 (v);
647 /* Make normal rtx_code into something we can index from an array. */
649 static enum internal_test
650 map_test_to_internal_test (enum rtx_code test_code)
652 enum internal_test test = ITEST_MAX;
654 switch (test_code)
656 default: break;
657 case EQ: test = ITEST_EQ; break;
658 case NE: test = ITEST_NE; break;
659 case GT: test = ITEST_GT; break;
660 case GE: test = ITEST_GE; break;
661 case LT: test = ITEST_LT; break;
662 case LE: test = ITEST_LE; break;
663 case GTU: test = ITEST_GTU; break;
664 case GEU: test = ITEST_GEU; break;
665 case LTU: test = ITEST_LTU; break;
666 case LEU: test = ITEST_LEU; break;
669 return test;
673 /* Generate the code to compare two integer values. The return value is
674 the comparison expression. */
676 static rtx
677 gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
678 rtx cmp0, /* first operand to compare */
679 rtx cmp1, /* second operand to compare */
680 int *p_invert /* whether branch needs to reverse test */)
682 struct cmp_info
684 enum rtx_code test_code; /* test code to use in insn */
685 bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
686 int const_add; /* constant to add (convert LE -> LT) */
687 int reverse_regs; /* reverse registers in test */
688 int invert_const; /* != 0 if invert value if cmp1 is constant */
689 int invert_reg; /* != 0 if invert value if cmp1 is register */
690 int unsignedp; /* != 0 for unsigned comparisons. */
693 static struct cmp_info info[ (int)ITEST_MAX ] = {
695 { EQ, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */
696 { NE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */
698 { LT, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */
699 { GE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */
700 { LT, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */
701 { GE, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */
703 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */
704 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */
705 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */
706 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */
709 enum internal_test test;
710 machine_mode mode;
711 struct cmp_info *p_info;
713 test = map_test_to_internal_test (test_code);
714 gcc_assert (test != ITEST_MAX);
716 p_info = &info[ (int)test ];
718 mode = GET_MODE (cmp0);
719 if (mode == VOIDmode)
720 mode = GET_MODE (cmp1);
722 /* Make sure we can handle any constants given to us. */
723 if (GET_CODE (cmp1) == CONST_INT)
725 HOST_WIDE_INT value = INTVAL (cmp1);
726 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
728 /* if the immediate overflows or does not fit in the immediate field,
729 spill it to a register */
731 if ((p_info->unsignedp ?
732 (uvalue + p_info->const_add > uvalue) :
733 (value + p_info->const_add > value)) != (p_info->const_add > 0))
735 cmp1 = force_reg (mode, cmp1);
737 else if (!(p_info->const_range_p) (value + p_info->const_add))
739 cmp1 = force_reg (mode, cmp1);
742 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
744 cmp1 = force_reg (mode, cmp1);
747 /* See if we need to invert the result. */
748 *p_invert = ((GET_CODE (cmp1) == CONST_INT)
749 ? p_info->invert_const
750 : p_info->invert_reg);
752 /* Comparison to constants, may involve adding 1 to change a LT into LE.
753 Comparison between two registers, may involve switching operands. */
754 if (GET_CODE (cmp1) == CONST_INT)
756 if (p_info->const_add != 0)
757 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
760 else if (p_info->reverse_regs)
762 rtx temp = cmp0;
763 cmp0 = cmp1;
764 cmp1 = temp;
767 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
771 /* Generate the code to compare two float values. The return value is
772 the comparison expression. */
774 static rtx
775 gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
776 rtx cmp0, /* first operand to compare */
777 rtx cmp1 /* second operand to compare */)
779 rtx (*gen_fn) (rtx, rtx, rtx);
780 rtx brtmp;
781 int reverse_regs, invert;
783 switch (test_code)
785 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
786 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
787 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
788 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
789 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
790 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
791 case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
792 case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
793 case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
794 case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
795 case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
796 case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
797 case UNORDERED:
798 reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
799 case ORDERED:
800 reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
801 default:
802 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
803 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
806 if (reverse_regs)
808 rtx temp = cmp0;
809 cmp0 = cmp1;
810 cmp1 = temp;
813 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
814 emit_insn (gen_fn (brtmp, cmp0, cmp1));
816 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
820 void
821 xtensa_expand_conditional_branch (rtx *operands, machine_mode mode)
823 enum rtx_code test_code = GET_CODE (operands[0]);
824 rtx cmp0 = operands[1];
825 rtx cmp1 = operands[2];
826 rtx cmp;
827 int invert;
828 rtx label1, label2;
830 switch (mode)
832 case E_DFmode:
833 default:
834 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
836 case E_SImode:
837 invert = FALSE;
838 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
839 break;
841 case E_SFmode:
842 if (!TARGET_HARD_FLOAT)
843 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
844 cmp0, cmp1));
845 invert = FALSE;
846 cmp = gen_float_relational (test_code, cmp0, cmp1);
847 break;
850 /* Generate the branch. */
852 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
853 label2 = pc_rtx;
855 if (invert)
857 label2 = label1;
858 label1 = pc_rtx;
861 emit_jump_insn (gen_rtx_SET (pc_rtx,
862 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
863 label1,
864 label2)));
868 static rtx
869 gen_conditional_move (enum rtx_code code, machine_mode mode,
870 rtx op0, rtx op1)
872 if (mode == SImode)
874 rtx cmp;
876 /* Jump optimization calls get_condition() which canonicalizes
877 comparisons like (GE x <const>) to (GT x <const-1>).
878 Transform those comparisons back to GE, since that is the
879 comparison supported in Xtensa. We shouldn't have to
880 transform <LE x const> comparisons, because neither
881 xtensa_expand_conditional_branch() nor get_condition() will
882 produce them. */
884 if ((code == GT) && (op1 == constm1_rtx))
886 code = GE;
887 op1 = const0_rtx;
889 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
891 if (boolean_operator (cmp, VOIDmode))
893 /* Swap the operands to make const0 second. */
894 if (op0 == const0_rtx)
896 op0 = op1;
897 op1 = const0_rtx;
900 /* If not comparing against zero, emit a comparison (subtract). */
901 if (op1 != const0_rtx)
903 op0 = expand_binop (SImode, sub_optab, op0, op1,
904 0, 0, OPTAB_LIB_WIDEN);
905 op1 = const0_rtx;
908 else if (branch_operator (cmp, VOIDmode))
910 /* Swap the operands to make const0 second. */
911 if (op0 == const0_rtx)
913 op0 = op1;
914 op1 = const0_rtx;
916 switch (code)
918 case LT: code = GE; break;
919 case GE: code = LT; break;
920 default: gcc_unreachable ();
924 if (op1 != const0_rtx)
925 return 0;
927 else
928 return 0;
930 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
933 if (TARGET_HARD_FLOAT && mode == SFmode)
934 return gen_float_relational (code, op0, op1);
936 return 0;
941 xtensa_expand_conditional_move (rtx *operands, int isflt)
943 rtx dest = operands[0];
944 rtx cmp = operands[1];
945 machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
946 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
948 if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
949 XEXP (cmp, 0), XEXP (cmp, 1))))
950 return 0;
952 if (isflt)
953 gen_fn = (cmp_mode == SImode
954 ? gen_movsfcc_internal0
955 : gen_movsfcc_internal1);
956 else
957 gen_fn = (cmp_mode == SImode
958 ? gen_movsicc_internal0
959 : gen_movsicc_internal1);
961 emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
962 return 1;
967 xtensa_expand_scc (rtx operands[4], machine_mode cmp_mode)
969 rtx dest = operands[0];
970 rtx cmp;
971 rtx one_tmp, zero_tmp;
972 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
974 if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
975 operands[2], operands[3])))
976 return 0;
978 one_tmp = gen_reg_rtx (SImode);
979 zero_tmp = gen_reg_rtx (SImode);
980 emit_insn (gen_movsi (one_tmp, const_true_rtx));
981 emit_insn (gen_movsi (zero_tmp, const0_rtx));
983 gen_fn = (cmp_mode == SImode
984 ? gen_movsicc_internal0
985 : gen_movsicc_internal1);
986 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
987 return 1;
991 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
992 for the output, i.e., the input operands are twice as big as MODE. */
994 void
995 xtensa_split_operand_pair (rtx operands[4], machine_mode mode)
997 switch (GET_CODE (operands[1]))
999 case REG:
1000 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
1001 operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
1002 break;
1004 case MEM:
1005 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
1006 operands[2] = adjust_address (operands[1], mode, 0);
1007 break;
1009 case CONST_INT:
1010 case CONST_DOUBLE:
1011 split_double (operands[1], &operands[2], &operands[3]);
1012 break;
1014 default:
1015 gcc_unreachable ();
1018 switch (GET_CODE (operands[0]))
1020 case REG:
1021 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
1022 operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
1023 break;
1025 case MEM:
1026 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
1027 operands[0] = adjust_address (operands[0], mode, 0);
1028 break;
1030 default:
1031 gcc_unreachable ();
1036 /* Emit insns to move operands[1] into operands[0].
1037 Return 1 if we have written out everything that needs to be done to
1038 do the move. Otherwise, return 0 and the caller will emit the move
1039 normally. */
1042 xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
1044 rtx src = operands[1];
1046 if (CONSTANT_P (src)
1047 && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
1049 rtx dst = operands[0];
1051 if (xtensa_tls_referenced_p (src))
1053 rtx addend = NULL;
1055 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
1057 addend = XEXP (XEXP (src, 0), 1);
1058 src = XEXP (XEXP (src, 0), 0);
1061 src = xtensa_legitimize_tls_address (src);
1062 if (addend)
1064 src = gen_rtx_PLUS (mode, src, addend);
1065 src = force_operand (src, dst);
1067 emit_move_insn (dst, src);
1068 return 1;
1071 if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
1073 src = force_const_mem (SImode, src);
1074 operands[1] = src;
1077 /* PC-relative loads are always SImode, and CONST16 is only
1078 supported in the movsi pattern, so add a SUBREG for any other
1079 (smaller) mode. */
1081 if (mode != SImode)
1083 if (register_operand (dst, mode))
1085 emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
1086 return 1;
1088 else
1090 src = force_reg (SImode, src);
1091 src = gen_lowpart_SUBREG (mode, src);
1092 operands[1] = src;
1097 if (!(reload_in_progress | reload_completed)
1098 && !xtensa_valid_move (mode, operands))
1099 operands[1] = force_reg (mode, operands[1]);
1101 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1103 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1104 instruction won't be recognized after reload, so we remove the
1105 subreg and adjust mem accordingly. */
1106 if (reload_in_progress)
1108 operands[0] = fixup_subreg_mem (operands[0]);
1109 operands[1] = fixup_subreg_mem (operands[1]);
1111 return 0;
1115 static rtx
1116 fixup_subreg_mem (rtx x)
1118 if (GET_CODE (x) == SUBREG
1119 && GET_CODE (SUBREG_REG (x)) == REG
1120 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1122 rtx temp =
1123 gen_rtx_SUBREG (GET_MODE (x),
1124 reg_equiv_mem (REGNO (SUBREG_REG (x))),
1125 SUBREG_BYTE (x));
1126 x = alter_subreg (&temp, true);
1128 return x;
1132 /* Check if an incoming argument in a7 is expected to be used soon and
1133 if OPND is a register or register pair that includes a7. If so,
1134 create a new pseudo and copy a7 into that pseudo at the very
1135 beginning of the function, followed by the special "set_frame_ptr"
1136 unspec_volatile insn. The return value is either the original
1137 operand, if it is not a7, or the new pseudo containing a copy of
1138 the incoming argument. This is necessary because the register
1139 allocator will ignore conflicts with a7 and may either assign some
1140 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1141 the incoming argument in a7. By copying the argument out of a7 as
1142 the very first thing, and then immediately following that with an
1143 unspec_volatile to keep the scheduler away, we should avoid any
1144 problems. Putting the set_frame_ptr insn at the beginning, with
1145 only the a7 copy before it, also makes it easier for the prologue
1146 expander to initialize the frame pointer after the a7 copy and to
1147 fix up the a7 copy to use the stack pointer instead of the frame
1148 pointer. */
1151 xtensa_copy_incoming_a7 (rtx opnd)
1153 rtx entry_insns = 0;
1154 rtx reg, tmp;
1155 machine_mode mode;
1157 if (!cfun->machine->need_a7_copy)
1158 return opnd;
1160 /* This function should never be called again once a7 has been copied. */
1161 gcc_assert (!cfun->machine->set_frame_ptr_insn);
1163 mode = GET_MODE (opnd);
1165 /* The operand using a7 may come in a later instruction, so just return
1166 the original operand if it doesn't use a7. */
1167 reg = opnd;
1168 if (GET_CODE (reg) == SUBREG)
1170 gcc_assert (SUBREG_BYTE (reg) == 0);
1171 reg = SUBREG_REG (reg);
1173 if (GET_CODE (reg) != REG
1174 || REGNO (reg) > A7_REG
1175 || REGNO (reg) + hard_regno_nregs (A7_REG, mode) <= A7_REG)
1176 return opnd;
1178 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1179 gcc_assert (REGNO (reg) + hard_regno_nregs (A7_REG, mode) - 1 == A7_REG);
1181 cfun->machine->need_a7_copy = false;
1183 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1184 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1186 start_sequence ();
1187 tmp = gen_reg_rtx (mode);
1189 switch (mode)
1191 case E_DFmode:
1192 case E_DImode:
1193 /* Copy the value out of A7 here but keep the first word in A6 until
1194 after the set_frame_ptr insn. Otherwise, the register allocator
1195 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1196 value. */
1197 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1198 gen_raw_REG (SImode, A7_REG)));
1199 break;
1200 case E_SFmode:
1201 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1202 break;
1203 case E_SImode:
1204 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1205 break;
1206 case E_HImode:
1207 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1208 break;
1209 case E_QImode:
1210 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1211 break;
1212 default:
1213 gcc_unreachable ();
1216 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1218 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1219 if (mode == DFmode || mode == DImode)
1220 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1221 gen_rtx_REG (SImode, A7_REG - 1)));
1222 entry_insns = get_insns ();
1223 end_sequence ();
1225 if (cfun->machine->vararg_a7)
1227 /* This is called from within builtin_saveregs, which will insert the
1228 saveregs code at the function entry, ahead of anything placed at
1229 the function entry now. Instead, save the sequence to be inserted
1230 at the beginning of the saveregs code. */
1231 cfun->machine->vararg_a7_copy = entry_insns;
1233 else
1235 /* Put entry_insns after the NOTE that starts the function. If
1236 this is inside a start_sequence, make the outer-level insn
1237 chain current, so the code is placed at the start of the
1238 function. */
1239 push_topmost_sequence ();
1240 /* Do not use entry_of_function() here. This is called from within
1241 expand_function_start, when the CFG still holds GIMPLE. */
1242 emit_insn_after (entry_insns, get_insns ());
1243 pop_topmost_sequence ();
1246 return tmp;
1250 /* Try to expand a block move operation to a sequence of RTL move
1251 instructions. If not optimizing, or if the block size is not a
1252 constant, or if the block is too large, the expansion fails and GCC
1253 falls back to calling memcpy().
1255 operands[0] is the destination
1256 operands[1] is the source
1257 operands[2] is the length
1258 operands[3] is the alignment */
1261 xtensa_expand_block_move (rtx *operands)
1263 static const machine_mode mode_from_align[] =
1265 VOIDmode, QImode, HImode, VOIDmode, SImode,
1268 rtx dst_mem = operands[0];
1269 rtx src_mem = operands[1];
1270 HOST_WIDE_INT bytes, align;
1271 int num_pieces, move_ratio;
1272 rtx temp[2];
1273 machine_mode mode[2];
1274 int amount[2];
1275 bool active[2];
1276 int phase = 0;
1277 int next;
1278 int offset_ld = 0;
1279 int offset_st = 0;
1280 rtx x;
1282 /* If this is not a fixed size move, just call memcpy. */
1283 if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1284 return 0;
1286 bytes = INTVAL (operands[2]);
1287 align = INTVAL (operands[3]);
1289 /* Anything to move? */
1290 if (bytes <= 0)
1291 return 0;
1293 if (align > MOVE_MAX)
1294 align = MOVE_MAX;
1296 /* Decide whether to expand inline based on the optimization level. */
1297 move_ratio = 4;
1298 if (optimize > 2)
1299 move_ratio = LARGEST_MOVE_RATIO;
1300 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */
1301 if (num_pieces > move_ratio)
1302 return 0;
1304 x = XEXP (dst_mem, 0);
1305 if (!REG_P (x))
1307 x = force_reg (Pmode, x);
1308 dst_mem = replace_equiv_address (dst_mem, x);
1311 x = XEXP (src_mem, 0);
1312 if (!REG_P (x))
1314 x = force_reg (Pmode, x);
1315 src_mem = replace_equiv_address (src_mem, x);
1318 active[0] = active[1] = false;
1322 next = phase;
1323 phase ^= 1;
1325 if (bytes > 0)
1327 int next_amount;
1329 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1330 next_amount = MIN (next_amount, align);
1332 amount[next] = next_amount;
1333 mode[next] = mode_from_align[next_amount];
1334 temp[next] = gen_reg_rtx (mode[next]);
1336 x = adjust_address (src_mem, mode[next], offset_ld);
1337 emit_insn (gen_rtx_SET (temp[next], x));
1339 offset_ld += next_amount;
1340 bytes -= next_amount;
1341 active[next] = true;
1344 if (active[phase])
1346 active[phase] = false;
1348 x = adjust_address (dst_mem, mode[phase], offset_st);
1349 emit_insn (gen_rtx_SET (x, temp[phase]));
1351 offset_st += amount[phase];
1354 while (active[next]);
1356 return 1;
1360 void
1361 xtensa_expand_nonlocal_goto (rtx *operands)
1363 rtx goto_handler = operands[1];
1364 rtx containing_fp = operands[3];
1366 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1367 is too big to generate in-line. */
1369 if (GET_CODE (containing_fp) != REG)
1370 containing_fp = force_reg (Pmode, containing_fp);
1372 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1373 LCT_NORMAL, VOIDmode,
1374 containing_fp, Pmode,
1375 goto_handler, Pmode);
1379 static struct machine_function *
1380 xtensa_init_machine_status (void)
1382 return ggc_cleared_alloc<machine_function> ();
1386 /* Shift VAL of mode MODE left by COUNT bits. */
1388 static inline rtx
1389 xtensa_expand_mask_and_shift (rtx val, machine_mode mode, rtx count)
1391 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1392 NULL_RTX, 1, OPTAB_DIRECT);
1393 return expand_simple_binop (SImode, ASHIFT, val, count,
1394 NULL_RTX, 1, OPTAB_DIRECT);
1398 /* Structure to hold the initial parameters for a compare_and_swap operation
1399 in HImode and QImode. */
1401 struct alignment_context
1403 rtx memsi; /* SI aligned memory location. */
1404 rtx shift; /* Bit offset with regard to lsb. */
1405 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
1406 rtx modemaski; /* ~modemask */
1410 /* Initialize structure AC for word access to HI and QI mode memory. */
1412 static void
1413 init_alignment_context (struct alignment_context *ac, rtx mem)
1415 machine_mode mode = GET_MODE (mem);
1416 rtx byteoffset = NULL_RTX;
1417 bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1419 if (aligned)
1420 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
1421 else
1423 /* Alignment is unknown. */
1424 rtx addr, align;
1426 /* Force the address into a register. */
1427 addr = force_reg (Pmode, XEXP (mem, 0));
1429 /* Align it to SImode. */
1430 align = expand_simple_binop (Pmode, AND, addr,
1431 GEN_INT (-GET_MODE_SIZE (SImode)),
1432 NULL_RTX, 1, OPTAB_DIRECT);
1433 /* Generate MEM. */
1434 ac->memsi = gen_rtx_MEM (SImode, align);
1435 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1436 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1437 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1439 byteoffset = expand_simple_binop (Pmode, AND, addr,
1440 GEN_INT (GET_MODE_SIZE (SImode) - 1),
1441 NULL_RTX, 1, OPTAB_DIRECT);
1444 /* Calculate shiftcount. */
1445 if (TARGET_BIG_ENDIAN)
1447 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1448 if (!aligned)
1449 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1450 NULL_RTX, 1, OPTAB_DIRECT);
1452 else
1454 if (aligned)
1455 ac->shift = NULL_RTX;
1456 else
1457 ac->shift = byteoffset;
1460 if (ac->shift != NULL_RTX)
1462 /* Shift is the byte count, but we need the bitcount. */
1463 gcc_assert (exact_log2 (BITS_PER_UNIT) >= 0);
1464 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift,
1465 GEN_INT (exact_log2 (BITS_PER_UNIT)),
1466 NULL_RTX, 1, OPTAB_DIRECT);
1467 ac->modemask = expand_simple_binop (SImode, ASHIFT,
1468 GEN_INT (GET_MODE_MASK (mode)),
1469 ac->shift,
1470 NULL_RTX, 1, OPTAB_DIRECT);
1472 else
1473 ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1475 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1479 /* Expand an atomic compare and swap operation for HImode and QImode.
1480 MEM is the memory location, CMP the old value to compare MEM with
1481 and NEW_RTX the value to set if CMP == MEM. */
1483 void
1484 xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1486 machine_mode mode = GET_MODE (mem);
1487 struct alignment_context ac;
1488 rtx tmp, cmpv, newv, val;
1489 rtx oldval = gen_reg_rtx (SImode);
1490 rtx res = gen_reg_rtx (SImode);
1491 rtx_code_label *csloop = gen_label_rtx ();
1492 rtx_code_label *csend = gen_label_rtx ();
1494 init_alignment_context (&ac, mem);
1496 if (ac.shift != NULL_RTX)
1498 cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1499 new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1502 /* Load the surrounding word into VAL with the MEM value masked out. */
1503 val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1504 ac.modemaski, NULL_RTX, 1,
1505 OPTAB_DIRECT));
1506 emit_label (csloop);
1508 /* Patch CMP and NEW_RTX into VAL at correct position. */
1509 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1510 NULL_RTX, 1, OPTAB_DIRECT));
1511 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1512 NULL_RTX, 1, OPTAB_DIRECT));
1514 /* Jump to end if we're done. */
1515 emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1516 emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1518 /* Check for changes outside mode. */
1519 emit_move_insn (oldval, val);
1520 tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1521 val, 1, OPTAB_DIRECT);
1522 if (tmp != val)
1523 emit_move_insn (val, tmp);
1525 /* Loop internal if so. */
1526 emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1528 emit_label (csend);
1530 /* Return the correct part of the bitfield. */
1531 convert_move (target,
1532 (ac.shift == NULL_RTX ? res
1533 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1534 NULL_RTX, 1, OPTAB_DIRECT)),
1539 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1540 the default expansion works fine for SImode). MEM is the memory location
1541 and VAL the value to play with. If AFTER is true then store the value
1542 MEM holds after the operation, if AFTER is false then store the value MEM
1543 holds before the operation. If TARGET is zero then discard that value, else
1544 store it to TARGET. */
1546 void
1547 xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1548 bool after)
1550 machine_mode mode = GET_MODE (mem);
1551 struct alignment_context ac;
1552 rtx_code_label *csloop = gen_label_rtx ();
1553 rtx cmp, tmp;
1554 rtx old = gen_reg_rtx (SImode);
1555 rtx new_rtx = gen_reg_rtx (SImode);
1556 rtx orig = NULL_RTX;
1558 init_alignment_context (&ac, mem);
1560 /* Prepare values before the compare-and-swap loop. */
1561 if (ac.shift != NULL_RTX)
1562 val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1563 switch (code)
1565 case PLUS:
1566 case MINUS:
1567 orig = gen_reg_rtx (SImode);
1568 convert_move (orig, val, 1);
1569 break;
1571 case SET:
1572 case IOR:
1573 case XOR:
1574 break;
1576 case MULT: /* NAND */
1577 case AND:
1578 /* val = "11..1<val>11..1" */
1579 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1580 NULL_RTX, 1, OPTAB_DIRECT);
1581 break;
1583 default:
1584 gcc_unreachable ();
1587 /* Load full word. Subsequent loads are performed by S32C1I. */
1588 cmp = force_reg (SImode, ac.memsi);
1590 emit_label (csloop);
1591 emit_move_insn (old, cmp);
1593 switch (code)
1595 case PLUS:
1596 case MINUS:
1597 val = expand_simple_binop (SImode, code, old, orig,
1598 NULL_RTX, 1, OPTAB_DIRECT);
1599 val = expand_simple_binop (SImode, AND, val, ac.modemask,
1600 NULL_RTX, 1, OPTAB_DIRECT);
1601 /* FALLTHRU */
1602 case SET:
1603 tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1604 NULL_RTX, 1, OPTAB_DIRECT);
1605 tmp = expand_simple_binop (SImode, IOR, tmp, val,
1606 new_rtx, 1, OPTAB_DIRECT);
1607 break;
1609 case AND:
1610 case IOR:
1611 case XOR:
1612 tmp = expand_simple_binop (SImode, code, old, val,
1613 new_rtx, 1, OPTAB_DIRECT);
1614 break;
1616 case MULT: /* NAND */
1617 tmp = expand_simple_binop (SImode, XOR, old, ac.modemask,
1618 NULL_RTX, 1, OPTAB_DIRECT);
1619 tmp = expand_simple_binop (SImode, AND, tmp, val,
1620 new_rtx, 1, OPTAB_DIRECT);
1621 break;
1623 default:
1624 gcc_unreachable ();
1627 if (tmp != new_rtx)
1628 emit_move_insn (new_rtx, tmp);
1629 emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1630 emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1632 if (target)
1634 tmp = (after ? new_rtx : cmp);
1635 convert_move (target,
1636 (ac.shift == NULL_RTX ? tmp
1637 : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1638 NULL_RTX, 1, OPTAB_DIRECT)),
1644 void
1645 xtensa_setup_frame_addresses (void)
1647 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1648 cfun->machine->accesses_prev_frame = 1;
1650 if (TARGET_WINDOWED_ABI)
1651 emit_library_call
1652 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1653 LCT_NORMAL, VOIDmode);
1657 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1658 a comment showing where the end of the loop is. However, if there is a
1659 label or a branch at the end of the loop then we need to place a nop
1660 there. If the loop ends with a label we need the nop so that branches
1661 targeting that label will target the nop (and thus remain in the loop),
1662 instead of targeting the instruction after the loop (and thus exiting
1663 the loop). If the loop ends with a branch, we need the nop in case the
1664 branch is targeting a location inside the loop. When the branch
1665 executes it will cause the loop count to be decremented even if it is
1666 taken (because it is the last instruction in the loop), so we need to
1667 nop after the branch to prevent the loop count from being decremented
1668 when the branch is taken. */
1670 void
1671 xtensa_emit_loop_end (rtx_insn *insn, rtx *operands)
1673 char done = 0;
1675 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1677 switch (GET_CODE (insn))
1679 case NOTE:
1680 case BARRIER:
1681 break;
1683 case CODE_LABEL:
1684 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1685 done = 1;
1686 break;
1688 default:
1690 rtx body = PATTERN (insn);
1692 if (JUMP_P (body))
1694 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1695 done = 1;
1697 else if ((GET_CODE (body) != USE)
1698 && (GET_CODE (body) != CLOBBER))
1699 done = 1;
1701 break;
1705 output_asm_insn ("%1_LEND:", operands);
1709 char *
1710 xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1712 static char result[64];
1713 enum rtx_code code;
1714 const char *op;
1716 code = GET_CODE (operands[3]);
1717 switch (code)
1719 case EQ: op = inverted ? "ne" : "eq"; break;
1720 case NE: op = inverted ? "eq" : "ne"; break;
1721 case LT: op = inverted ? "ge" : "lt"; break;
1722 case GE: op = inverted ? "lt" : "ge"; break;
1723 case LTU: op = inverted ? "geu" : "ltu"; break;
1724 case GEU: op = inverted ? "ltu" : "geu"; break;
1725 default: gcc_unreachable ();
1728 if (immed)
1730 if (INTVAL (operands[1]) == 0)
1731 sprintf (result, "b%sz%s\t%%0, %%2", op,
1732 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1733 else
1734 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1736 else
1737 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1739 return result;
1743 char *
1744 xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1746 static char result[64];
1747 const char *op;
1749 switch (GET_CODE (operands[3]))
1751 case EQ: op = inverted ? "bs" : "bc"; break;
1752 case NE: op = inverted ? "bc" : "bs"; break;
1753 default: gcc_unreachable ();
1756 if (immed)
1758 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1759 operands[1] = GEN_INT (bitnum);
1760 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1762 else
1763 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1765 return result;
1769 char *
1770 xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1772 static char result[64];
1773 enum rtx_code code;
1774 const char *op;
1776 code = GET_CODE (operands[4]);
1777 if (isbool)
1779 switch (code)
1781 case EQ: op = inverted ? "t" : "f"; break;
1782 case NE: op = inverted ? "f" : "t"; break;
1783 default: gcc_unreachable ();
1786 else
1788 switch (code)
1790 case EQ: op = inverted ? "nez" : "eqz"; break;
1791 case NE: op = inverted ? "eqz" : "nez"; break;
1792 case LT: op = inverted ? "gez" : "ltz"; break;
1793 case GE: op = inverted ? "ltz" : "gez"; break;
1794 default: gcc_unreachable ();
1798 sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1799 op, isfp ? ".s" : "", inverted ? 3 : 2);
1800 return result;
1804 char *
1805 xtensa_emit_call (int callop, rtx *operands)
1807 static char result[64];
1808 rtx tgt = operands[callop];
1810 if (GET_CODE (tgt) == CONST_INT)
1811 sprintf (result, "call%d\t" HOST_WIDE_INT_PRINT_HEX,
1812 WINDOW_SIZE, INTVAL (tgt));
1813 else if (register_operand (tgt, VOIDmode))
1814 sprintf (result, "callx%d\t%%%d", WINDOW_SIZE, callop);
1815 else
1816 sprintf (result, "call%d\t%%%d", WINDOW_SIZE, callop);
1818 return result;
1822 bool
1823 xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
1825 /* Allow constant pool addresses. */
1826 if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1827 && ! TARGET_CONST16 && constantpool_address_p (addr)
1828 && ! xtensa_tls_referenced_p (addr))
1829 return true;
1831 while (GET_CODE (addr) == SUBREG)
1832 addr = SUBREG_REG (addr);
1834 /* Allow base registers. */
1835 if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1836 return true;
1838 /* Check for "register + offset" addressing. */
1839 if (GET_CODE (addr) == PLUS)
1841 rtx xplus0 = XEXP (addr, 0);
1842 rtx xplus1 = XEXP (addr, 1);
1843 enum rtx_code code0;
1844 enum rtx_code code1;
1846 while (GET_CODE (xplus0) == SUBREG)
1847 xplus0 = SUBREG_REG (xplus0);
1848 code0 = GET_CODE (xplus0);
1850 while (GET_CODE (xplus1) == SUBREG)
1851 xplus1 = SUBREG_REG (xplus1);
1852 code1 = GET_CODE (xplus1);
1854 /* Swap operands if necessary so the register is first. */
1855 if (code0 != REG && code1 == REG)
1857 xplus0 = XEXP (addr, 1);
1858 xplus1 = XEXP (addr, 0);
1859 code0 = GET_CODE (xplus0);
1860 code1 = GET_CODE (xplus1);
1863 if (code0 == REG && BASE_REG_P (xplus0, strict)
1864 && code1 == CONST_INT
1865 && xtensa_mem_offset (INTVAL (xplus1), mode))
1866 return true;
1869 return false;
1873 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1875 static GTY(()) rtx xtensa_tls_module_base_symbol;
1877 static rtx
1878 xtensa_tls_module_base (void)
1880 if (! xtensa_tls_module_base_symbol)
1882 xtensa_tls_module_base_symbol =
1883 gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1884 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1885 |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1888 return xtensa_tls_module_base_symbol;
1892 static rtx_insn *
1893 xtensa_call_tls_desc (rtx sym, rtx *retp)
1895 rtx fn, arg, a_io;
1896 rtx_insn *call_insn, *insns;
1898 start_sequence ();
1899 fn = gen_reg_rtx (Pmode);
1900 arg = gen_reg_rtx (Pmode);
1901 a_io = gen_rtx_REG (Pmode, WINDOW_SIZE + 2);
1903 emit_insn (gen_tls_func (fn, sym));
1904 emit_insn (gen_tls_arg (arg, sym));
1905 emit_move_insn (a_io, arg);
1906 call_insn = emit_call_insn (gen_tls_call (a_io, fn, sym, const1_rtx));
1907 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), a_io);
1908 insns = get_insns ();
1909 end_sequence ();
1911 *retp = a_io;
1912 return insns;
1916 static rtx
1917 xtensa_legitimize_tls_address (rtx x)
1919 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1920 rtx dest, tp, ret, modbase, base, addend;
1921 rtx_insn *insns;
1923 dest = gen_reg_rtx (Pmode);
1924 switch (model)
1926 case TLS_MODEL_GLOBAL_DYNAMIC:
1927 insns = xtensa_call_tls_desc (x, &ret);
1928 emit_libcall_block (insns, dest, ret, x);
1929 break;
1931 case TLS_MODEL_LOCAL_DYNAMIC:
1932 base = gen_reg_rtx (Pmode);
1933 modbase = xtensa_tls_module_base ();
1934 insns = xtensa_call_tls_desc (modbase, &ret);
1935 emit_libcall_block (insns, base, ret, modbase);
1936 addend = force_reg (SImode, gen_sym_DTPOFF (x));
1937 emit_insn (gen_addsi3 (dest, base, addend));
1938 break;
1940 case TLS_MODEL_INITIAL_EXEC:
1941 case TLS_MODEL_LOCAL_EXEC:
1942 tp = gen_reg_rtx (SImode);
1943 emit_insn (gen_get_thread_pointersi (tp));
1944 addend = force_reg (SImode, gen_sym_TPOFF (x));
1945 emit_insn (gen_addsi3 (dest, tp, addend));
1946 break;
1948 default:
1949 gcc_unreachable ();
1952 return dest;
1957 xtensa_legitimize_address (rtx x,
1958 rtx oldx ATTRIBUTE_UNUSED,
1959 machine_mode mode)
1961 if (xtensa_tls_symbol_p (x))
1962 return xtensa_legitimize_tls_address (x);
1964 if (GET_CODE (x) == PLUS)
1966 rtx plus0 = XEXP (x, 0);
1967 rtx plus1 = XEXP (x, 1);
1969 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1971 plus0 = XEXP (x, 1);
1972 plus1 = XEXP (x, 0);
1975 /* Try to split up the offset to use an ADDMI instruction. */
1976 if (GET_CODE (plus0) == REG
1977 && GET_CODE (plus1) == CONST_INT
1978 && !xtensa_mem_offset (INTVAL (plus1), mode)
1979 && !xtensa_simm8 (INTVAL (plus1))
1980 && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1981 && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1983 rtx temp = gen_reg_rtx (Pmode);
1984 rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1985 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, plus0,
1986 addmi_offset)));
1987 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1991 return x;
1994 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
1996 Treat constant-pool references as "mode dependent" since they can
1997 only be accessed with SImode loads. This works around a bug in the
1998 combiner where a constant pool reference is temporarily converted
1999 to an HImode load, which is then assumed to zero-extend based on
2000 our definition of LOAD_EXTEND_OP. This is wrong because the high
2001 bits of a 16-bit value in the constant pool are now sign-extended
2002 by default. */
2004 static bool
2005 xtensa_mode_dependent_address_p (const_rtx addr,
2006 addr_space_t as ATTRIBUTE_UNUSED)
2008 return constantpool_address_p (addr);
2011 /* Return TRUE if X contains any TLS symbol references. */
2013 bool
2014 xtensa_tls_referenced_p (rtx x)
2016 if (! TARGET_HAVE_TLS)
2017 return false;
2019 subrtx_iterator::array_type array;
2020 FOR_EACH_SUBRTX (iter, array, x, ALL)
2022 const_rtx x = *iter;
2023 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
2024 return true;
2026 /* Ignore TLS references that have already been legitimized. */
2027 if (GET_CODE (x) == UNSPEC)
2028 switch (XINT (x, 1))
2030 case UNSPEC_TPOFF:
2031 case UNSPEC_DTPOFF:
2032 case UNSPEC_TLS_FUNC:
2033 case UNSPEC_TLS_ARG:
2034 case UNSPEC_TLS_CALL:
2035 iter.skip_subrtxes ();
2036 break;
2037 default:
2038 break;
2041 return false;
2045 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2047 static bool
2048 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2050 return xtensa_tls_referenced_p (x);
2054 /* Return the debugger register number to use for 'regno'. */
2057 xtensa_dbx_register_number (int regno)
2059 int first = -1;
2061 if (GP_REG_P (regno))
2063 regno -= GP_REG_FIRST;
2064 first = 0;
2066 else if (BR_REG_P (regno))
2068 regno -= BR_REG_FIRST;
2069 first = 16;
2071 else if (FP_REG_P (regno))
2073 regno -= FP_REG_FIRST;
2074 first = 48;
2076 else if (ACC_REG_P (regno))
2078 first = 0x200; /* Start of Xtensa special registers. */
2079 regno = 16; /* ACCLO is special register 16. */
2082 /* When optimizing, we sometimes get asked about pseudo-registers
2083 that don't represent hard registers. Return 0 for these. */
2084 if (first == -1)
2085 return 0;
2087 return first + regno;
2091 /* Argument support functions. */
2093 /* Initialize CUMULATIVE_ARGS for a function. */
2095 void
2096 init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
2098 cum->arg_words = 0;
2099 cum->incoming = incoming;
2103 /* Advance the argument to the next argument position. */
2105 static void
2106 xtensa_function_arg_advance (cumulative_args_t cum, machine_mode mode,
2107 const_tree type, bool named ATTRIBUTE_UNUSED)
2109 int words, max;
2110 int *arg_words;
2112 arg_words = &get_cumulative_args (cum)->arg_words;
2113 max = MAX_ARGS_IN_REGISTERS;
2115 words = (((mode != BLKmode)
2116 ? (int) GET_MODE_SIZE (mode)
2117 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2119 if (*arg_words < max
2120 && (targetm.calls.must_pass_in_stack (mode, type)
2121 || *arg_words + words > max))
2122 *arg_words = max;
2124 *arg_words += words;
2128 /* Return an RTL expression containing the register for the given mode,
2129 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2130 if this is an incoming argument to the current function. */
2132 static rtx
2133 xtensa_function_arg_1 (cumulative_args_t cum_v, machine_mode mode,
2134 const_tree type, bool incoming_p)
2136 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2137 int regbase, words, max;
2138 int *arg_words;
2139 int regno;
2141 arg_words = &cum->arg_words;
2142 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2143 max = MAX_ARGS_IN_REGISTERS;
2145 words = (((mode != BLKmode)
2146 ? (int) GET_MODE_SIZE (mode)
2147 : int_size_in_bytes (type)) + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
2149 if (type && (TYPE_ALIGN (type) > BITS_PER_WORD))
2151 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_WORD;
2152 *arg_words = (*arg_words + align - 1) & -align;
2155 if (*arg_words + words > max)
2156 return (rtx)0;
2158 regno = regbase + *arg_words;
2160 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2161 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI;
2163 return gen_rtx_REG (mode, regno);
2166 /* Implement TARGET_FUNCTION_ARG. */
2168 static rtx
2169 xtensa_function_arg (cumulative_args_t cum, machine_mode mode,
2170 const_tree type, bool named ATTRIBUTE_UNUSED)
2172 return xtensa_function_arg_1 (cum, mode, type, false);
2175 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2177 static rtx
2178 xtensa_function_incoming_arg (cumulative_args_t cum, machine_mode mode,
2179 const_tree type, bool named ATTRIBUTE_UNUSED)
2181 return xtensa_function_arg_1 (cum, mode, type, true);
2184 static unsigned int
2185 xtensa_function_arg_boundary (machine_mode mode, const_tree type)
2187 unsigned int alignment;
2189 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2190 if (alignment < PARM_BOUNDARY)
2191 alignment = PARM_BOUNDARY;
2192 if (alignment > STACK_BOUNDARY)
2193 alignment = STACK_BOUNDARY;
2194 return alignment;
2198 static bool
2199 xtensa_return_in_msb (const_tree valtype)
2201 return (TARGET_BIG_ENDIAN
2202 && AGGREGATE_TYPE_P (valtype)
2203 && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2207 static void
2208 xtensa_option_override (void)
2210 int regno;
2211 machine_mode mode;
2213 /* Use CONST16 in the absence of L32R.
2214 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa
2215 configuration in the xtensa-common.c */
2217 if (!TARGET_L32R)
2218 target_flags |= MASK_CONST16;
2220 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2221 error ("boolean registers required for the floating-point option");
2223 /* Set up array giving whether a given register can hold a given mode. */
2224 for (mode = VOIDmode;
2225 mode != MAX_MACHINE_MODE;
2226 mode = (machine_mode) ((int) mode + 1))
2228 int size = GET_MODE_SIZE (mode);
2229 enum mode_class mclass = GET_MODE_CLASS (mode);
2231 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2233 int temp;
2235 if (ACC_REG_P (regno))
2236 temp = (TARGET_MAC16
2237 && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2238 else if (GP_REG_P (regno))
2239 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2240 else if (FP_REG_P (regno))
2241 temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2242 else if (BR_REG_P (regno))
2243 temp = (TARGET_BOOLEANS && (mode == CCmode));
2244 else
2245 temp = FALSE;
2247 xtensa_hard_regno_mode_ok_p[(int) mode][regno] = temp;
2251 init_machine_status = xtensa_init_machine_status;
2253 /* Check PIC settings. PIC is only supported when using L32R
2254 instructions, and some targets need to always use PIC. */
2255 if (flag_pic && TARGET_CONST16)
2256 error ("-f%s is not supported with CONST16 instructions",
2257 (flag_pic > 1 ? "PIC" : "pic"));
2258 else if (TARGET_FORCE_NO_PIC)
2259 flag_pic = 0;
2260 else if (XTENSA_ALWAYS_PIC)
2262 if (TARGET_CONST16)
2263 error ("PIC is required but not supported with CONST16 instructions");
2264 flag_pic = 1;
2266 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2267 if (flag_pic > 1)
2268 flag_pic = 1;
2269 if (flag_pic && !flag_pie)
2270 flag_shlib = 1;
2272 /* Hot/cold partitioning does not work on this architecture, because of
2273 constant pools (the load instruction cannot necessarily reach that far).
2274 Therefore disable it on this architecture. */
2275 if (flag_reorder_blocks_and_partition)
2277 flag_reorder_blocks_and_partition = 0;
2278 flag_reorder_blocks = 1;
2282 /* Implement TARGET_HARD_REGNO_NREGS. */
2284 static unsigned int
2285 xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode)
2287 if (FP_REG_P (regno))
2288 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG);
2289 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2292 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2294 static bool
2295 xtensa_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2297 return xtensa_hard_regno_mode_ok_p[mode][regno];
2300 /* Implement TARGET_MODES_TIEABLE_P. */
2302 static bool
2303 xtensa_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2305 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
2306 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
2307 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
2308 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
2311 /* A C compound statement to output to stdio stream STREAM the
2312 assembler syntax for an instruction operand X. X is an RTL
2313 expression.
2315 CODE is a value that can be used to specify one of several ways
2316 of printing the operand. It is used when identical operands
2317 must be printed differently depending on the context. CODE
2318 comes from the '%' specification that was used to request
2319 printing of the operand. If the specification was just '%DIGIT'
2320 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2321 is the ASCII code for LTR.
2323 If X is a register, this macro should print the register's name.
2324 The names can be found in an array 'reg_names' whose type is
2325 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2327 When the machine description has a specification '%PUNCT' (a '%'
2328 followed by a punctuation character), this macro is called with
2329 a null pointer for X and the punctuation character for CODE.
2331 'a', 'c', 'l', and 'n' are reserved.
2333 The Xtensa specific codes are:
2335 'd' CONST_INT, print as signed decimal
2336 'x' CONST_INT, print as signed hexadecimal
2337 'K' CONST_INT, print number of bits in mask for EXTUI
2338 'R' CONST_INT, print (X & 0x1f)
2339 'L' CONST_INT, print ((32 - X) & 0x1f)
2340 'D' REG, print second register of double-word register operand
2341 'N' MEM, print address of next word following a memory operand
2342 'v' MEM, if memory reference is volatile, output a MEMW before it
2343 't' any constant, add "@h" suffix for top 16 bits
2344 'b' any constant, add "@l" suffix for bottom 16 bits
2347 static void
2348 printx (FILE *file, signed int val)
2350 /* Print a hexadecimal value in a nice way. */
2351 if ((val > -0xa) && (val < 0xa))
2352 fprintf (file, "%d", val);
2353 else if (val < 0)
2354 fprintf (file, "-0x%x", -val);
2355 else
2356 fprintf (file, "0x%x", val);
2360 void
2361 print_operand (FILE *file, rtx x, int letter)
2363 if (!x)
2364 error ("PRINT_OPERAND null pointer");
2366 switch (letter)
2368 case 'D':
2369 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2370 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2371 else
2372 output_operand_lossage ("invalid %%D value");
2373 break;
2375 case 'v':
2376 if (GET_CODE (x) == MEM)
2378 /* For a volatile memory reference, emit a MEMW before the
2379 load or store. */
2380 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2381 fprintf (file, "memw\n\t");
2383 else
2384 output_operand_lossage ("invalid %%v value");
2385 break;
2387 case 'N':
2388 if (GET_CODE (x) == MEM
2389 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2391 x = adjust_address (x, GET_MODE (x) == DFmode ? E_SFmode : E_SImode,
2393 output_address (GET_MODE (x), XEXP (x, 0));
2395 else
2396 output_operand_lossage ("invalid %%N value");
2397 break;
2399 case 'K':
2400 if (GET_CODE (x) == CONST_INT)
2402 int num_bits = 0;
2403 unsigned val = INTVAL (x);
2404 while (val & 1)
2406 num_bits += 1;
2407 val = val >> 1;
2409 if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2410 fatal_insn ("invalid mask", x);
2412 fprintf (file, "%d", num_bits);
2414 else
2415 output_operand_lossage ("invalid %%K value");
2416 break;
2418 case 'L':
2419 if (GET_CODE (x) == CONST_INT)
2420 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INTVAL (x)) & 0x1f);
2421 else
2422 output_operand_lossage ("invalid %%L value");
2423 break;
2425 case 'R':
2426 if (GET_CODE (x) == CONST_INT)
2427 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x1f);
2428 else
2429 output_operand_lossage ("invalid %%R value");
2430 break;
2432 case 'x':
2433 if (GET_CODE (x) == CONST_INT)
2434 printx (file, INTVAL (x));
2435 else
2436 output_operand_lossage ("invalid %%x value");
2437 break;
2439 case 'd':
2440 if (GET_CODE (x) == CONST_INT)
2441 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2442 else
2443 output_operand_lossage ("invalid %%d value");
2444 break;
2446 case 't':
2447 case 'b':
2448 if (GET_CODE (x) == CONST_INT)
2450 printx (file, INTVAL (x));
2451 fputs (letter == 't' ? "@h" : "@l", file);
2453 else if (GET_CODE (x) == CONST_DOUBLE)
2455 if (GET_MODE (x) == SFmode)
2457 long l;
2458 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
2459 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2461 else
2462 output_operand_lossage ("invalid %%t/%%b value");
2464 else if (GET_CODE (x) == CONST)
2466 /* X must be a symbolic constant on ELF. Write an expression
2467 suitable for 'const16' that sets the high or low 16 bits. */
2468 if (GET_CODE (XEXP (x, 0)) != PLUS
2469 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2470 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2471 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2472 output_operand_lossage ("invalid %%t/%%b value");
2473 print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2474 fputs (letter == 't' ? "@h" : "@l", file);
2475 /* There must be a non-alphanumeric character between 'h' or 'l'
2476 and the number. The '-' is added by print_operand() already. */
2477 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2478 fputs ("+", file);
2479 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2481 else
2483 output_addr_const (file, x);
2484 fputs (letter == 't' ? "@h" : "@l", file);
2486 break;
2488 case 'y':
2489 if (GET_CODE (x) == CONST_DOUBLE &&
2490 GET_MODE (x) == SFmode)
2492 long l;
2493 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
2494 fprintf (file, "0x%08lx", l);
2495 break;
2498 /* fall through */
2500 default:
2501 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2502 fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2503 else if (GET_CODE (x) == MEM)
2504 output_address (GET_MODE (x), XEXP (x, 0));
2505 else if (GET_CODE (x) == CONST_INT)
2506 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2507 else
2508 output_addr_const (file, x);
2513 /* A C compound statement to output to stdio stream STREAM the
2514 assembler syntax for an instruction operand that is a memory
2515 reference whose address is ADDR. ADDR is an RTL expression. */
2517 void
2518 print_operand_address (FILE *file, rtx addr)
2520 if (!addr)
2521 error ("PRINT_OPERAND_ADDRESS, null pointer");
2523 switch (GET_CODE (addr))
2525 default:
2526 fatal_insn ("invalid address", addr);
2527 break;
2529 case REG:
2530 fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2531 break;
2533 case PLUS:
2535 rtx reg = (rtx)0;
2536 rtx offset = (rtx)0;
2537 rtx arg0 = XEXP (addr, 0);
2538 rtx arg1 = XEXP (addr, 1);
2540 if (GET_CODE (arg0) == REG)
2542 reg = arg0;
2543 offset = arg1;
2545 else if (GET_CODE (arg1) == REG)
2547 reg = arg1;
2548 offset = arg0;
2550 else
2551 fatal_insn ("no register in address", addr);
2553 if (CONSTANT_P (offset))
2555 fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2556 output_addr_const (file, offset);
2558 else
2559 fatal_insn ("address offset not a constant", addr);
2561 break;
2563 case LABEL_REF:
2564 case SYMBOL_REF:
2565 case CONST_INT:
2566 case CONST:
2567 output_addr_const (file, addr);
2568 break;
2572 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2574 static bool
2575 xtensa_output_addr_const_extra (FILE *fp, rtx x)
2577 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2579 switch (XINT (x, 1))
2581 case UNSPEC_TPOFF:
2582 output_addr_const (fp, XVECEXP (x, 0, 0));
2583 fputs ("@TPOFF", fp);
2584 return true;
2585 case UNSPEC_DTPOFF:
2586 output_addr_const (fp, XVECEXP (x, 0, 0));
2587 fputs ("@DTPOFF", fp);
2588 return true;
2589 case UNSPEC_PLT:
2590 if (flag_pic)
2592 output_addr_const (fp, XVECEXP (x, 0, 0));
2593 fputs ("@PLT", fp);
2594 return true;
2596 break;
2597 default:
2598 break;
2601 return false;
2604 static void
2605 xtensa_output_integer_literal_parts (FILE *file, rtx x, int size)
2607 if (size > 4 && !(size & (size - 1)))
2609 rtx first, second;
2611 split_double (x, &first, &second);
2612 xtensa_output_integer_literal_parts (file, first, size / 2);
2613 fputs (", ", file);
2614 xtensa_output_integer_literal_parts (file, second, size / 2);
2616 else if (size == 4)
2618 output_addr_const (file, x);
2620 else
2622 gcc_unreachable();
2626 void
2627 xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno)
2629 long value_long[2];
2631 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2633 switch (GET_MODE_CLASS (mode))
2635 case MODE_FLOAT:
2636 gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2638 switch (mode)
2640 case E_SFmode:
2641 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x),
2642 value_long[0]);
2643 if (HOST_BITS_PER_LONG > 32)
2644 value_long[0] &= 0xffffffff;
2645 fprintf (file, "0x%08lx\n", value_long[0]);
2646 break;
2648 case E_DFmode:
2649 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x),
2650 value_long);
2651 if (HOST_BITS_PER_LONG > 32)
2653 value_long[0] &= 0xffffffff;
2654 value_long[1] &= 0xffffffff;
2656 fprintf (file, "0x%08lx, 0x%08lx\n",
2657 value_long[0], value_long[1]);
2658 break;
2660 default:
2661 gcc_unreachable ();
2664 break;
2666 case MODE_INT:
2667 case MODE_PARTIAL_INT:
2668 xtensa_output_integer_literal_parts (file, x, GET_MODE_SIZE (mode));
2669 fputs ("\n", file);
2670 break;
2672 default:
2673 gcc_unreachable ();
2677 static bool
2678 xtensa_call_save_reg(int regno)
2680 if (TARGET_WINDOWED_ABI)
2681 return false;
2683 if (regno == A0_REG)
2684 return crtl->profile || !crtl->is_leaf || crtl->calls_eh_return ||
2685 df_regs_ever_live_p (regno);
2687 if (crtl->calls_eh_return && regno >= 2 && regno < 4)
2688 return true;
2690 return !fixed_regs[regno] && !call_used_regs[regno] &&
2691 df_regs_ever_live_p (regno);
2694 /* Return the bytes needed to compute the frame pointer from the current
2695 stack pointer. */
2697 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2698 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2700 long
2701 compute_frame_size (poly_int64 size)
2703 int regno;
2705 if (reload_completed && cfun->machine->frame_laid_out)
2706 return cfun->machine->current_frame_size;
2708 /* Add space for the incoming static chain value. */
2709 if (cfun->static_chain_decl != NULL)
2710 size += (1 * UNITS_PER_WORD);
2712 cfun->machine->callee_save_size = 0;
2713 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2715 if (xtensa_call_save_reg(regno))
2716 cfun->machine->callee_save_size += UNITS_PER_WORD;
2719 cfun->machine->current_frame_size =
2720 XTENSA_STACK_ALIGN (size
2721 + cfun->machine->callee_save_size
2722 + crtl->outgoing_args_size
2723 + (WINDOW_SIZE * UNITS_PER_WORD));
2724 cfun->machine->callee_save_size =
2725 XTENSA_STACK_ALIGN (cfun->machine->callee_save_size);
2726 cfun->machine->frame_laid_out = true;
2727 return cfun->machine->current_frame_size;
2731 bool
2732 xtensa_frame_pointer_required (void)
2734 /* The code to expand builtin_frame_addr and builtin_return_addr
2735 currently uses the hard_frame_pointer instead of frame_pointer.
2736 This seems wrong but maybe it's necessary for other architectures.
2737 This function is derived from the i386 code. */
2739 if (cfun->machine->accesses_prev_frame)
2740 return true;
2742 return false;
2745 HOST_WIDE_INT
2746 xtensa_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
2748 long frame_size = compute_frame_size (get_frame_size ());
2749 HOST_WIDE_INT offset;
2751 switch (from)
2753 case FRAME_POINTER_REGNUM:
2754 if (FRAME_GROWS_DOWNWARD)
2755 offset = frame_size - (WINDOW_SIZE * UNITS_PER_WORD)
2756 - cfun->machine->callee_save_size;
2757 else
2758 offset = 0;
2759 break;
2760 case ARG_POINTER_REGNUM:
2761 offset = frame_size;
2762 break;
2763 default:
2764 gcc_unreachable ();
2767 return offset;
2770 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2771 and the total number of words must be a multiple of 128 bits. */
2772 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2774 void
2775 xtensa_expand_prologue (void)
2777 HOST_WIDE_INT total_size;
2778 rtx_insn *insn = NULL;
2779 rtx note_rtx;
2782 total_size = compute_frame_size (get_frame_size ());
2784 if (flag_stack_usage_info)
2785 current_function_static_stack_size = total_size;
2787 if (TARGET_WINDOWED_ABI)
2789 if (total_size < (1 << (12+3)))
2790 insn = emit_insn (gen_entry (GEN_INT (total_size)));
2791 else
2793 /* Use a8 as a temporary since a0-a7 may be live. */
2794 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2795 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2796 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2797 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2798 insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2801 else
2803 int regno;
2804 HOST_WIDE_INT offset = 0;
2805 int callee_save_size = cfun->machine->callee_save_size;
2807 /* -128 is a limit of single addi instruction. */
2808 if (total_size > 0 && total_size <= 128)
2810 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2811 GEN_INT (-total_size)));
2812 RTX_FRAME_RELATED_P (insn) = 1;
2813 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2814 plus_constant (Pmode, stack_pointer_rtx,
2815 -total_size));
2816 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2817 offset = total_size - UNITS_PER_WORD;
2819 else if (callee_save_size)
2821 /* 1020 is maximal s32i offset, if the frame is bigger than that
2822 * we move sp to the end of callee-saved save area, save and then
2823 * move it to its final location. */
2824 if (total_size > 1024)
2826 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2827 GEN_INT (-callee_save_size)));
2828 RTX_FRAME_RELATED_P (insn) = 1;
2829 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2830 plus_constant (Pmode, stack_pointer_rtx,
2831 -callee_save_size));
2832 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2833 offset = callee_save_size - UNITS_PER_WORD;
2835 else
2837 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2838 emit_move_insn (tmp_reg, GEN_INT (total_size));
2839 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
2840 stack_pointer_rtx, tmp_reg));
2841 RTX_FRAME_RELATED_P (insn) = 1;
2842 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2843 plus_constant (Pmode, stack_pointer_rtx,
2844 -total_size));
2845 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2846 offset = total_size - UNITS_PER_WORD;
2850 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2852 if (xtensa_call_save_reg(regno))
2854 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2855 rtx mem = gen_frame_mem (SImode, x);
2856 rtx reg = gen_rtx_REG (SImode, regno);
2858 offset -= UNITS_PER_WORD;
2859 insn = emit_move_insn (mem, reg);
2860 RTX_FRAME_RELATED_P (insn) = 1;
2861 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
2862 gen_rtx_SET (mem, reg));
2865 if (total_size > 1024)
2867 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2868 emit_move_insn (tmp_reg, GEN_INT (total_size -
2869 callee_save_size));
2870 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
2871 stack_pointer_rtx, tmp_reg));
2872 RTX_FRAME_RELATED_P (insn) = 1;
2873 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2874 plus_constant (Pmode, stack_pointer_rtx,
2875 callee_save_size -
2876 total_size));
2877 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2881 if (frame_pointer_needed)
2883 if (cfun->machine->set_frame_ptr_insn)
2885 rtx_insn *first;
2887 push_topmost_sequence ();
2888 first = get_insns ();
2889 pop_topmost_sequence ();
2891 /* For all instructions prior to set_frame_ptr_insn, replace
2892 hard_frame_pointer references with stack_pointer. */
2893 for (insn = first;
2894 insn != cfun->machine->set_frame_ptr_insn;
2895 insn = NEXT_INSN (insn))
2897 if (INSN_P (insn))
2899 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2900 hard_frame_pointer_rtx,
2901 stack_pointer_rtx);
2902 df_insn_rescan (insn);
2906 else
2908 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2909 stack_pointer_rtx));
2910 if (!TARGET_WINDOWED_ABI)
2912 note_rtx = gen_rtx_SET (hard_frame_pointer_rtx,
2913 stack_pointer_rtx);
2914 RTX_FRAME_RELATED_P (insn) = 1;
2915 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2920 if (TARGET_WINDOWED_ABI)
2922 /* Create a note to describe the CFA. Because this is only used to set
2923 DW_AT_frame_base for debug info, don't bother tracking changes through
2924 each instruction in the prologue. It just takes up space. */
2925 note_rtx = gen_rtx_SET ((frame_pointer_needed
2926 ? hard_frame_pointer_rtx
2927 : stack_pointer_rtx),
2928 plus_constant (Pmode, stack_pointer_rtx,
2929 -total_size));
2930 RTX_FRAME_RELATED_P (insn) = 1;
2931 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2935 void
2936 xtensa_expand_epilogue (void)
2938 if (!TARGET_WINDOWED_ABI)
2940 int regno;
2941 HOST_WIDE_INT offset;
2943 if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024))
2945 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2946 emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size -
2947 cfun->machine->callee_save_size));
2948 emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ?
2949 hard_frame_pointer_rtx : stack_pointer_rtx,
2950 tmp_reg));
2951 offset = cfun->machine->callee_save_size - UNITS_PER_WORD;
2953 else
2955 if (frame_pointer_needed)
2956 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
2957 offset = cfun->machine->current_frame_size - UNITS_PER_WORD;
2960 /* Prevent reordering of saved a0 update and loading it back from
2961 the save area. */
2962 if (crtl->calls_eh_return)
2963 emit_insn (gen_blockage ());
2965 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2967 if (xtensa_call_save_reg(regno))
2969 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2971 offset -= UNITS_PER_WORD;
2972 emit_move_insn (gen_rtx_REG (SImode, regno),
2973 gen_frame_mem (SImode, x));
2977 if (cfun->machine->current_frame_size > 0)
2979 if (frame_pointer_needed || /* always reachable with addi */
2980 cfun->machine->current_frame_size > 1024 ||
2981 cfun->machine->current_frame_size <= 127)
2983 if (cfun->machine->current_frame_size <= 127)
2984 offset = cfun->machine->current_frame_size;
2985 else
2986 offset = cfun->machine->callee_save_size;
2988 emit_insn (gen_addsi3 (stack_pointer_rtx,
2989 stack_pointer_rtx,
2990 GEN_INT (offset)));
2992 else
2994 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2995 emit_move_insn (tmp_reg,
2996 GEN_INT (cfun->machine->current_frame_size));
2997 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2998 tmp_reg));
3002 if (crtl->calls_eh_return)
3003 emit_insn (gen_add3_insn (stack_pointer_rtx,
3004 stack_pointer_rtx,
3005 EH_RETURN_STACKADJ_RTX));
3007 cfun->machine->epilogue_done = true;
3008 emit_jump_insn (gen_return ());
3011 bool
3012 xtensa_use_return_instruction_p (void)
3014 if (!reload_completed)
3015 return false;
3016 if (TARGET_WINDOWED_ABI)
3017 return true;
3018 if (compute_frame_size (get_frame_size ()) == 0)
3019 return true;
3020 return cfun->machine->epilogue_done;
3023 void
3024 xtensa_set_return_address (rtx address, rtx scratch)
3026 HOST_WIDE_INT total_size = compute_frame_size (get_frame_size ());
3027 rtx frame = frame_pointer_needed ?
3028 hard_frame_pointer_rtx : stack_pointer_rtx;
3029 rtx a0_addr = plus_constant (Pmode, frame,
3030 total_size - UNITS_PER_WORD);
3031 rtx note = gen_rtx_SET (gen_frame_mem (SImode, a0_addr),
3032 gen_rtx_REG (SImode, A0_REG));
3033 rtx insn;
3035 if (total_size > 1024) {
3036 emit_move_insn (scratch, GEN_INT (total_size - UNITS_PER_WORD));
3037 emit_insn (gen_addsi3 (scratch, frame, scratch));
3038 a0_addr = scratch;
3041 insn = emit_move_insn (gen_frame_mem (SImode, a0_addr), address);
3042 RTX_FRAME_RELATED_P (insn) = 1;
3043 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
3047 xtensa_return_addr (int count, rtx frame)
3049 rtx result, retaddr, curaddr, label;
3051 if (!TARGET_WINDOWED_ABI)
3053 if (count != 0)
3054 return const0_rtx;
3056 return get_hard_reg_initial_val (Pmode, A0_REG);
3059 if (count == -1)
3060 retaddr = gen_rtx_REG (Pmode, A0_REG);
3061 else
3063 rtx addr = plus_constant (Pmode, frame, -4 * UNITS_PER_WORD);
3064 addr = memory_address (Pmode, addr);
3065 retaddr = gen_reg_rtx (Pmode);
3066 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
3069 /* The 2 most-significant bits of the return address on Xtensa hold
3070 the register window size. To get the real return address, these
3071 bits must be replaced with the high bits from some address in the
3072 code. */
3074 /* Get the 2 high bits of a local label in the code. */
3075 curaddr = gen_reg_rtx (Pmode);
3076 label = gen_label_rtx ();
3077 emit_label (label);
3078 LABEL_PRESERVE_P (label) = 1;
3079 emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
3080 emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
3081 emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
3083 /* Clear the 2 high bits of the return address. */
3084 result = gen_reg_rtx (Pmode);
3085 emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
3086 emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
3088 /* Combine them to get the result. */
3089 emit_insn (gen_iorsi3 (result, result, curaddr));
3090 return result;
3093 /* Disable the use of word-sized or smaller complex modes for structures,
3094 and for function arguments in particular, where they cause problems with
3095 register a7. The xtensa_copy_incoming_a7 function assumes that there is
3096 a single reference to an argument in a7, but with small complex modes the
3097 real and imaginary components may be extracted separately, leading to two
3098 uses of the register, only one of which would be replaced. */
3100 static bool
3101 xtensa_member_type_forces_blk (const_tree, machine_mode mode)
3103 return mode == CQImode || mode == CHImode;
3106 /* Create the va_list data type.
3108 This structure is set up by __builtin_saveregs. The __va_reg field
3109 points to a stack-allocated region holding the contents of the
3110 incoming argument registers. The __va_ndx field is an index
3111 initialized to the position of the first unnamed (variable)
3112 argument. This same index is also used to address the arguments
3113 passed in memory. Thus, the __va_stk field is initialized to point
3114 to the position of the first argument in memory offset to account
3115 for the arguments passed in registers and to account for the size
3116 of the argument registers not being 16-byte aligned. E.G., there
3117 are 6 argument registers of 4 bytes each, but we want the __va_ndx
3118 for the first stack argument to have the maximal alignment of 16
3119 bytes, so we offset the __va_stk address by 32 bytes so that
3120 __va_stk[32] references the first argument on the stack. */
3122 static tree
3123 xtensa_build_builtin_va_list (void)
3125 tree f_stk, f_reg, f_ndx, record, type_decl;
3127 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
3128 type_decl = build_decl (BUILTINS_LOCATION,
3129 TYPE_DECL, get_identifier ("__va_list_tag"), record);
3131 f_stk = build_decl (BUILTINS_LOCATION,
3132 FIELD_DECL, get_identifier ("__va_stk"),
3133 ptr_type_node);
3134 f_reg = build_decl (BUILTINS_LOCATION,
3135 FIELD_DECL, get_identifier ("__va_reg"),
3136 ptr_type_node);
3137 f_ndx = build_decl (BUILTINS_LOCATION,
3138 FIELD_DECL, get_identifier ("__va_ndx"),
3139 integer_type_node);
3141 DECL_FIELD_CONTEXT (f_stk) = record;
3142 DECL_FIELD_CONTEXT (f_reg) = record;
3143 DECL_FIELD_CONTEXT (f_ndx) = record;
3145 TYPE_STUB_DECL (record) = type_decl;
3146 TYPE_NAME (record) = type_decl;
3147 TYPE_FIELDS (record) = f_stk;
3148 DECL_CHAIN (f_stk) = f_reg;
3149 DECL_CHAIN (f_reg) = f_ndx;
3151 layout_type (record);
3152 return record;
3156 /* Save the incoming argument registers on the stack. Returns the
3157 address of the saved registers. */
3159 static rtx
3160 xtensa_builtin_saveregs (void)
3162 rtx gp_regs;
3163 int arg_words = crtl->args.info.arg_words;
3164 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
3166 if (gp_left <= 0)
3167 return const0_rtx;
3169 /* Allocate the general-purpose register space. */
3170 gp_regs = assign_stack_local
3171 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
3172 set_mem_alias_set (gp_regs, get_varargs_alias_set ());
3174 /* Now store the incoming registers. */
3175 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI;
3176 cfun->machine->vararg_a7 = true;
3177 move_block_from_reg (GP_ARG_FIRST + arg_words,
3178 adjust_address (gp_regs, BLKmode,
3179 arg_words * UNITS_PER_WORD),
3180 gp_left);
3181 if (cfun->machine->vararg_a7_copy != 0)
3182 emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
3184 return XEXP (gp_regs, 0);
3188 /* Implement `va_start' for varargs and stdarg. We look at the
3189 current function to fill in an initial va_list. */
3191 static void
3192 xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
3194 tree f_stk, stk;
3195 tree f_reg, reg;
3196 tree f_ndx, ndx;
3197 tree t, u;
3198 int arg_words;
3200 arg_words = crtl->args.info.arg_words;
3202 f_stk = TYPE_FIELDS (va_list_type_node);
3203 f_reg = DECL_CHAIN (f_stk);
3204 f_ndx = DECL_CHAIN (f_reg);
3206 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
3207 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
3208 f_reg, NULL_TREE);
3209 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
3210 f_ndx, NULL_TREE);
3212 /* Call __builtin_saveregs; save the result in __va_reg */
3213 u = make_tree (sizetype, expand_builtin_saveregs ());
3214 u = fold_convert (ptr_type_node, u);
3215 t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
3216 TREE_SIDE_EFFECTS (t) = 1;
3217 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3219 /* Set the __va_stk member to ($arg_ptr - 32). */
3220 u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3221 u = fold_build_pointer_plus_hwi (u, -32);
3222 t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
3223 TREE_SIDE_EFFECTS (t) = 1;
3224 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3226 /* Set the __va_ndx member. If the first variable argument is on
3227 the stack, adjust __va_ndx by 2 words to account for the extra
3228 alignment offset for __va_stk. */
3229 if (arg_words >= MAX_ARGS_IN_REGISTERS)
3230 arg_words += 2;
3231 t = build2 (MODIFY_EXPR, integer_type_node, ndx,
3232 build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
3233 TREE_SIDE_EFFECTS (t) = 1;
3234 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3238 /* Implement `va_arg'. */
3240 static tree
3241 xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
3242 gimple_seq *post_p ATTRIBUTE_UNUSED)
3244 tree f_stk, stk;
3245 tree f_reg, reg;
3246 tree f_ndx, ndx;
3247 tree type_size, array, orig_ndx, addr, size, va_size, t;
3248 tree lab_false, lab_over, lab_false2;
3249 bool indirect;
3251 indirect = pass_by_reference (NULL, TYPE_MODE (type), type, false);
3252 if (indirect)
3253 type = build_pointer_type (type);
3255 /* Handle complex values as separate real and imaginary parts. */
3256 if (TREE_CODE (type) == COMPLEX_TYPE)
3258 tree real_part, imag_part;
3260 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
3261 pre_p, NULL);
3262 real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
3264 imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
3265 TREE_TYPE (type),
3266 pre_p, NULL);
3267 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
3269 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
3272 f_stk = TYPE_FIELDS (va_list_type_node);
3273 f_reg = DECL_CHAIN (f_stk);
3274 f_ndx = DECL_CHAIN (f_reg);
3276 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
3277 f_stk, NULL_TREE);
3278 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
3279 f_reg, NULL_TREE);
3280 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
3281 f_ndx, NULL_TREE);
3283 type_size = size_in_bytes (type);
3284 va_size = round_up (type_size, UNITS_PER_WORD);
3285 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
3288 /* First align __va_ndx if necessary for this arg:
3290 orig_ndx = (AP).__va_ndx;
3291 if (__alignof__ (TYPE) > 4 )
3292 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3293 & -__alignof__ (TYPE)); */
3295 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
3297 if (TYPE_ALIGN (type) > BITS_PER_WORD)
3299 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
3301 t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
3302 build_int_cst (integer_type_node, align - 1));
3303 t = build2 (BIT_AND_EXPR, integer_type_node, t,
3304 build_int_cst (integer_type_node, -align));
3305 gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
3309 /* Increment __va_ndx to point past the argument:
3311 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3313 t = fold_convert (integer_type_node, va_size);
3314 t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
3315 gimplify_assign (unshare_expr (ndx), t, pre_p);
3318 /* Check if the argument is in registers:
3320 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3321 && !must_pass_in_stack (type))
3322 __array = (AP).__va_reg; */
3324 array = create_tmp_var (ptr_type_node);
3326 lab_over = NULL;
3327 if (!targetm.calls.must_pass_in_stack (TYPE_MODE (type), type))
3329 lab_false = create_artificial_label (UNKNOWN_LOCATION);
3330 lab_over = create_artificial_label (UNKNOWN_LOCATION);
3332 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
3333 build_int_cst (integer_type_node,
3334 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
3335 t = build3 (COND_EXPR, void_type_node, t,
3336 build1 (GOTO_EXPR, void_type_node, lab_false),
3337 NULL_TREE);
3338 gimplify_and_add (t, pre_p);
3340 gimplify_assign (unshare_expr (array), reg, pre_p);
3342 t = build1 (GOTO_EXPR, void_type_node, lab_over);
3343 gimplify_and_add (t, pre_p);
3345 t = build1 (LABEL_EXPR, void_type_node, lab_false);
3346 gimplify_and_add (t, pre_p);
3350 /* ...otherwise, the argument is on the stack (never split between
3351 registers and the stack -- change __va_ndx if necessary):
3353 else
3355 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3356 (AP).__va_ndx = 32 + __va_size (TYPE);
3357 __array = (AP).__va_stk;
3358 } */
3360 lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
3362 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
3363 build_int_cst (integer_type_node,
3364 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
3365 t = build3 (COND_EXPR, void_type_node, t,
3366 build1 (GOTO_EXPR, void_type_node, lab_false2),
3367 NULL_TREE);
3368 gimplify_and_add (t, pre_p);
3370 t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
3371 t = fold_convert (integer_type_node, t);
3372 gimplify_assign (unshare_expr (ndx), t, pre_p);
3374 t = build1 (LABEL_EXPR, void_type_node, lab_false2);
3375 gimplify_and_add (t, pre_p);
3377 gimplify_assign (array, stk, pre_p);
3379 if (lab_over)
3381 t = build1 (LABEL_EXPR, void_type_node, lab_over);
3382 gimplify_and_add (t, pre_p);
3386 /* Given the base array pointer (__array) and index to the subsequent
3387 argument (__va_ndx), find the address:
3389 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3390 ? sizeof (TYPE)
3391 : __va_size (TYPE))
3393 The results are endian-dependent because values smaller than one word
3394 are aligned differently. */
3397 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
3399 t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
3400 size_int (PARM_BOUNDARY / BITS_PER_UNIT));
3401 t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
3402 unshare_expr (type_size));
3403 size = t;
3405 else
3406 size = unshare_expr (va_size);
3408 t = fold_convert (sizetype, unshare_expr (ndx));
3409 t = build2 (MINUS_EXPR, sizetype, t, size);
3410 addr = fold_build_pointer_plus (unshare_expr (array), t);
3412 addr = fold_convert (build_pointer_type (type), addr);
3413 if (indirect)
3414 addr = build_va_arg_indirect_ref (addr);
3415 return build_va_arg_indirect_ref (addr);
3419 /* Builtins. */
3421 enum xtensa_builtin
3423 XTENSA_BUILTIN_UMULSIDI3,
3424 XTENSA_BUILTIN_max
3428 static void
3429 xtensa_init_builtins (void)
3431 tree ftype, decl;
3433 ftype = build_function_type_list (unsigned_intDI_type_node,
3434 unsigned_intSI_type_node,
3435 unsigned_intSI_type_node, NULL_TREE);
3437 decl = add_builtin_function ("__builtin_umulsidi3", ftype,
3438 XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
3439 "__umulsidi3", NULL_TREE);
3440 TREE_NOTHROW (decl) = 1;
3441 TREE_READONLY (decl) = 1;
3445 static tree
3446 xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
3447 bool ignore ATTRIBUTE_UNUSED)
3449 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3450 tree arg0, arg1;
3452 switch (fcode)
3454 case XTENSA_BUILTIN_UMULSIDI3:
3455 arg0 = args[0];
3456 arg1 = args[1];
3457 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3458 || TARGET_MUL32_HIGH)
3459 return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
3460 fold_convert (unsigned_intDI_type_node, arg0),
3461 fold_convert (unsigned_intDI_type_node, arg1));
3462 break;
3464 default:
3465 internal_error ("bad builtin code");
3466 break;
3469 return NULL;
3473 static rtx
3474 xtensa_expand_builtin (tree exp, rtx target,
3475 rtx subtarget ATTRIBUTE_UNUSED,
3476 machine_mode mode ATTRIBUTE_UNUSED,
3477 int ignore)
3479 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3480 unsigned int fcode = DECL_FUNCTION_CODE (fndecl);
3482 switch (fcode)
3484 case XTENSA_BUILTIN_UMULSIDI3:
3485 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3486 __umulsidi3 function when the Xtensa configuration can directly
3487 implement it. If not, just call the function. */
3488 return expand_call (exp, target, ignore);
3490 default:
3491 internal_error ("bad builtin code");
3493 return NULL_RTX;
3496 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3498 static reg_class_t
3499 xtensa_preferred_reload_class (rtx x, reg_class_t rclass)
3501 if (CONSTANT_P (x) && CONST_DOUBLE_P (x))
3502 return NO_REGS;
3504 /* Don't use the stack pointer or hard frame pointer for reloads!
3505 The hard frame pointer would normally be OK except that it may
3506 briefly hold an incoming argument in the prologue, and reload
3507 won't know that it is live because the hard frame pointer is
3508 treated specially. */
3510 if (rclass == AR_REGS || rclass == GR_REGS)
3511 return RL_REGS;
3513 return rclass;
3516 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3518 static reg_class_t
3519 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED,
3520 reg_class_t rclass)
3522 /* Don't use the stack pointer or hard frame pointer for reloads!
3523 The hard frame pointer would normally be OK except that it may
3524 briefly hold an incoming argument in the prologue, and reload
3525 won't know that it is live because the hard frame pointer is
3526 treated specially. */
3528 if (rclass == AR_REGS || rclass == GR_REGS)
3529 return RL_REGS;
3531 return rclass;
3534 /* Worker function for TARGET_SECONDARY_RELOAD. */
3536 static reg_class_t
3537 xtensa_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
3538 machine_mode mode, secondary_reload_info *sri)
3540 int regno;
3542 if (in_p && constantpool_mem_p (x))
3544 if (rclass == FP_REGS)
3545 return RL_REGS;
3547 if (mode == QImode)
3548 sri->icode = CODE_FOR_reloadqi_literal;
3549 else if (mode == HImode)
3550 sri->icode = CODE_FOR_reloadhi_literal;
3553 regno = xt_true_regnum (x);
3554 if (ACC_REG_P (regno))
3555 return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3556 if (rclass == ACC_REG)
3557 return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3559 return NO_REGS;
3563 void
3564 order_regs_for_local_alloc (void)
3566 if (!leaf_function_p ())
3568 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
3569 REG_ALLOC_ORDER;
3570 static const int reg_nonleaf_alloc_order_call0[FIRST_PSEUDO_REGISTER] =
3572 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
3574 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
3575 0, 1, 16, 17,
3579 memcpy (reg_alloc_order, TARGET_WINDOWED_ABI ?
3580 reg_nonleaf_alloc_order : reg_nonleaf_alloc_order_call0,
3581 FIRST_PSEUDO_REGISTER * sizeof (int));
3583 else
3585 int i, num_arg_regs;
3586 int nxt = 0;
3588 /* Use the AR registers in increasing order (skipping a0 and a1)
3589 but save the incoming argument registers for a last resort. */
3590 num_arg_regs = crtl->args.info.arg_words;
3591 if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3592 num_arg_regs = MAX_ARGS_IN_REGISTERS;
3593 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3594 reg_alloc_order[nxt++] = i + num_arg_regs;
3595 for (i = 0; i < num_arg_regs; i++)
3596 reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3598 /* List the coprocessor registers in order. */
3599 for (i = 0; i < BR_REG_NUM; i++)
3600 reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3602 /* List the FP registers in order for now. */
3603 for (i = 0; i < 16; i++)
3604 reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3606 /* GCC requires that we list *all* the registers.... */
3607 reg_alloc_order[nxt++] = 0; /* a0 = return address */
3608 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */
3609 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */
3610 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */
3612 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */
3617 /* Some Xtensa targets support multiple bss sections. If the section
3618 name ends with ".bss", add SECTION_BSS to the flags. */
3620 static unsigned int
3621 xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3623 unsigned int flags = default_section_type_flags (decl, name, reloc);
3624 const char *suffix;
3626 suffix = strrchr (name, '.');
3627 if (suffix && strcmp (suffix, ".bss") == 0)
3629 if (!decl || (TREE_CODE (decl) == VAR_DECL
3630 && DECL_INITIAL (decl) == NULL_TREE))
3631 flags |= SECTION_BSS; /* @nobits */
3632 else
3633 warning (0, "only uninitialized variables can be placed in a "
3634 ".bss section");
3637 return flags;
3641 /* The literal pool stays with the function. */
3643 static section *
3644 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
3645 rtx x ATTRIBUTE_UNUSED,
3646 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3648 return function_section (current_function_decl);
3651 /* Worker function for TARGET_REGISTER_MOVE_COST. */
3653 static int
3654 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3655 reg_class_t from, reg_class_t to)
3657 if (from == to && from != BR_REGS && to != BR_REGS)
3658 return 2;
3659 else if (reg_class_subset_p (from, AR_REGS)
3660 && reg_class_subset_p (to, AR_REGS))
3661 return 2;
3662 else if (reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
3663 return 3;
3664 else if (from == ACC_REG && reg_class_subset_p (to, AR_REGS))
3665 return 3;
3666 else
3667 return 10;
3670 /* Worker function for TARGET_MEMORY_MOVE_COST. */
3672 static int
3673 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3674 reg_class_t rclass ATTRIBUTE_UNUSED,
3675 bool in ATTRIBUTE_UNUSED)
3677 return 4;
3680 /* Compute a (partial) cost for rtx X. Return true if the complete
3681 cost has been computed, and false if subexpressions should be
3682 scanned. In either case, *TOTAL contains the cost result. */
3684 static bool
3685 xtensa_rtx_costs (rtx x, machine_mode mode, int outer_code,
3686 int opno ATTRIBUTE_UNUSED,
3687 int *total, bool speed ATTRIBUTE_UNUSED)
3689 int code = GET_CODE (x);
3691 switch (code)
3693 case CONST_INT:
3694 switch (outer_code)
3696 case SET:
3697 if (xtensa_simm12b (INTVAL (x)))
3699 *total = 4;
3700 return true;
3702 break;
3703 case PLUS:
3704 if (xtensa_simm8 (INTVAL (x))
3705 || xtensa_simm8x256 (INTVAL (x)))
3707 *total = 0;
3708 return true;
3710 break;
3711 case AND:
3712 if (xtensa_mask_immediate (INTVAL (x)))
3714 *total = 0;
3715 return true;
3717 break;
3718 case COMPARE:
3719 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3721 *total = 0;
3722 return true;
3724 break;
3725 case ASHIFT:
3726 case ASHIFTRT:
3727 case LSHIFTRT:
3728 case ROTATE:
3729 case ROTATERT:
3730 /* No way to tell if X is the 2nd operand so be conservative. */
3731 default: break;
3733 if (xtensa_simm12b (INTVAL (x)))
3734 *total = 5;
3735 else if (TARGET_CONST16)
3736 *total = COSTS_N_INSNS (2);
3737 else
3738 *total = 6;
3739 return true;
3741 case CONST:
3742 case LABEL_REF:
3743 case SYMBOL_REF:
3744 if (TARGET_CONST16)
3745 *total = COSTS_N_INSNS (2);
3746 else
3747 *total = 5;
3748 return true;
3750 case CONST_DOUBLE:
3751 if (TARGET_CONST16)
3752 *total = COSTS_N_INSNS (4);
3753 else
3754 *total = 7;
3755 return true;
3757 case MEM:
3759 int num_words =
3760 (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3762 if (memory_address_p (mode, XEXP ((x), 0)))
3763 *total = COSTS_N_INSNS (num_words);
3764 else
3765 *total = COSTS_N_INSNS (2*num_words);
3766 return true;
3769 case FFS:
3770 case CTZ:
3771 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3772 return true;
3774 case CLZ:
3775 *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3776 return true;
3778 case NOT:
3779 *total = COSTS_N_INSNS (mode == DImode ? 3 : 2);
3780 return true;
3782 case AND:
3783 case IOR:
3784 case XOR:
3785 if (mode == DImode)
3786 *total = COSTS_N_INSNS (2);
3787 else
3788 *total = COSTS_N_INSNS (1);
3789 return true;
3791 case ASHIFT:
3792 case ASHIFTRT:
3793 case LSHIFTRT:
3794 if (mode == DImode)
3795 *total = COSTS_N_INSNS (50);
3796 else
3797 *total = COSTS_N_INSNS (1);
3798 return true;
3800 case ABS:
3802 if (mode == SFmode)
3803 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3804 else if (mode == DFmode)
3805 *total = COSTS_N_INSNS (50);
3806 else
3807 *total = COSTS_N_INSNS (4);
3808 return true;
3811 case PLUS:
3812 case MINUS:
3814 if (mode == SFmode)
3815 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3816 else if (mode == DFmode || mode == DImode)
3817 *total = COSTS_N_INSNS (50);
3818 else
3819 *total = COSTS_N_INSNS (1);
3820 return true;
3823 case NEG:
3824 *total = COSTS_N_INSNS (mode == DImode ? 4 : 2);
3825 return true;
3827 case MULT:
3829 if (mode == SFmode)
3830 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3831 else if (mode == DFmode)
3832 *total = COSTS_N_INSNS (50);
3833 else if (mode == DImode)
3834 *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3835 else if (TARGET_MUL32)
3836 *total = COSTS_N_INSNS (4);
3837 else if (TARGET_MAC16)
3838 *total = COSTS_N_INSNS (16);
3839 else if (TARGET_MUL16)
3840 *total = COSTS_N_INSNS (12);
3841 else
3842 *total = COSTS_N_INSNS (50);
3843 return true;
3846 case DIV:
3847 case MOD:
3849 if (mode == SFmode)
3851 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3852 return true;
3854 else if (mode == DFmode)
3856 *total = COSTS_N_INSNS (50);
3857 return true;
3860 /* Fall through. */
3862 case UDIV:
3863 case UMOD:
3865 if (mode == DImode)
3866 *total = COSTS_N_INSNS (50);
3867 else if (TARGET_DIV32)
3868 *total = COSTS_N_INSNS (32);
3869 else
3870 *total = COSTS_N_INSNS (50);
3871 return true;
3874 case SQRT:
3875 if (mode == SFmode)
3876 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3877 else
3878 *total = COSTS_N_INSNS (50);
3879 return true;
3881 case SMIN:
3882 case UMIN:
3883 case SMAX:
3884 case UMAX:
3885 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3886 return true;
3888 case SIGN_EXTRACT:
3889 case SIGN_EXTEND:
3890 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3891 return true;
3893 case ZERO_EXTRACT:
3894 case ZERO_EXTEND:
3895 *total = COSTS_N_INSNS (1);
3896 return true;
3898 default:
3899 return false;
3903 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3905 static bool
3906 xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3908 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3909 > 4 * UNITS_PER_WORD);
3912 /* Worker function for TARGET_FUNCTION_VALUE. */
3915 xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3916 bool outgoing)
3918 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3919 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3920 ? SImode : TYPE_MODE (valtype),
3921 outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3924 /* Worker function for TARGET_LIBCALL_VALUE. */
3926 static rtx
3927 xtensa_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
3929 return gen_rtx_REG ((GET_MODE_CLASS (mode) == MODE_INT
3930 && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3931 ? SImode : mode, GP_RETURN);
3934 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
3936 static bool
3937 xtensa_function_value_regno_p (const unsigned int regno)
3939 return (regno == GP_RETURN);
3942 /* The static chain is passed in memory. Provide rtx giving 'mem'
3943 expressions that denote where they are stored. */
3945 static rtx
3946 xtensa_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
3948 if (TARGET_WINDOWED_ABI)
3950 rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3951 return gen_frame_mem (Pmode, plus_constant (Pmode, base,
3952 -5 * UNITS_PER_WORD));
3954 else
3955 return gen_rtx_REG (Pmode, A8_REG);
3959 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3960 instruction with a minimal stack frame in order to get some free
3961 registers. Once the actual call target is known, the proper stack frame
3962 size is extracted from the ENTRY instruction at the target and the
3963 current frame is adjusted to match. The trampoline then transfers
3964 control to the instruction following the ENTRY at the target. Note:
3965 this assumes that the target begins with an ENTRY instruction. */
3967 static void
3968 xtensa_asm_trampoline_template (FILE *stream)
3970 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3972 fprintf (stream, "\t.begin no-transform\n");
3974 if (TARGET_WINDOWED_ABI)
3976 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3978 if (use_call0)
3980 /* Save the return address. */
3981 fprintf (stream, "\tmov\ta10, a0\n");
3983 /* Use a CALL0 instruction to skip past the constants and in the
3984 process get the PC into A0. This allows PC-relative access to
3985 the constants without relying on L32R. */
3986 fprintf (stream, "\tcall0\t.Lskipconsts\n");
3988 else
3989 fprintf (stream, "\tj\t.Lskipconsts\n");
3991 fprintf (stream, "\t.align\t4\n");
3992 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3993 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3994 fprintf (stream, ".Lskipconsts:\n");
3996 /* Load the static chain and function address from the trampoline. */
3997 if (use_call0)
3999 fprintf (stream, "\taddi\ta0, a0, 3\n");
4000 fprintf (stream, "\tl32i\ta9, a0, 0\n");
4001 fprintf (stream, "\tl32i\ta8, a0, 4\n");
4003 else
4005 fprintf (stream, "\tl32r\ta9, .Lchainval\n");
4006 fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
4009 /* Store the static chain. */
4010 fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
4012 /* Set the proper stack pointer value. */
4013 fprintf (stream, "\tl32i\ta9, a8, 0\n");
4014 fprintf (stream, "\textui\ta9, a9, %d, 12\n",
4015 TARGET_BIG_ENDIAN ? 8 : 12);
4016 fprintf (stream, "\tslli\ta9, a9, 3\n");
4017 fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
4018 fprintf (stream, "\tsub\ta9, sp, a9\n");
4019 fprintf (stream, "\tmovsp\tsp, a9\n");
4021 if (use_call0)
4022 /* Restore the return address. */
4023 fprintf (stream, "\tmov\ta0, a10\n");
4025 /* Jump to the instruction following the ENTRY. */
4026 fprintf (stream, "\taddi\ta8, a8, 3\n");
4027 fprintf (stream, "\tjx\ta8\n");
4029 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4030 if (use_call0)
4031 fprintf (stream, "\t.byte\t0\n");
4032 else
4033 fprintf (stream, "\tnop\n");
4035 else
4037 if (use_call0)
4039 /* Save the return address. */
4040 fprintf (stream, "\tmov\ta10, a0\n");
4042 /* Use a CALL0 instruction to skip past the constants and in the
4043 process get the PC into A0. This allows PC-relative access to
4044 the constants without relying on L32R. */
4045 fprintf (stream, "\tcall0\t.Lskipconsts\n");
4047 else
4048 fprintf (stream, "\tj\t.Lskipconsts\n");
4050 fprintf (stream, "\t.align\t4\n");
4051 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
4052 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
4053 fprintf (stream, ".Lskipconsts:\n");
4055 /* Load the static chain and function address from the trampoline. */
4056 if (use_call0)
4058 fprintf (stream, "\taddi\ta0, a0, 3\n");
4059 fprintf (stream, "\tl32i\ta8, a0, 0\n");
4060 fprintf (stream, "\tl32i\ta9, a0, 4\n");
4061 fprintf (stream, "\tmov\ta0, a10\n");
4063 else
4065 fprintf (stream, "\tl32r\ta8, .Lchainval\n");
4066 fprintf (stream, "\tl32r\ta9, .Lfnaddr\n");
4068 fprintf (stream, "\tjx\ta9\n");
4070 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4071 if (use_call0)
4072 fprintf (stream, "\t.byte\t0\n");
4073 else
4074 fprintf (stream, "\tnop\n");
4076 fprintf (stream, "\t.end no-transform\n");
4079 static void
4080 xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
4082 rtx func = XEXP (DECL_RTL (fndecl), 0);
4083 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
4084 int chain_off;
4085 int func_off;
4087 if (TARGET_WINDOWED_ABI)
4089 chain_off = use_call0 ? 12 : 8;
4090 func_off = use_call0 ? 16 : 12;
4092 else
4094 chain_off = use_call0 ? 8 : 4;
4095 func_off = use_call0 ? 12 : 8;
4098 emit_block_move (m_tramp, assemble_trampoline_template (),
4099 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4101 emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
4102 emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
4103 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
4104 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
4107 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
4109 static bool
4110 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
4112 return !xtensa_tls_referenced_p (x);
4115 /* Implement TARGET_CAN_USE_DOLOOP_P. */
4117 static bool
4118 xtensa_can_use_doloop_p (const widest_int &, const widest_int &,
4119 unsigned int loop_depth, bool entered_at_top)
4121 /* Considering limitations in the hardware, only use doloop
4122 for innermost loops which must be entered from the top. */
4123 if (loop_depth > 1 || !entered_at_top)
4124 return false;
4126 return true;
4129 /* NULL if INSN insn is valid within a low-overhead loop.
4130 Otherwise return why doloop cannot be applied. */
4132 static const char *
4133 xtensa_invalid_within_doloop (const rtx_insn *insn)
4135 if (CALL_P (insn))
4136 return "Function call in the loop.";
4138 if (JUMP_P (insn) && INSN_CODE (insn) == CODE_FOR_return)
4139 return "Return from a call instruction in the loop.";
4141 return NULL;
4144 /* Optimize LOOP. */
4146 static bool
4147 hwloop_optimize (hwloop_info loop)
4149 int i;
4150 edge entry_edge;
4151 basic_block entry_bb;
4152 rtx iter_reg;
4153 rtx_insn *insn, *seq, *entry_after;
4155 if (loop->depth > 1)
4157 if (dump_file)
4158 fprintf (dump_file, ";; loop %d is not innermost\n",
4159 loop->loop_no);
4160 return false;
4163 if (!loop->incoming_dest)
4165 if (dump_file)
4166 fprintf (dump_file, ";; loop %d has more than one entry\n",
4167 loop->loop_no);
4168 return false;
4171 if (loop->incoming_dest != loop->head)
4173 if (dump_file)
4174 fprintf (dump_file, ";; loop %d is not entered from head\n",
4175 loop->loop_no);
4176 return false;
4179 if (loop->has_call || loop->has_asm)
4181 if (dump_file)
4182 fprintf (dump_file, ";; loop %d has invalid insn\n",
4183 loop->loop_no);
4184 return false;
4187 /* Scan all the blocks to make sure they don't use iter_reg. */
4188 if (loop->iter_reg_used || loop->iter_reg_used_outside)
4190 if (dump_file)
4191 fprintf (dump_file, ";; loop %d uses iterator\n",
4192 loop->loop_no);
4193 return false;
4196 /* Check if start_label appears before doloop_end. */
4197 insn = loop->start_label;
4198 while (insn && insn != loop->loop_end)
4199 insn = NEXT_INSN (insn);
4201 if (!insn)
4203 if (dump_file)
4204 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
4205 loop->loop_no);
4206 return false;
4209 /* Get the loop iteration register. */
4210 iter_reg = loop->iter_reg;
4212 gcc_assert (REG_P (iter_reg));
4214 entry_edge = NULL;
4216 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
4217 if (entry_edge->flags & EDGE_FALLTHRU)
4218 break;
4220 if (entry_edge == NULL)
4221 return false;
4223 /* Place the zero_cost_loop_start instruction before the loop. */
4224 entry_bb = entry_edge->src;
4226 start_sequence ();
4228 insn = emit_insn (gen_zero_cost_loop_start (loop->iter_reg,
4229 loop->start_label,
4230 loop->iter_reg));
4232 seq = get_insns ();
4234 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1)
4236 basic_block new_bb;
4237 edge e;
4238 edge_iterator ei;
4240 emit_insn_before (seq, BB_HEAD (loop->head));
4241 seq = emit_label_before (gen_label_rtx (), seq);
4242 new_bb = create_basic_block (seq, insn, entry_bb);
4243 FOR_EACH_EDGE (e, ei, loop->incoming)
4245 if (!(e->flags & EDGE_FALLTHRU))
4246 redirect_edge_and_branch_force (e, new_bb);
4247 else
4248 redirect_edge_succ (e, new_bb);
4251 make_edge (new_bb, loop->head, 0);
4253 else
4255 entry_after = BB_END (entry_bb);
4256 while (DEBUG_INSN_P (entry_after)
4257 || (NOTE_P (entry_after)
4258 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
4259 entry_after = PREV_INSN (entry_after);
4261 emit_insn_after (seq, entry_after);
4264 end_sequence ();
4266 return true;
4269 /* A callback for the hw-doloop pass. Called when a loop we have discovered
4270 turns out not to be optimizable; we have to split the loop_end pattern into
4271 a subtract and a test. */
4273 static void
4274 hwloop_fail (hwloop_info loop)
4276 rtx test;
4277 rtx_insn *insn = loop->loop_end;
4279 emit_insn_before (gen_addsi3 (loop->iter_reg,
4280 loop->iter_reg,
4281 constm1_rtx),
4282 loop->loop_end);
4284 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
4285 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
4286 loop->iter_reg, const0_rtx,
4287 loop->start_label),
4288 loop->loop_end);
4290 JUMP_LABEL (insn) = loop->start_label;
4291 LABEL_NUSES (loop->start_label)++;
4292 delete_insn (loop->loop_end);
4295 /* A callback for the hw-doloop pass. This function examines INSN; if
4296 it is a doloop_end pattern we recognize, return the reg rtx for the
4297 loop counter. Otherwise, return NULL_RTX. */
4299 static rtx
4300 hwloop_pattern_reg (rtx_insn *insn)
4302 rtx reg;
4304 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
4305 return NULL_RTX;
4307 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
4308 if (!REG_P (reg))
4309 return NULL_RTX;
4311 return reg;
4315 static struct hw_doloop_hooks xtensa_doloop_hooks =
4317 hwloop_pattern_reg,
4318 hwloop_optimize,
4319 hwloop_fail
4322 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
4323 and tries to rewrite the RTL of these loops so that proper Xtensa
4324 hardware loops are generated. */
4326 static void
4327 xtensa_reorg_loops (void)
4329 if (TARGET_LOOPS)
4330 reorg_loops (false, &xtensa_doloop_hooks);
4333 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4335 static void
4336 xtensa_reorg (void)
4338 /* We are freeing block_for_insn in the toplev to keep compatibility
4339 with old MDEP_REORGS that are not CFG based. Recompute it now. */
4340 compute_bb_for_insn ();
4342 df_analyze ();
4344 /* Doloop optimization. */
4345 xtensa_reorg_loops ();
4348 /* Update register usage after having seen the compiler flags. */
4350 static void
4351 xtensa_conditional_register_usage (void)
4353 unsigned i, c_mask;
4355 c_mask = TARGET_WINDOWED_ABI ? (1 << 1) : (1 << 2);
4357 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4359 /* Set/reset conditionally defined registers from
4360 CALL_USED_REGISTERS initializer. */
4361 if (call_used_regs[i] > 1)
4362 call_used_regs[i] = !!(call_used_regs[i] & c_mask);
4365 /* Remove hard FP register from the preferred reload registers set. */
4366 CLEAR_HARD_REG_BIT (reg_class_contents[(int)RL_REGS],
4367 HARD_FRAME_POINTER_REGNUM);
4370 /* Map hard register number to register class */
4372 enum reg_class xtensa_regno_to_class (int regno)
4374 static const enum reg_class regno_to_class[FIRST_PSEUDO_REGISTER] =
4376 RL_REGS, SP_REG, RL_REGS, RL_REGS,
4377 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
4378 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
4379 RL_REGS, RL_REGS, RL_REGS, RL_REGS,
4380 AR_REGS, AR_REGS, BR_REGS,
4381 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
4382 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
4383 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
4384 FP_REGS, FP_REGS, FP_REGS, FP_REGS,
4385 ACC_REG,
4388 if (regno == HARD_FRAME_POINTER_REGNUM)
4389 return GR_REGS;
4390 else
4391 return regno_to_class[regno];
4394 /* Implement TARGET_CONSTANT_ALIGNMENT. Align string constants and
4395 constructors to at least a word boundary. The typical use of this
4396 macro is to increase alignment for string constants to be word
4397 aligned so that 'strcpy' calls that copy constants can be done
4398 inline. */
4400 static HOST_WIDE_INT
4401 xtensa_constant_alignment (const_tree exp, HOST_WIDE_INT align)
4403 if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
4404 && !optimize_size)
4405 return MAX (align, BITS_PER_WORD);
4406 return align;
4409 /* Implement TARGET_STARTING_FRAME_OFFSET. */
4411 static HOST_WIDE_INT
4412 xtensa_starting_frame_offset (void)
4414 if (FRAME_GROWS_DOWNWARD)
4415 return 0;
4416 return crtl->outgoing_args_size;
4419 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
4421 static unsigned HOST_WIDE_INT
4422 xtensa_asan_shadow_offset (void)
4424 return HOST_WIDE_INT_UC (0x10000000);
4427 #include "gt-xtensa.h"