1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright (C) 2001-2020 Free Software Foundation, Inc.
3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21 #define IN_TARGET_CODE 1
22
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"
58
59 /* This file should be included last. */
60 #include "target-def.h"
61
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. */
65
66 enum internal_test
67 {
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
79 };
80
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];
85
86 /* Largest block move to handle in-line. */
87 #define LARGEST_MOVE_RATIO 15
88
89 /* Define the structure for the machine field in struct function. */
90 struct GTY(()) machine_function
91 {
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;
104 };
105
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. */
109
110 const char xtensa_leaf_regs[FIRST_PSEUDO_REGISTER] =
111 {
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,
115 1
116 };
117
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,
145 const function_arg_info &);
146 static rtx xtensa_function_arg (cumulative_args_t, const function_arg_info &);
147 static rtx xtensa_function_incoming_arg (cumulative_args_t,
148 const function_arg_info &);
149 static rtx xtensa_function_value (const_tree, const_tree, bool);
150 static rtx xtensa_libcall_value (machine_mode, const_rtx);
151 static bool xtensa_function_value_regno_p (const unsigned int);
152 static unsigned int xtensa_function_arg_boundary (machine_mode,
153 const_tree);
154 static void xtensa_init_builtins (void);
155 static tree xtensa_fold_builtin (tree, int, tree *, bool);
156 static rtx xtensa_expand_builtin (tree, rtx, rtx, machine_mode, int);
157 static void xtensa_va_start (tree, rtx);
158 static bool xtensa_frame_pointer_required (void);
159 static rtx xtensa_static_chain (const_tree, bool);
160 static void xtensa_asm_trampoline_template (FILE *);
161 static void xtensa_trampoline_init (rtx, tree, rtx);
162 static bool xtensa_output_addr_const_extra (FILE *, rtx);
163 static bool xtensa_cannot_force_const_mem (machine_mode, rtx);
164
165 static reg_class_t xtensa_preferred_reload_class (rtx, reg_class_t);
166 static reg_class_t xtensa_preferred_output_reload_class (rtx, reg_class_t);
167 static reg_class_t xtensa_secondary_reload (bool, rtx, reg_class_t,
168 machine_mode,
169 struct secondary_reload_info *);
170
171 static bool constantpool_address_p (const_rtx addr);
172 static bool xtensa_legitimate_constant_p (machine_mode, rtx);
173 static void xtensa_reorg (void);
174 static bool xtensa_can_use_doloop_p (const widest_int &, const widest_int &,
175 unsigned int, bool);
176 static const char *xtensa_invalid_within_doloop (const rtx_insn *);
177
178 static bool xtensa_member_type_forces_blk (const_tree,
179 machine_mode mode);
180
181 static void xtensa_conditional_register_usage (void);
182 static unsigned int xtensa_hard_regno_nregs (unsigned int, machine_mode);
183 static bool xtensa_hard_regno_mode_ok (unsigned int, machine_mode);
184 static bool xtensa_modes_tieable_p (machine_mode, machine_mode);
185 static HOST_WIDE_INT xtensa_constant_alignment (const_tree, HOST_WIDE_INT);
186 static HOST_WIDE_INT xtensa_starting_frame_offset (void);
187 static unsigned HOST_WIDE_INT xtensa_asan_shadow_offset (void);
188
189
190
191 /* These hooks specify assembly directives for creating certain kinds
192 of integer object. */
193
194 #undef TARGET_ASM_ALIGNED_SI_OP
195 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
196
197 #undef TARGET_ASM_SELECT_RTX_SECTION
198 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
199
200 #undef TARGET_LEGITIMIZE_ADDRESS
201 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
202 #undef TARGET_MODE_DEPENDENT_ADDRESS_P
203 #define TARGET_MODE_DEPENDENT_ADDRESS_P xtensa_mode_dependent_address_p
204
205 #undef TARGET_REGISTER_MOVE_COST
206 #define TARGET_REGISTER_MOVE_COST xtensa_register_move_cost
207 #undef TARGET_MEMORY_MOVE_COST
208 #define TARGET_MEMORY_MOVE_COST xtensa_memory_move_cost
209 #undef TARGET_RTX_COSTS
210 #define TARGET_RTX_COSTS xtensa_rtx_costs
211 #undef TARGET_ADDRESS_COST
212 #define TARGET_ADDRESS_COST hook_int_rtx_mode_as_bool_0
213
214 #undef TARGET_MEMBER_TYPE_FORCES_BLK
215 #define TARGET_MEMBER_TYPE_FORCES_BLK xtensa_member_type_forces_blk
216
217 #undef TARGET_BUILD_BUILTIN_VA_LIST
218 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
219
220 #undef TARGET_EXPAND_BUILTIN_VA_START
221 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
222
223 #undef TARGET_PROMOTE_FUNCTION_MODE
224 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
225 #undef TARGET_PROMOTE_PROTOTYPES
226 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
227
228 #undef TARGET_RETURN_IN_MEMORY
229 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
230 #undef TARGET_FUNCTION_VALUE
231 #define TARGET_FUNCTION_VALUE xtensa_function_value
232 #undef TARGET_LIBCALL_VALUE
233 #define TARGET_LIBCALL_VALUE xtensa_libcall_value
234 #undef TARGET_FUNCTION_VALUE_REGNO_P
235 #define TARGET_FUNCTION_VALUE_REGNO_P xtensa_function_value_regno_p
236
237 #undef TARGET_SPLIT_COMPLEX_ARG
238 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
239 #undef TARGET_MUST_PASS_IN_STACK
240 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
241 #undef TARGET_FUNCTION_ARG_ADVANCE
242 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
243 #undef TARGET_FUNCTION_ARG
244 #define TARGET_FUNCTION_ARG xtensa_function_arg
245 #undef TARGET_FUNCTION_INCOMING_ARG
246 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
247 #undef TARGET_FUNCTION_ARG_BOUNDARY
248 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
249
250 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
251 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
252 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
253 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
254
255 #undef TARGET_RETURN_IN_MSB
256 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
257
258 #undef TARGET_INIT_BUILTINS
259 #define TARGET_INIT_BUILTINS xtensa_init_builtins
260 #undef TARGET_FOLD_BUILTIN
261 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
262 #undef TARGET_EXPAND_BUILTIN
263 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
264
265 #undef TARGET_PREFERRED_RELOAD_CLASS
266 #define TARGET_PREFERRED_RELOAD_CLASS xtensa_preferred_reload_class
267 #undef TARGET_PREFERRED_OUTPUT_RELOAD_CLASS
268 #define TARGET_PREFERRED_OUTPUT_RELOAD_CLASS xtensa_preferred_output_reload_class
269
270 #undef TARGET_SECONDARY_RELOAD
271 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
272
273 #undef TARGET_HAVE_TLS
274 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
275
276 #undef TARGET_CANNOT_FORCE_CONST_MEM
277 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_cannot_force_const_mem
278
279 #undef TARGET_LRA_P
280 #define TARGET_LRA_P hook_bool_void_false
281
282 #undef TARGET_LEGITIMATE_ADDRESS_P
283 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
284
285 #undef TARGET_FRAME_POINTER_REQUIRED
286 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
287
288 #undef TARGET_STATIC_CHAIN
289 #define TARGET_STATIC_CHAIN xtensa_static_chain
290 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
291 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
292 #undef TARGET_TRAMPOLINE_INIT
293 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
294
295 #undef TARGET_OPTION_OVERRIDE
296 #define TARGET_OPTION_OVERRIDE xtensa_option_override
297
298 #undef TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA
299 #define TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA xtensa_output_addr_const_extra
300
301 #undef TARGET_LEGITIMATE_CONSTANT_P
302 #define TARGET_LEGITIMATE_CONSTANT_P xtensa_legitimate_constant_p
303
304 #undef TARGET_MACHINE_DEPENDENT_REORG
305 #define TARGET_MACHINE_DEPENDENT_REORG xtensa_reorg
306
307 #undef TARGET_CAN_USE_DOLOOP_P
308 #define TARGET_CAN_USE_DOLOOP_P xtensa_can_use_doloop_p
309
310 #undef TARGET_INVALID_WITHIN_DOLOOP
311 #define TARGET_INVALID_WITHIN_DOLOOP xtensa_invalid_within_doloop
312
313 #undef TARGET_CONDITIONAL_REGISTER_USAGE
314 #define TARGET_CONDITIONAL_REGISTER_USAGE xtensa_conditional_register_usage
315
316 #undef TARGET_HARD_REGNO_NREGS
317 #define TARGET_HARD_REGNO_NREGS xtensa_hard_regno_nregs
318 #undef TARGET_HARD_REGNO_MODE_OK
319 #define TARGET_HARD_REGNO_MODE_OK xtensa_hard_regno_mode_ok
320
321 #undef TARGET_MODES_TIEABLE_P
322 #define TARGET_MODES_TIEABLE_P xtensa_modes_tieable_p
323
324 #undef TARGET_CONSTANT_ALIGNMENT
325 #define TARGET_CONSTANT_ALIGNMENT xtensa_constant_alignment
326
327 #undef TARGET_STARTING_FRAME_OFFSET
328 #define TARGET_STARTING_FRAME_OFFSET xtensa_starting_frame_offset
329
330 #undef TARGET_ASAN_SHADOW_OFFSET
331 #define TARGET_ASAN_SHADOW_OFFSET xtensa_asan_shadow_offset
332
333 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
334 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
335
336 struct gcc_target targetm = TARGET_INITIALIZER;
337
338
339 /* Functions to test Xtensa immediate operand validity. */
340
341 bool
xtensa_simm8(HOST_WIDE_INT v)342 xtensa_simm8 (HOST_WIDE_INT v)
343 {
344 return v >= -128 && v <= 127;
345 }
346
347
348 bool
xtensa_simm8x256(HOST_WIDE_INT v)349 xtensa_simm8x256 (HOST_WIDE_INT v)
350 {
351 return (v & 255) == 0 && (v >= -32768 && v <= 32512);
352 }
353
354
355 bool
xtensa_simm12b(HOST_WIDE_INT v)356 xtensa_simm12b (HOST_WIDE_INT v)
357 {
358 return v >= -2048 && v <= 2047;
359 }
360
361
362 static bool
xtensa_uimm8(HOST_WIDE_INT v)363 xtensa_uimm8 (HOST_WIDE_INT v)
364 {
365 return v >= 0 && v <= 255;
366 }
367
368
369 static bool
xtensa_uimm8x2(HOST_WIDE_INT v)370 xtensa_uimm8x2 (HOST_WIDE_INT v)
371 {
372 return (v & 1) == 0 && (v >= 0 && v <= 510);
373 }
374
375
376 static bool
xtensa_uimm8x4(HOST_WIDE_INT v)377 xtensa_uimm8x4 (HOST_WIDE_INT v)
378 {
379 return (v & 3) == 0 && (v >= 0 && v <= 1020);
380 }
381
382
383 static bool
xtensa_b4const(HOST_WIDE_INT v)384 xtensa_b4const (HOST_WIDE_INT v)
385 {
386 switch (v)
387 {
388 case -1:
389 case 1:
390 case 2:
391 case 3:
392 case 4:
393 case 5:
394 case 6:
395 case 7:
396 case 8:
397 case 10:
398 case 12:
399 case 16:
400 case 32:
401 case 64:
402 case 128:
403 case 256:
404 return true;
405 }
406 return false;
407 }
408
409
410 bool
xtensa_b4const_or_zero(HOST_WIDE_INT v)411 xtensa_b4const_or_zero (HOST_WIDE_INT v)
412 {
413 if (v == 0)
414 return true;
415 return xtensa_b4const (v);
416 }
417
418
419 bool
xtensa_b4constu(HOST_WIDE_INT v)420 xtensa_b4constu (HOST_WIDE_INT v)
421 {
422 switch (v)
423 {
424 case 32768:
425 case 65536:
426 case 2:
427 case 3:
428 case 4:
429 case 5:
430 case 6:
431 case 7:
432 case 8:
433 case 10:
434 case 12:
435 case 16:
436 case 32:
437 case 64:
438 case 128:
439 case 256:
440 return true;
441 }
442 return false;
443 }
444
445
446 bool
xtensa_mask_immediate(HOST_WIDE_INT v)447 xtensa_mask_immediate (HOST_WIDE_INT v)
448 {
449 #define MAX_MASK_SIZE 16
450 int mask_size;
451
452 for (mask_size = 1; mask_size <= MAX_MASK_SIZE; mask_size++)
453 {
454 if ((v & 1) == 0)
455 return false;
456 v = v >> 1;
457 if (v == 0)
458 return true;
459 }
460
461 return false;
462 }
463
464
465 /* This is just like the standard true_regnum() function except that it
466 works even when reg_renumber is not initialized. */
467
468 int
xt_true_regnum(rtx x)469 xt_true_regnum (rtx x)
470 {
471 if (GET_CODE (x) == REG)
472 {
473 if (reg_renumber
474 && REGNO (x) >= FIRST_PSEUDO_REGISTER
475 && reg_renumber[REGNO (x)] >= 0)
476 return reg_renumber[REGNO (x)];
477 return REGNO (x);
478 }
479 if (GET_CODE (x) == SUBREG)
480 {
481 int base = xt_true_regnum (SUBREG_REG (x));
482 if (base >= 0 && base < FIRST_PSEUDO_REGISTER)
483 return base + subreg_regno_offset (REGNO (SUBREG_REG (x)),
484 GET_MODE (SUBREG_REG (x)),
485 SUBREG_BYTE (x), GET_MODE (x));
486 }
487 return -1;
488 }
489
490
491 int
xtensa_valid_move(machine_mode mode,rtx * operands)492 xtensa_valid_move (machine_mode mode, rtx *operands)
493 {
494 /* Either the destination or source must be a register, and the
495 MAC16 accumulator doesn't count. */
496
497 if (register_operand (operands[0], mode))
498 {
499 int dst_regnum = xt_true_regnum (operands[0]);
500
501 if (xtensa_tls_referenced_p (operands[1]))
502 return FALSE;
503
504 /* The stack pointer can only be assigned with a MOVSP opcode. */
505 if (dst_regnum == STACK_POINTER_REGNUM)
506 return !TARGET_WINDOWED_ABI
507 || (mode == SImode
508 && register_operand (operands[1], mode)
509 && !ACC_REG_P (xt_true_regnum (operands[1])));
510
511 if (!ACC_REG_P (dst_regnum))
512 return true;
513 }
514 if (register_operand (operands[1], mode))
515 {
516 int src_regnum = xt_true_regnum (operands[1]);
517 if (!ACC_REG_P (src_regnum))
518 return true;
519 }
520 return FALSE;
521 }
522
523
524 int
smalloffset_mem_p(rtx op)525 smalloffset_mem_p (rtx op)
526 {
527 if (GET_CODE (op) == MEM)
528 {
529 rtx addr = XEXP (op, 0);
530 if (GET_CODE (addr) == REG)
531 return BASE_REG_P (addr, 0);
532 if (GET_CODE (addr) == PLUS)
533 {
534 rtx offset = XEXP (addr, 0);
535 HOST_WIDE_INT val;
536 if (GET_CODE (offset) != CONST_INT)
537 offset = XEXP (addr, 1);
538 if (GET_CODE (offset) != CONST_INT)
539 return FALSE;
540
541 val = INTVAL (offset);
542 return (val & 3) == 0 && (val >= 0 && val <= 60);
543 }
544 }
545 return FALSE;
546 }
547
548
549 static bool
constantpool_address_p(const_rtx addr)550 constantpool_address_p (const_rtx addr)
551 {
552 const_rtx sym = addr;
553
554 if (GET_CODE (addr) == CONST)
555 {
556 rtx offset;
557
558 /* Only handle (PLUS (SYM, OFFSET)) form. */
559 addr = XEXP (addr, 0);
560 if (GET_CODE (addr) != PLUS)
561 return false;
562
563 /* Make sure the address is word aligned. */
564 offset = XEXP (addr, 1);
565 if ((!CONST_INT_P (offset))
566 || ((INTVAL (offset) & 3) != 0))
567 return false;
568
569 sym = XEXP (addr, 0);
570 }
571
572 if ((GET_CODE (sym) == SYMBOL_REF)
573 && CONSTANT_POOL_ADDRESS_P (sym))
574 return true;
575 return false;
576 }
577
578
579 int
constantpool_mem_p(rtx op)580 constantpool_mem_p (rtx op)
581 {
582 if (GET_CODE (op) == SUBREG)
583 op = SUBREG_REG (op);
584 if (GET_CODE (op) == MEM)
585 return constantpool_address_p (XEXP (op, 0));
586 return FALSE;
587 }
588
589
590 /* Return TRUE if X is a thread-local symbol. */
591
592 static bool
xtensa_tls_symbol_p(rtx x)593 xtensa_tls_symbol_p (rtx x)
594 {
595 if (! TARGET_HAVE_TLS)
596 return false;
597
598 return GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0;
599 }
600
601
602 void
xtensa_extend_reg(rtx dst,rtx src)603 xtensa_extend_reg (rtx dst, rtx src)
604 {
605 rtx temp = gen_reg_rtx (SImode);
606 rtx shift = GEN_INT (BITS_PER_WORD - GET_MODE_BITSIZE (GET_MODE (src)));
607
608 /* Generate paradoxical subregs as needed so that the modes match. */
609 src = simplify_gen_subreg (SImode, src, GET_MODE (src), 0);
610 dst = simplify_gen_subreg (SImode, dst, GET_MODE (dst), 0);
611
612 emit_insn (gen_ashlsi3 (temp, src, shift));
613 emit_insn (gen_ashrsi3 (dst, temp, shift));
614 }
615
616
617 bool
xtensa_mem_offset(unsigned v,machine_mode mode)618 xtensa_mem_offset (unsigned v, machine_mode mode)
619 {
620 switch (mode)
621 {
622 case E_BLKmode:
623 /* Handle the worst case for block moves. See xtensa_expand_block_move
624 where we emit an optimized block move operation if the block can be
625 moved in < "move_ratio" pieces. The worst case is when the block is
626 aligned but has a size of (3 mod 4) (does this happen?) so that the
627 last piece requires a byte load/store. */
628 return (xtensa_uimm8 (v)
629 && xtensa_uimm8 (v + MOVE_MAX * LARGEST_MOVE_RATIO));
630
631 case E_QImode:
632 return xtensa_uimm8 (v);
633
634 case E_HImode:
635 return xtensa_uimm8x2 (v);
636
637 case E_DImode:
638 case E_DFmode:
639 return (xtensa_uimm8x4 (v) && xtensa_uimm8x4 (v + 4));
640
641 default:
642 break;
643 }
644
645 return xtensa_uimm8x4 (v);
646 }
647
648
649 /* Make normal rtx_code into something we can index from an array. */
650
651 static enum internal_test
map_test_to_internal_test(enum rtx_code test_code)652 map_test_to_internal_test (enum rtx_code test_code)
653 {
654 enum internal_test test = ITEST_MAX;
655
656 switch (test_code)
657 {
658 default: break;
659 case EQ: test = ITEST_EQ; break;
660 case NE: test = ITEST_NE; break;
661 case GT: test = ITEST_GT; break;
662 case GE: test = ITEST_GE; break;
663 case LT: test = ITEST_LT; break;
664 case LE: test = ITEST_LE; break;
665 case GTU: test = ITEST_GTU; break;
666 case GEU: test = ITEST_GEU; break;
667 case LTU: test = ITEST_LTU; break;
668 case LEU: test = ITEST_LEU; break;
669 }
670
671 return test;
672 }
673
674
675 /* Generate the code to compare two integer values. The return value is
676 the comparison expression. */
677
678 static rtx
gen_int_relational(enum rtx_code test_code,rtx cmp0,rtx cmp1,int * p_invert)679 gen_int_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
680 rtx cmp0, /* first operand to compare */
681 rtx cmp1, /* second operand to compare */
682 int *p_invert /* whether branch needs to reverse test */)
683 {
684 struct cmp_info
685 {
686 enum rtx_code test_code; /* test code to use in insn */
687 bool (*const_range_p) (HOST_WIDE_INT); /* range check function */
688 int const_add; /* constant to add (convert LE -> LT) */
689 int reverse_regs; /* reverse registers in test */
690 int invert_const; /* != 0 if invert value if cmp1 is constant */
691 int invert_reg; /* != 0 if invert value if cmp1 is register */
692 int unsignedp; /* != 0 for unsigned comparisons. */
693 };
694
695 static struct cmp_info info[ (int)ITEST_MAX ] = {
696
697 { EQ, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* EQ */
698 { NE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* NE */
699
700 { LT, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* GT */
701 { GE, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* GE */
702 { LT, xtensa_b4const_or_zero, 0, 0, 0, 0, 0 }, /* LT */
703 { GE, xtensa_b4const_or_zero, 1, 1, 1, 0, 0 }, /* LE */
704
705 { LTU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* GTU */
706 { GEU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* GEU */
707 { LTU, xtensa_b4constu, 0, 0, 0, 0, 1 }, /* LTU */
708 { GEU, xtensa_b4constu, 1, 1, 1, 0, 1 }, /* LEU */
709 };
710
711 enum internal_test test;
712 machine_mode mode;
713 struct cmp_info *p_info;
714
715 test = map_test_to_internal_test (test_code);
716 gcc_assert (test != ITEST_MAX);
717
718 p_info = &info[ (int)test ];
719
720 mode = GET_MODE (cmp0);
721 if (mode == VOIDmode)
722 mode = GET_MODE (cmp1);
723
724 /* Make sure we can handle any constants given to us. */
725 if (GET_CODE (cmp1) == CONST_INT)
726 {
727 HOST_WIDE_INT value = INTVAL (cmp1);
728 unsigned HOST_WIDE_INT uvalue = (unsigned HOST_WIDE_INT)value;
729
730 /* if the immediate overflows or does not fit in the immediate field,
731 spill it to a register */
732
733 if ((p_info->unsignedp ?
734 (uvalue + p_info->const_add > uvalue) :
735 (value + p_info->const_add > value)) != (p_info->const_add > 0))
736 {
737 cmp1 = force_reg (mode, cmp1);
738 }
739 else if (!(p_info->const_range_p) (value + p_info->const_add))
740 {
741 cmp1 = force_reg (mode, cmp1);
742 }
743 }
744 else if ((GET_CODE (cmp1) != REG) && (GET_CODE (cmp1) != SUBREG))
745 {
746 cmp1 = force_reg (mode, cmp1);
747 }
748
749 /* See if we need to invert the result. */
750 *p_invert = ((GET_CODE (cmp1) == CONST_INT)
751 ? p_info->invert_const
752 : p_info->invert_reg);
753
754 /* Comparison to constants, may involve adding 1 to change a LT into LE.
755 Comparison between two registers, may involve switching operands. */
756 if (GET_CODE (cmp1) == CONST_INT)
757 {
758 if (p_info->const_add != 0)
759 cmp1 = GEN_INT (INTVAL (cmp1) + p_info->const_add);
760
761 }
762 else if (p_info->reverse_regs)
763 {
764 rtx temp = cmp0;
765 cmp0 = cmp1;
766 cmp1 = temp;
767 }
768
769 return gen_rtx_fmt_ee (p_info->test_code, VOIDmode, cmp0, cmp1);
770 }
771
772
773 /* Generate the code to compare two float values. The return value is
774 the comparison expression. */
775
776 static rtx
gen_float_relational(enum rtx_code test_code,rtx cmp0,rtx cmp1)777 gen_float_relational (enum rtx_code test_code, /* relational test (EQ, etc) */
778 rtx cmp0, /* first operand to compare */
779 rtx cmp1 /* second operand to compare */)
780 {
781 rtx (*gen_fn) (rtx, rtx, rtx);
782 rtx brtmp;
783 int reverse_regs, invert;
784
785 switch (test_code)
786 {
787 case EQ: reverse_regs = 0; invert = 0; gen_fn = gen_seq_sf; break;
788 case NE: reverse_regs = 0; invert = 1; gen_fn = gen_seq_sf; break;
789 case LE: reverse_regs = 0; invert = 0; gen_fn = gen_sle_sf; break;
790 case GT: reverse_regs = 1; invert = 0; gen_fn = gen_slt_sf; break;
791 case LT: reverse_regs = 0; invert = 0; gen_fn = gen_slt_sf; break;
792 case GE: reverse_regs = 1; invert = 0; gen_fn = gen_sle_sf; break;
793 case UNEQ: reverse_regs = 0; invert = 0; gen_fn = gen_suneq_sf; break;
794 case LTGT: reverse_regs = 0; invert = 1; gen_fn = gen_suneq_sf; break;
795 case UNLE: reverse_regs = 0; invert = 0; gen_fn = gen_sunle_sf; break;
796 case UNGT: reverse_regs = 1; invert = 0; gen_fn = gen_sunlt_sf; break;
797 case UNLT: reverse_regs = 0; invert = 0; gen_fn = gen_sunlt_sf; break;
798 case UNGE: reverse_regs = 1; invert = 0; gen_fn = gen_sunle_sf; break;
799 case UNORDERED:
800 reverse_regs = 0; invert = 0; gen_fn = gen_sunordered_sf; break;
801 case ORDERED:
802 reverse_regs = 0; invert = 1; gen_fn = gen_sunordered_sf; break;
803 default:
804 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
805 reverse_regs = 0; invert = 0; gen_fn = 0; /* avoid compiler warnings */
806 }
807
808 if (reverse_regs)
809 {
810 rtx temp = cmp0;
811 cmp0 = cmp1;
812 cmp1 = temp;
813 }
814
815 brtmp = gen_rtx_REG (CCmode, FPCC_REGNUM);
816 emit_insn (gen_fn (brtmp, cmp0, cmp1));
817
818 return gen_rtx_fmt_ee (invert ? EQ : NE, VOIDmode, brtmp, const0_rtx);
819 }
820
821
822 void
xtensa_expand_conditional_branch(rtx * operands,machine_mode mode)823 xtensa_expand_conditional_branch (rtx *operands, machine_mode mode)
824 {
825 enum rtx_code test_code = GET_CODE (operands[0]);
826 rtx cmp0 = operands[1];
827 rtx cmp1 = operands[2];
828 rtx cmp;
829 int invert;
830 rtx label1, label2;
831
832 switch (mode)
833 {
834 case E_DFmode:
835 default:
836 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode, cmp0, cmp1));
837
838 case E_SImode:
839 invert = FALSE;
840 cmp = gen_int_relational (test_code, cmp0, cmp1, &invert);
841 break;
842
843 case E_SFmode:
844 if (!TARGET_HARD_FLOAT)
845 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code, VOIDmode,
846 cmp0, cmp1));
847 invert = FALSE;
848 cmp = gen_float_relational (test_code, cmp0, cmp1);
849 break;
850 }
851
852 /* Generate the branch. */
853
854 label1 = gen_rtx_LABEL_REF (VOIDmode, operands[3]);
855 label2 = pc_rtx;
856
857 if (invert)
858 {
859 label2 = label1;
860 label1 = pc_rtx;
861 }
862
863 emit_jump_insn (gen_rtx_SET (pc_rtx,
864 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
865 label1,
866 label2)));
867 }
868
869
870 static rtx
gen_conditional_move(enum rtx_code code,machine_mode mode,rtx op0,rtx op1)871 gen_conditional_move (enum rtx_code code, machine_mode mode,
872 rtx op0, rtx op1)
873 {
874 if (mode == SImode)
875 {
876 rtx cmp;
877
878 /* Jump optimization calls get_condition() which canonicalizes
879 comparisons like (GE x <const>) to (GT x <const-1>).
880 Transform those comparisons back to GE, since that is the
881 comparison supported in Xtensa. We shouldn't have to
882 transform <LE x const> comparisons, because neither
883 xtensa_expand_conditional_branch() nor get_condition() will
884 produce them. */
885
886 if ((code == GT) && (op1 == constm1_rtx))
887 {
888 code = GE;
889 op1 = const0_rtx;
890 }
891 cmp = gen_rtx_fmt_ee (code, VOIDmode, cc0_rtx, const0_rtx);
892
893 if (boolean_operator (cmp, VOIDmode))
894 {
895 /* Swap the operands to make const0 second. */
896 if (op0 == const0_rtx)
897 {
898 op0 = op1;
899 op1 = const0_rtx;
900 }
901
902 /* If not comparing against zero, emit a comparison (subtract). */
903 if (op1 != const0_rtx)
904 {
905 op0 = expand_binop (SImode, sub_optab, op0, op1,
906 0, 0, OPTAB_LIB_WIDEN);
907 op1 = const0_rtx;
908 }
909 }
910 else if (branch_operator (cmp, VOIDmode))
911 {
912 /* Swap the operands to make const0 second. */
913 if (op0 == const0_rtx)
914 {
915 op0 = op1;
916 op1 = const0_rtx;
917
918 switch (code)
919 {
920 case LT: code = GE; break;
921 case GE: code = LT; break;
922 default: gcc_unreachable ();
923 }
924 }
925
926 if (op1 != const0_rtx)
927 return 0;
928 }
929 else
930 return 0;
931
932 return gen_rtx_fmt_ee (code, VOIDmode, op0, op1);
933 }
934
935 if (TARGET_HARD_FLOAT && mode == SFmode)
936 return gen_float_relational (code, op0, op1);
937
938 return 0;
939 }
940
941
942 int
xtensa_expand_conditional_move(rtx * operands,int isflt)943 xtensa_expand_conditional_move (rtx *operands, int isflt)
944 {
945 rtx dest = operands[0];
946 rtx cmp = operands[1];
947 machine_mode cmp_mode = GET_MODE (XEXP (cmp, 0));
948 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
949
950 if (!(cmp = gen_conditional_move (GET_CODE (cmp), cmp_mode,
951 XEXP (cmp, 0), XEXP (cmp, 1))))
952 return 0;
953
954 if (isflt)
955 gen_fn = (cmp_mode == SImode
956 ? gen_movsfcc_internal0
957 : gen_movsfcc_internal1);
958 else
959 gen_fn = (cmp_mode == SImode
960 ? gen_movsicc_internal0
961 : gen_movsicc_internal1);
962
963 emit_insn (gen_fn (dest, XEXP (cmp, 0), operands[2], operands[3], cmp));
964 return 1;
965 }
966
967
968 int
xtensa_expand_scc(rtx operands[4],machine_mode cmp_mode)969 xtensa_expand_scc (rtx operands[4], machine_mode cmp_mode)
970 {
971 rtx dest = operands[0];
972 rtx cmp;
973 rtx one_tmp, zero_tmp;
974 rtx (*gen_fn) (rtx, rtx, rtx, rtx, rtx);
975
976 if (!(cmp = gen_conditional_move (GET_CODE (operands[1]), cmp_mode,
977 operands[2], operands[3])))
978 return 0;
979
980 one_tmp = gen_reg_rtx (SImode);
981 zero_tmp = gen_reg_rtx (SImode);
982 emit_insn (gen_movsi (one_tmp, const_true_rtx));
983 emit_insn (gen_movsi (zero_tmp, const0_rtx));
984
985 gen_fn = (cmp_mode == SImode
986 ? gen_movsicc_internal0
987 : gen_movsicc_internal1);
988 emit_insn (gen_fn (dest, XEXP (cmp, 0), one_tmp, zero_tmp, cmp));
989 return 1;
990 }
991
992
993 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
994 for the output, i.e., the input operands are twice as big as MODE. */
995
996 void
xtensa_split_operand_pair(rtx operands[4],machine_mode mode)997 xtensa_split_operand_pair (rtx operands[4], machine_mode mode)
998 {
999 switch (GET_CODE (operands[1]))
1000 {
1001 case REG:
1002 operands[3] = gen_rtx_REG (mode, REGNO (operands[1]) + 1);
1003 operands[2] = gen_rtx_REG (mode, REGNO (operands[1]));
1004 break;
1005
1006 case MEM:
1007 operands[3] = adjust_address (operands[1], mode, GET_MODE_SIZE (mode));
1008 operands[2] = adjust_address (operands[1], mode, 0);
1009 break;
1010
1011 case CONST_INT:
1012 case CONST_DOUBLE:
1013 split_double (operands[1], &operands[2], &operands[3]);
1014 break;
1015
1016 default:
1017 gcc_unreachable ();
1018 }
1019
1020 switch (GET_CODE (operands[0]))
1021 {
1022 case REG:
1023 operands[1] = gen_rtx_REG (mode, REGNO (operands[0]) + 1);
1024 operands[0] = gen_rtx_REG (mode, REGNO (operands[0]));
1025 break;
1026
1027 case MEM:
1028 operands[1] = adjust_address (operands[0], mode, GET_MODE_SIZE (mode));
1029 operands[0] = adjust_address (operands[0], mode, 0);
1030 break;
1031
1032 default:
1033 gcc_unreachable ();
1034 }
1035 }
1036
1037
1038 /* Emit insns to move operands[1] into operands[0].
1039 Return 1 if we have written out everything that needs to be done to
1040 do the move. Otherwise, return 0 and the caller will emit the move
1041 normally. */
1042
1043 int
xtensa_emit_move_sequence(rtx * operands,machine_mode mode)1044 xtensa_emit_move_sequence (rtx *operands, machine_mode mode)
1045 {
1046 rtx src = operands[1];
1047
1048 if (CONSTANT_P (src)
1049 && (GET_CODE (src) != CONST_INT || ! xtensa_simm12b (INTVAL (src))))
1050 {
1051 rtx dst = operands[0];
1052
1053 if (xtensa_tls_referenced_p (src))
1054 {
1055 rtx addend = NULL;
1056
1057 if (GET_CODE (src) == CONST && GET_CODE (XEXP (src, 0)) == PLUS)
1058 {
1059 addend = XEXP (XEXP (src, 0), 1);
1060 src = XEXP (XEXP (src, 0), 0);
1061 }
1062
1063 src = xtensa_legitimize_tls_address (src);
1064 if (addend)
1065 {
1066 src = gen_rtx_PLUS (mode, src, addend);
1067 src = force_operand (src, dst);
1068 }
1069 emit_move_insn (dst, src);
1070 return 1;
1071 }
1072
1073 if (! TARGET_AUTO_LITPOOLS && ! TARGET_CONST16)
1074 {
1075 src = force_const_mem (SImode, src);
1076 operands[1] = src;
1077 }
1078
1079 /* PC-relative loads are always SImode, and CONST16 is only
1080 supported in the movsi pattern, so add a SUBREG for any other
1081 (smaller) mode. */
1082
1083 if (mode != SImode)
1084 {
1085 if (register_operand (dst, mode))
1086 {
1087 emit_move_insn (simplify_gen_subreg (SImode, dst, mode, 0), src);
1088 return 1;
1089 }
1090 else
1091 {
1092 src = force_reg (SImode, src);
1093 src = gen_lowpart_SUBREG (mode, src);
1094 operands[1] = src;
1095 }
1096 }
1097 }
1098
1099 if (!(reload_in_progress | reload_completed)
1100 && !xtensa_valid_move (mode, operands))
1101 operands[1] = force_reg (mode, operands[1]);
1102
1103 operands[1] = xtensa_copy_incoming_a7 (operands[1]);
1104
1105 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1106 instruction won't be recognized after reload, so we remove the
1107 subreg and adjust mem accordingly. */
1108 if (reload_in_progress)
1109 {
1110 operands[0] = fixup_subreg_mem (operands[0]);
1111 operands[1] = fixup_subreg_mem (operands[1]);
1112 }
1113 return 0;
1114 }
1115
1116
1117 static rtx
fixup_subreg_mem(rtx x)1118 fixup_subreg_mem (rtx x)
1119 {
1120 if (GET_CODE (x) == SUBREG
1121 && GET_CODE (SUBREG_REG (x)) == REG
1122 && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
1123 {
1124 rtx temp =
1125 gen_rtx_SUBREG (GET_MODE (x),
1126 reg_equiv_mem (REGNO (SUBREG_REG (x))),
1127 SUBREG_BYTE (x));
1128 x = alter_subreg (&temp, true);
1129 }
1130 return x;
1131 }
1132
1133
1134 /* Check if an incoming argument in a7 is expected to be used soon and
1135 if OPND is a register or register pair that includes a7. If so,
1136 create a new pseudo and copy a7 into that pseudo at the very
1137 beginning of the function, followed by the special "set_frame_ptr"
1138 unspec_volatile insn. The return value is either the original
1139 operand, if it is not a7, or the new pseudo containing a copy of
1140 the incoming argument. This is necessary because the register
1141 allocator will ignore conflicts with a7 and may either assign some
1142 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1143 the incoming argument in a7. By copying the argument out of a7 as
1144 the very first thing, and then immediately following that with an
1145 unspec_volatile to keep the scheduler away, we should avoid any
1146 problems. Putting the set_frame_ptr insn at the beginning, with
1147 only the a7 copy before it, also makes it easier for the prologue
1148 expander to initialize the frame pointer after the a7 copy and to
1149 fix up the a7 copy to use the stack pointer instead of the frame
1150 pointer. */
1151
1152 rtx
xtensa_copy_incoming_a7(rtx opnd)1153 xtensa_copy_incoming_a7 (rtx opnd)
1154 {
1155 rtx entry_insns = 0;
1156 rtx reg, tmp;
1157 machine_mode mode;
1158
1159 if (!cfun->machine->need_a7_copy)
1160 return opnd;
1161
1162 /* This function should never be called again once a7 has been copied. */
1163 gcc_assert (!cfun->machine->set_frame_ptr_insn);
1164
1165 mode = GET_MODE (opnd);
1166
1167 /* The operand using a7 may come in a later instruction, so just return
1168 the original operand if it doesn't use a7. */
1169 reg = opnd;
1170 if (GET_CODE (reg) == SUBREG)
1171 {
1172 gcc_assert (SUBREG_BYTE (reg) == 0);
1173 reg = SUBREG_REG (reg);
1174 }
1175 if (GET_CODE (reg) != REG
1176 || REGNO (reg) > A7_REG
1177 || REGNO (reg) + hard_regno_nregs (A7_REG, mode) <= A7_REG)
1178 return opnd;
1179
1180 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1181 gcc_assert (REGNO (reg) + hard_regno_nregs (A7_REG, mode) - 1 == A7_REG);
1182
1183 cfun->machine->need_a7_copy = false;
1184
1185 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1186 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1187
1188 start_sequence ();
1189 tmp = gen_reg_rtx (mode);
1190
1191 switch (mode)
1192 {
1193 case E_DFmode:
1194 case E_DImode:
1195 /* Copy the value out of A7 here but keep the first word in A6 until
1196 after the set_frame_ptr insn. Otherwise, the register allocator
1197 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1198 value. */
1199 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 4),
1200 gen_raw_REG (SImode, A7_REG)));
1201 break;
1202 case E_SFmode:
1203 emit_insn (gen_movsf_internal (tmp, gen_raw_REG (mode, A7_REG)));
1204 break;
1205 case E_SImode:
1206 emit_insn (gen_movsi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1207 break;
1208 case E_HImode:
1209 emit_insn (gen_movhi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1210 break;
1211 case E_QImode:
1212 emit_insn (gen_movqi_internal (tmp, gen_raw_REG (mode, A7_REG)));
1213 break;
1214 default:
1215 gcc_unreachable ();
1216 }
1217
1218 cfun->machine->set_frame_ptr_insn = emit_insn (gen_set_frame_ptr ());
1219
1220 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1221 if (mode == DFmode || mode == DImode)
1222 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode, tmp, 0),
1223 gen_rtx_REG (SImode, A7_REG - 1)));
1224 entry_insns = get_insns ();
1225 end_sequence ();
1226
1227 if (cfun->machine->vararg_a7)
1228 {
1229 /* This is called from within builtin_saveregs, which will insert the
1230 saveregs code at the function entry, ahead of anything placed at
1231 the function entry now. Instead, save the sequence to be inserted
1232 at the beginning of the saveregs code. */
1233 cfun->machine->vararg_a7_copy = entry_insns;
1234 }
1235 else
1236 {
1237 /* Put entry_insns after the NOTE that starts the function. If
1238 this is inside a start_sequence, make the outer-level insn
1239 chain current, so the code is placed at the start of the
1240 function. */
1241 push_topmost_sequence ();
1242 /* Do not use entry_of_function() here. This is called from within
1243 expand_function_start, when the CFG still holds GIMPLE. */
1244 emit_insn_after (entry_insns, get_insns ());
1245 pop_topmost_sequence ();
1246 }
1247
1248 return tmp;
1249 }
1250
1251
1252 /* Try to expand a block move operation to a sequence of RTL move
1253 instructions. If not optimizing, or if the block size is not a
1254 constant, or if the block is too large, the expansion fails and GCC
1255 falls back to calling memcpy().
1256
1257 operands[0] is the destination
1258 operands[1] is the source
1259 operands[2] is the length
1260 operands[3] is the alignment */
1261
1262 int
xtensa_expand_block_move(rtx * operands)1263 xtensa_expand_block_move (rtx *operands)
1264 {
1265 static const machine_mode mode_from_align[] =
1266 {
1267 VOIDmode, QImode, HImode, VOIDmode, SImode,
1268 };
1269
1270 rtx dst_mem = operands[0];
1271 rtx src_mem = operands[1];
1272 HOST_WIDE_INT bytes, align;
1273 int num_pieces, move_ratio;
1274 rtx temp[2];
1275 machine_mode mode[2];
1276 int amount[2];
1277 bool active[2];
1278 int phase = 0;
1279 int next;
1280 int offset_ld = 0;
1281 int offset_st = 0;
1282 rtx x;
1283
1284 /* If this is not a fixed size move, just call memcpy. */
1285 if (!optimize || (GET_CODE (operands[2]) != CONST_INT))
1286 return 0;
1287
1288 bytes = INTVAL (operands[2]);
1289 align = INTVAL (operands[3]);
1290
1291 /* Anything to move? */
1292 if (bytes <= 0)
1293 return 0;
1294
1295 if (align > MOVE_MAX)
1296 align = MOVE_MAX;
1297
1298 /* Decide whether to expand inline based on the optimization level. */
1299 move_ratio = 4;
1300 if (optimize > 2)
1301 move_ratio = LARGEST_MOVE_RATIO;
1302 num_pieces = (bytes / align) + (bytes % align); /* Close enough anyway. */
1303 if (num_pieces > move_ratio)
1304 return 0;
1305
1306 x = XEXP (dst_mem, 0);
1307 if (!REG_P (x))
1308 {
1309 x = force_reg (Pmode, x);
1310 dst_mem = replace_equiv_address (dst_mem, x);
1311 }
1312
1313 x = XEXP (src_mem, 0);
1314 if (!REG_P (x))
1315 {
1316 x = force_reg (Pmode, x);
1317 src_mem = replace_equiv_address (src_mem, x);
1318 }
1319
1320 active[0] = active[1] = false;
1321
1322 do
1323 {
1324 next = phase;
1325 phase ^= 1;
1326
1327 if (bytes > 0)
1328 {
1329 int next_amount;
1330
1331 next_amount = (bytes >= 4 ? 4 : (bytes >= 2 ? 2 : 1));
1332 next_amount = MIN (next_amount, align);
1333
1334 amount[next] = next_amount;
1335 mode[next] = mode_from_align[next_amount];
1336 temp[next] = gen_reg_rtx (mode[next]);
1337
1338 x = adjust_address (src_mem, mode[next], offset_ld);
1339 emit_insn (gen_rtx_SET (temp[next], x));
1340
1341 offset_ld += next_amount;
1342 bytes -= next_amount;
1343 active[next] = true;
1344 }
1345
1346 if (active[phase])
1347 {
1348 active[phase] = false;
1349
1350 x = adjust_address (dst_mem, mode[phase], offset_st);
1351 emit_insn (gen_rtx_SET (x, temp[phase]));
1352
1353 offset_st += amount[phase];
1354 }
1355 }
1356 while (active[next]);
1357
1358 return 1;
1359 }
1360
1361
1362 void
xtensa_expand_nonlocal_goto(rtx * operands)1363 xtensa_expand_nonlocal_goto (rtx *operands)
1364 {
1365 rtx goto_handler = operands[1];
1366 rtx containing_fp = operands[3];
1367
1368 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1369 is too big to generate in-line. */
1370
1371 if (GET_CODE (containing_fp) != REG)
1372 containing_fp = force_reg (Pmode, containing_fp);
1373
1374 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_nonlocal_goto"),
1375 LCT_NORMAL, VOIDmode,
1376 containing_fp, Pmode,
1377 goto_handler, Pmode);
1378 }
1379
1380
1381 static struct machine_function *
xtensa_init_machine_status(void)1382 xtensa_init_machine_status (void)
1383 {
1384 return ggc_cleared_alloc<machine_function> ();
1385 }
1386
1387
1388 /* Shift VAL of mode MODE left by COUNT bits. */
1389
1390 static inline rtx
xtensa_expand_mask_and_shift(rtx val,machine_mode mode,rtx count)1391 xtensa_expand_mask_and_shift (rtx val, machine_mode mode, rtx count)
1392 {
1393 val = expand_simple_binop (SImode, AND, val, GEN_INT (GET_MODE_MASK (mode)),
1394 NULL_RTX, 1, OPTAB_DIRECT);
1395 return expand_simple_binop (SImode, ASHIFT, val, count,
1396 NULL_RTX, 1, OPTAB_DIRECT);
1397 }
1398
1399
1400 /* Structure to hold the initial parameters for a compare_and_swap operation
1401 in HImode and QImode. */
1402
1403 struct alignment_context
1404 {
1405 rtx memsi; /* SI aligned memory location. */
1406 rtx shift; /* Bit offset with regard to lsb. */
1407 rtx modemask; /* Mask of the HQImode shifted by SHIFT bits. */
1408 rtx modemaski; /* ~modemask */
1409 };
1410
1411
1412 /* Initialize structure AC for word access to HI and QI mode memory. */
1413
1414 static void
init_alignment_context(struct alignment_context * ac,rtx mem)1415 init_alignment_context (struct alignment_context *ac, rtx mem)
1416 {
1417 machine_mode mode = GET_MODE (mem);
1418 rtx byteoffset = NULL_RTX;
1419 bool aligned = (MEM_ALIGN (mem) >= GET_MODE_BITSIZE (SImode));
1420
1421 if (aligned)
1422 ac->memsi = adjust_address (mem, SImode, 0); /* Memory is aligned. */
1423 else
1424 {
1425 /* Alignment is unknown. */
1426 rtx addr, align;
1427
1428 /* Force the address into a register. */
1429 addr = force_reg (Pmode, XEXP (mem, 0));
1430
1431 /* Align it to SImode. */
1432 align = expand_simple_binop (Pmode, AND, addr,
1433 GEN_INT (-GET_MODE_SIZE (SImode)),
1434 NULL_RTX, 1, OPTAB_DIRECT);
1435 /* Generate MEM. */
1436 ac->memsi = gen_rtx_MEM (SImode, align);
1437 MEM_VOLATILE_P (ac->memsi) = MEM_VOLATILE_P (mem);
1438 set_mem_alias_set (ac->memsi, ALIAS_SET_MEMORY_BARRIER);
1439 set_mem_align (ac->memsi, GET_MODE_BITSIZE (SImode));
1440
1441 byteoffset = expand_simple_binop (Pmode, AND, addr,
1442 GEN_INT (GET_MODE_SIZE (SImode) - 1),
1443 NULL_RTX, 1, OPTAB_DIRECT);
1444 }
1445
1446 /* Calculate shiftcount. */
1447 if (TARGET_BIG_ENDIAN)
1448 {
1449 ac->shift = GEN_INT (GET_MODE_SIZE (SImode) - GET_MODE_SIZE (mode));
1450 if (!aligned)
1451 ac->shift = expand_simple_binop (SImode, MINUS, ac->shift, byteoffset,
1452 NULL_RTX, 1, OPTAB_DIRECT);
1453 }
1454 else
1455 {
1456 if (aligned)
1457 ac->shift = NULL_RTX;
1458 else
1459 ac->shift = byteoffset;
1460 }
1461
1462 if (ac->shift != NULL_RTX)
1463 {
1464 /* Shift is the byte count, but we need the bitcount. */
1465 gcc_assert (exact_log2 (BITS_PER_UNIT) >= 0);
1466 ac->shift = expand_simple_binop (SImode, ASHIFT, ac->shift,
1467 GEN_INT (exact_log2 (BITS_PER_UNIT)),
1468 NULL_RTX, 1, OPTAB_DIRECT);
1469 ac->modemask = expand_simple_binop (SImode, ASHIFT,
1470 GEN_INT (GET_MODE_MASK (mode)),
1471 ac->shift,
1472 NULL_RTX, 1, OPTAB_DIRECT);
1473 }
1474 else
1475 ac->modemask = GEN_INT (GET_MODE_MASK (mode));
1476
1477 ac->modemaski = expand_simple_unop (SImode, NOT, ac->modemask, NULL_RTX, 1);
1478 }
1479
1480
1481 /* Expand an atomic compare and swap operation for HImode and QImode.
1482 MEM is the memory location, CMP the old value to compare MEM with
1483 and NEW_RTX the value to set if CMP == MEM. */
1484
1485 void
xtensa_expand_compare_and_swap(rtx target,rtx mem,rtx cmp,rtx new_rtx)1486 xtensa_expand_compare_and_swap (rtx target, rtx mem, rtx cmp, rtx new_rtx)
1487 {
1488 machine_mode mode = GET_MODE (mem);
1489 struct alignment_context ac;
1490 rtx tmp, cmpv, newv, val;
1491 rtx oldval = gen_reg_rtx (SImode);
1492 rtx res = gen_reg_rtx (SImode);
1493 rtx_code_label *csloop = gen_label_rtx ();
1494 rtx_code_label *csend = gen_label_rtx ();
1495
1496 init_alignment_context (&ac, mem);
1497
1498 if (ac.shift != NULL_RTX)
1499 {
1500 cmp = xtensa_expand_mask_and_shift (cmp, mode, ac.shift);
1501 new_rtx = xtensa_expand_mask_and_shift (new_rtx, mode, ac.shift);
1502 }
1503
1504 /* Load the surrounding word into VAL with the MEM value masked out. */
1505 val = force_reg (SImode, expand_simple_binop (SImode, AND, ac.memsi,
1506 ac.modemaski, NULL_RTX, 1,
1507 OPTAB_DIRECT));
1508 emit_label (csloop);
1509
1510 /* Patch CMP and NEW_RTX into VAL at correct position. */
1511 cmpv = force_reg (SImode, expand_simple_binop (SImode, IOR, cmp, val,
1512 NULL_RTX, 1, OPTAB_DIRECT));
1513 newv = force_reg (SImode, expand_simple_binop (SImode, IOR, new_rtx, val,
1514 NULL_RTX, 1, OPTAB_DIRECT));
1515
1516 /* Jump to end if we're done. */
1517 emit_insn (gen_sync_compare_and_swapsi (res, ac.memsi, cmpv, newv));
1518 emit_cmp_and_jump_insns (res, cmpv, EQ, const0_rtx, SImode, true, csend);
1519
1520 /* Check for changes outside mode. */
1521 emit_move_insn (oldval, val);
1522 tmp = expand_simple_binop (SImode, AND, res, ac.modemaski,
1523 val, 1, OPTAB_DIRECT);
1524 if (tmp != val)
1525 emit_move_insn (val, tmp);
1526
1527 /* Loop internal if so. */
1528 emit_cmp_and_jump_insns (oldval, val, NE, const0_rtx, SImode, true, csloop);
1529
1530 emit_label (csend);
1531
1532 /* Return the correct part of the bitfield. */
1533 convert_move (target,
1534 (ac.shift == NULL_RTX ? res
1535 : expand_simple_binop (SImode, LSHIFTRT, res, ac.shift,
1536 NULL_RTX, 1, OPTAB_DIRECT)),
1537 1);
1538 }
1539
1540
1541 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1542 the default expansion works fine for SImode). MEM is the memory location
1543 and VAL the value to play with. If AFTER is true then store the value
1544 MEM holds after the operation, if AFTER is false then store the value MEM
1545 holds before the operation. If TARGET is zero then discard that value, else
1546 store it to TARGET. */
1547
1548 void
xtensa_expand_atomic(enum rtx_code code,rtx target,rtx mem,rtx val,bool after)1549 xtensa_expand_atomic (enum rtx_code code, rtx target, rtx mem, rtx val,
1550 bool after)
1551 {
1552 machine_mode mode = GET_MODE (mem);
1553 struct alignment_context ac;
1554 rtx_code_label *csloop = gen_label_rtx ();
1555 rtx cmp, tmp;
1556 rtx old = gen_reg_rtx (SImode);
1557 rtx new_rtx = gen_reg_rtx (SImode);
1558 rtx orig = NULL_RTX;
1559
1560 init_alignment_context (&ac, mem);
1561
1562 /* Prepare values before the compare-and-swap loop. */
1563 if (ac.shift != NULL_RTX)
1564 val = xtensa_expand_mask_and_shift (val, mode, ac.shift);
1565 switch (code)
1566 {
1567 case PLUS:
1568 case MINUS:
1569 orig = gen_reg_rtx (SImode);
1570 convert_move (orig, val, 1);
1571 break;
1572
1573 case SET:
1574 case IOR:
1575 case XOR:
1576 break;
1577
1578 case MULT: /* NAND */
1579 case AND:
1580 /* val = "11..1<val>11..1" */
1581 val = expand_simple_binop (SImode, XOR, val, ac.modemaski,
1582 NULL_RTX, 1, OPTAB_DIRECT);
1583 break;
1584
1585 default:
1586 gcc_unreachable ();
1587 }
1588
1589 /* Load full word. Subsequent loads are performed by S32C1I. */
1590 cmp = force_reg (SImode, ac.memsi);
1591
1592 emit_label (csloop);
1593 emit_move_insn (old, cmp);
1594
1595 switch (code)
1596 {
1597 case PLUS:
1598 case MINUS:
1599 val = expand_simple_binop (SImode, code, old, orig,
1600 NULL_RTX, 1, OPTAB_DIRECT);
1601 val = expand_simple_binop (SImode, AND, val, ac.modemask,
1602 NULL_RTX, 1, OPTAB_DIRECT);
1603 /* FALLTHRU */
1604 case SET:
1605 tmp = expand_simple_binop (SImode, AND, old, ac.modemaski,
1606 NULL_RTX, 1, OPTAB_DIRECT);
1607 tmp = expand_simple_binop (SImode, IOR, tmp, val,
1608 new_rtx, 1, OPTAB_DIRECT);
1609 break;
1610
1611 case AND:
1612 case IOR:
1613 case XOR:
1614 tmp = expand_simple_binop (SImode, code, old, val,
1615 new_rtx, 1, OPTAB_DIRECT);
1616 break;
1617
1618 case MULT: /* NAND */
1619 tmp = expand_simple_binop (SImode, AND, old, val,
1620 NULL_RTX, 1, OPTAB_DIRECT);
1621 tmp = expand_simple_binop (SImode, XOR, tmp, ac.modemask,
1622 new_rtx, 1, OPTAB_DIRECT);
1623 break;
1624
1625 default:
1626 gcc_unreachable ();
1627 }
1628
1629 if (tmp != new_rtx)
1630 emit_move_insn (new_rtx, tmp);
1631 emit_insn (gen_sync_compare_and_swapsi (cmp, ac.memsi, old, new_rtx));
1632 emit_cmp_and_jump_insns (cmp, old, NE, const0_rtx, SImode, true, csloop);
1633
1634 if (target)
1635 {
1636 tmp = (after ? new_rtx : cmp);
1637 convert_move (target,
1638 (ac.shift == NULL_RTX ? tmp
1639 : expand_simple_binop (SImode, LSHIFTRT, tmp, ac.shift,
1640 NULL_RTX, 1, OPTAB_DIRECT)),
1641 1);
1642 }
1643 }
1644
1645
1646 void
xtensa_setup_frame_addresses(void)1647 xtensa_setup_frame_addresses (void)
1648 {
1649 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1650 cfun->machine->accesses_prev_frame = 1;
1651
1652 if (TARGET_WINDOWED_ABI)
1653 emit_library_call
1654 (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_libgcc_window_spill"),
1655 LCT_NORMAL, VOIDmode);
1656 }
1657
1658
1659 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1660 a comment showing where the end of the loop is. However, if there is a
1661 label or a branch at the end of the loop then we need to place a nop
1662 there. If the loop ends with a label we need the nop so that branches
1663 targeting that label will target the nop (and thus remain in the loop),
1664 instead of targeting the instruction after the loop (and thus exiting
1665 the loop). If the loop ends with a branch, we need the nop in case the
1666 branch is targeting a location inside the loop. When the branch
1667 executes it will cause the loop count to be decremented even if it is
1668 taken (because it is the last instruction in the loop), so we need to
1669 nop after the branch to prevent the loop count from being decremented
1670 when the branch is taken. */
1671
1672 void
xtensa_emit_loop_end(rtx_insn * insn,rtx * operands)1673 xtensa_emit_loop_end (rtx_insn *insn, rtx *operands)
1674 {
1675 char done = 0;
1676
1677 for (insn = PREV_INSN (insn); insn && !done; insn = PREV_INSN (insn))
1678 {
1679 switch (GET_CODE (insn))
1680 {
1681 case NOTE:
1682 case BARRIER:
1683 break;
1684
1685 case CODE_LABEL:
1686 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1687 done = 1;
1688 break;
1689
1690 default:
1691 {
1692 rtx body = PATTERN (insn);
1693
1694 if (JUMP_P (body))
1695 {
1696 output_asm_insn (TARGET_DENSITY ? "nop.n" : "nop", operands);
1697 done = 1;
1698 }
1699 else if ((GET_CODE (body) != USE)
1700 && (GET_CODE (body) != CLOBBER))
1701 done = 1;
1702 }
1703 break;
1704 }
1705 }
1706
1707 output_asm_insn ("%1_LEND:", operands);
1708 }
1709
1710
1711 char *
xtensa_emit_branch(bool inverted,bool immed,rtx * operands)1712 xtensa_emit_branch (bool inverted, bool immed, rtx *operands)
1713 {
1714 static char result[64];
1715 enum rtx_code code;
1716 const char *op;
1717
1718 code = GET_CODE (operands[3]);
1719 switch (code)
1720 {
1721 case EQ: op = inverted ? "ne" : "eq"; break;
1722 case NE: op = inverted ? "eq" : "ne"; break;
1723 case LT: op = inverted ? "ge" : "lt"; break;
1724 case GE: op = inverted ? "lt" : "ge"; break;
1725 case LTU: op = inverted ? "geu" : "ltu"; break;
1726 case GEU: op = inverted ? "ltu" : "geu"; break;
1727 default: gcc_unreachable ();
1728 }
1729
1730 if (immed)
1731 {
1732 if (INTVAL (operands[1]) == 0)
1733 sprintf (result, "b%sz%s\t%%0, %%2", op,
1734 (TARGET_DENSITY && (code == EQ || code == NE)) ? ".n" : "");
1735 else
1736 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1737 }
1738 else
1739 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1740
1741 return result;
1742 }
1743
1744
1745 char *
xtensa_emit_bit_branch(bool inverted,bool immed,rtx * operands)1746 xtensa_emit_bit_branch (bool inverted, bool immed, rtx *operands)
1747 {
1748 static char result[64];
1749 const char *op;
1750
1751 switch (GET_CODE (operands[3]))
1752 {
1753 case EQ: op = inverted ? "bs" : "bc"; break;
1754 case NE: op = inverted ? "bc" : "bs"; break;
1755 default: gcc_unreachable ();
1756 }
1757
1758 if (immed)
1759 {
1760 unsigned bitnum = INTVAL (operands[1]) & 0x1f;
1761 operands[1] = GEN_INT (bitnum);
1762 sprintf (result, "b%si\t%%0, %%d1, %%2", op);
1763 }
1764 else
1765 sprintf (result, "b%s\t%%0, %%1, %%2", op);
1766
1767 return result;
1768 }
1769
1770
1771 char *
xtensa_emit_movcc(bool inverted,bool isfp,bool isbool,rtx * operands)1772 xtensa_emit_movcc (bool inverted, bool isfp, bool isbool, rtx *operands)
1773 {
1774 static char result[64];
1775 enum rtx_code code;
1776 const char *op;
1777
1778 code = GET_CODE (operands[4]);
1779 if (isbool)
1780 {
1781 switch (code)
1782 {
1783 case EQ: op = inverted ? "t" : "f"; break;
1784 case NE: op = inverted ? "f" : "t"; break;
1785 default: gcc_unreachable ();
1786 }
1787 }
1788 else
1789 {
1790 switch (code)
1791 {
1792 case EQ: op = inverted ? "nez" : "eqz"; break;
1793 case NE: op = inverted ? "eqz" : "nez"; break;
1794 case LT: op = inverted ? "gez" : "ltz"; break;
1795 case GE: op = inverted ? "ltz" : "gez"; break;
1796 default: gcc_unreachable ();
1797 }
1798 }
1799
1800 sprintf (result, "mov%s%s\t%%0, %%%d, %%1",
1801 op, isfp ? ".s" : "", inverted ? 3 : 2);
1802 return result;
1803 }
1804
1805
1806 char *
xtensa_emit_call(int callop,rtx * operands)1807 xtensa_emit_call (int callop, rtx *operands)
1808 {
1809 static char result[64];
1810 rtx tgt = operands[callop];
1811
1812 if (GET_CODE (tgt) == CONST_INT)
1813 sprintf (result, "call%d\t" HOST_WIDE_INT_PRINT_HEX,
1814 WINDOW_SIZE, INTVAL (tgt));
1815 else if (register_operand (tgt, VOIDmode))
1816 sprintf (result, "callx%d\t%%%d", WINDOW_SIZE, callop);
1817 else
1818 sprintf (result, "call%d\t%%%d", WINDOW_SIZE, callop);
1819
1820 return result;
1821 }
1822
1823
1824 bool
xtensa_legitimate_address_p(machine_mode mode,rtx addr,bool strict)1825 xtensa_legitimate_address_p (machine_mode mode, rtx addr, bool strict)
1826 {
1827 /* Allow constant pool addresses. */
1828 if (mode != BLKmode && GET_MODE_SIZE (mode) >= UNITS_PER_WORD
1829 && ! TARGET_CONST16 && constantpool_address_p (addr)
1830 && ! xtensa_tls_referenced_p (addr))
1831 return true;
1832
1833 while (GET_CODE (addr) == SUBREG)
1834 addr = SUBREG_REG (addr);
1835
1836 /* Allow base registers. */
1837 if (GET_CODE (addr) == REG && BASE_REG_P (addr, strict))
1838 return true;
1839
1840 /* Check for "register + offset" addressing. */
1841 if (GET_CODE (addr) == PLUS)
1842 {
1843 rtx xplus0 = XEXP (addr, 0);
1844 rtx xplus1 = XEXP (addr, 1);
1845 enum rtx_code code0;
1846 enum rtx_code code1;
1847
1848 while (GET_CODE (xplus0) == SUBREG)
1849 xplus0 = SUBREG_REG (xplus0);
1850 code0 = GET_CODE (xplus0);
1851
1852 while (GET_CODE (xplus1) == SUBREG)
1853 xplus1 = SUBREG_REG (xplus1);
1854 code1 = GET_CODE (xplus1);
1855
1856 /* Swap operands if necessary so the register is first. */
1857 if (code0 != REG && code1 == REG)
1858 {
1859 xplus0 = XEXP (addr, 1);
1860 xplus1 = XEXP (addr, 0);
1861 code0 = GET_CODE (xplus0);
1862 code1 = GET_CODE (xplus1);
1863 }
1864
1865 if (code0 == REG && BASE_REG_P (xplus0, strict)
1866 && code1 == CONST_INT
1867 && xtensa_mem_offset (INTVAL (xplus1), mode))
1868 return true;
1869 }
1870
1871 return false;
1872 }
1873
1874
1875 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1876
1877 static GTY(()) rtx xtensa_tls_module_base_symbol;
1878
1879 static rtx
xtensa_tls_module_base(void)1880 xtensa_tls_module_base (void)
1881 {
1882 if (! xtensa_tls_module_base_symbol)
1883 {
1884 xtensa_tls_module_base_symbol =
1885 gen_rtx_SYMBOL_REF (Pmode, "_TLS_MODULE_BASE_");
1886 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol)
1887 |= TLS_MODEL_GLOBAL_DYNAMIC << SYMBOL_FLAG_TLS_SHIFT;
1888 }
1889
1890 return xtensa_tls_module_base_symbol;
1891 }
1892
1893
1894 static rtx_insn *
xtensa_call_tls_desc(rtx sym,rtx * retp)1895 xtensa_call_tls_desc (rtx sym, rtx *retp)
1896 {
1897 rtx fn, arg, a_io;
1898 rtx_insn *call_insn, *insns;
1899
1900 start_sequence ();
1901 fn = gen_reg_rtx (Pmode);
1902 arg = gen_reg_rtx (Pmode);
1903 a_io = gen_rtx_REG (Pmode, WINDOW_SIZE + 2);
1904
1905 emit_insn (gen_tls_func (fn, sym));
1906 emit_insn (gen_tls_arg (arg, sym));
1907 emit_move_insn (a_io, arg);
1908 call_insn = emit_call_insn (gen_tls_call (a_io, fn, sym, const1_rtx));
1909 use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), a_io);
1910 insns = get_insns ();
1911 end_sequence ();
1912
1913 *retp = a_io;
1914 return insns;
1915 }
1916
1917
1918 static rtx
xtensa_legitimize_tls_address(rtx x)1919 xtensa_legitimize_tls_address (rtx x)
1920 {
1921 unsigned int model = SYMBOL_REF_TLS_MODEL (x);
1922 rtx dest, tp, ret, modbase, base, addend;
1923 rtx_insn *insns;
1924
1925 dest = gen_reg_rtx (Pmode);
1926 switch (model)
1927 {
1928 case TLS_MODEL_GLOBAL_DYNAMIC:
1929 insns = xtensa_call_tls_desc (x, &ret);
1930 emit_libcall_block (insns, dest, ret, x);
1931 break;
1932
1933 case TLS_MODEL_LOCAL_DYNAMIC:
1934 base = gen_reg_rtx (Pmode);
1935 modbase = xtensa_tls_module_base ();
1936 insns = xtensa_call_tls_desc (modbase, &ret);
1937 emit_libcall_block (insns, base, ret, modbase);
1938 addend = force_reg (SImode, gen_sym_DTPOFF (x));
1939 emit_insn (gen_addsi3 (dest, base, addend));
1940 break;
1941
1942 case TLS_MODEL_INITIAL_EXEC:
1943 case TLS_MODEL_LOCAL_EXEC:
1944 tp = gen_reg_rtx (SImode);
1945 emit_insn (gen_get_thread_pointersi (tp));
1946 addend = force_reg (SImode, gen_sym_TPOFF (x));
1947 emit_insn (gen_addsi3 (dest, tp, addend));
1948 break;
1949
1950 default:
1951 gcc_unreachable ();
1952 }
1953
1954 return dest;
1955 }
1956
1957
1958 rtx
xtensa_legitimize_address(rtx x,rtx oldx ATTRIBUTE_UNUSED,machine_mode mode)1959 xtensa_legitimize_address (rtx x,
1960 rtx oldx ATTRIBUTE_UNUSED,
1961 machine_mode mode)
1962 {
1963 if (xtensa_tls_symbol_p (x))
1964 return xtensa_legitimize_tls_address (x);
1965
1966 if (GET_CODE (x) == PLUS)
1967 {
1968 rtx plus0 = XEXP (x, 0);
1969 rtx plus1 = XEXP (x, 1);
1970
1971 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
1972 {
1973 plus0 = XEXP (x, 1);
1974 plus1 = XEXP (x, 0);
1975 }
1976
1977 /* Try to split up the offset to use an ADDMI instruction. */
1978 if (GET_CODE (plus0) == REG
1979 && GET_CODE (plus1) == CONST_INT
1980 && !xtensa_mem_offset (INTVAL (plus1), mode)
1981 && !xtensa_simm8 (INTVAL (plus1))
1982 && xtensa_mem_offset (INTVAL (plus1) & 0xff, mode)
1983 && xtensa_simm8x256 (INTVAL (plus1) & ~0xff))
1984 {
1985 rtx temp = gen_reg_rtx (Pmode);
1986 rtx addmi_offset = GEN_INT (INTVAL (plus1) & ~0xff);
1987 emit_insn (gen_rtx_SET (temp, gen_rtx_PLUS (Pmode, plus0,
1988 addmi_offset)));
1989 return gen_rtx_PLUS (Pmode, temp, GEN_INT (INTVAL (plus1) & 0xff));
1990 }
1991 }
1992
1993 return x;
1994 }
1995
1996 /* Worker function for TARGET_MODE_DEPENDENT_ADDRESS_P.
1997
1998 Treat constant-pool references as "mode dependent" since they can
1999 only be accessed with SImode loads. This works around a bug in the
2000 combiner where a constant pool reference is temporarily converted
2001 to an HImode load, which is then assumed to zero-extend based on
2002 our definition of LOAD_EXTEND_OP. This is wrong because the high
2003 bits of a 16-bit value in the constant pool are now sign-extended
2004 by default. */
2005
2006 static bool
xtensa_mode_dependent_address_p(const_rtx addr,addr_space_t as ATTRIBUTE_UNUSED)2007 xtensa_mode_dependent_address_p (const_rtx addr,
2008 addr_space_t as ATTRIBUTE_UNUSED)
2009 {
2010 return constantpool_address_p (addr);
2011 }
2012
2013 /* Return TRUE if X contains any TLS symbol references. */
2014
2015 bool
xtensa_tls_referenced_p(rtx x)2016 xtensa_tls_referenced_p (rtx x)
2017 {
2018 if (! TARGET_HAVE_TLS)
2019 return false;
2020
2021 subrtx_iterator::array_type array;
2022 FOR_EACH_SUBRTX (iter, array, x, ALL)
2023 {
2024 const_rtx x = *iter;
2025 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x) != 0)
2026 return true;
2027
2028 /* Ignore TLS references that have already been legitimized. */
2029 if (GET_CODE (x) == UNSPEC)
2030 switch (XINT (x, 1))
2031 {
2032 case UNSPEC_TPOFF:
2033 case UNSPEC_DTPOFF:
2034 case UNSPEC_TLS_FUNC:
2035 case UNSPEC_TLS_ARG:
2036 case UNSPEC_TLS_CALL:
2037 iter.skip_subrtxes ();
2038 break;
2039 default:
2040 break;
2041 }
2042 }
2043 return false;
2044 }
2045
2046
2047 /* Implement TARGET_CANNOT_FORCE_CONST_MEM. */
2048
2049 static bool
xtensa_cannot_force_const_mem(machine_mode mode ATTRIBUTE_UNUSED,rtx x)2050 xtensa_cannot_force_const_mem (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
2051 {
2052 return xtensa_tls_referenced_p (x);
2053 }
2054
2055
2056 /* Return the debugger register number to use for 'regno'. */
2057
2058 int
xtensa_dbx_register_number(int regno)2059 xtensa_dbx_register_number (int regno)
2060 {
2061 int first = -1;
2062
2063 if (GP_REG_P (regno))
2064 {
2065 regno -= GP_REG_FIRST;
2066 first = 0;
2067 }
2068 else if (BR_REG_P (regno))
2069 {
2070 regno -= BR_REG_FIRST;
2071 first = 16;
2072 }
2073 else if (FP_REG_P (regno))
2074 {
2075 regno -= FP_REG_FIRST;
2076 first = 48;
2077 }
2078 else if (ACC_REG_P (regno))
2079 {
2080 first = 0x200; /* Start of Xtensa special registers. */
2081 regno = 16; /* ACCLO is special register 16. */
2082 }
2083
2084 /* When optimizing, we sometimes get asked about pseudo-registers
2085 that don't represent hard registers. Return 0 for these. */
2086 if (first == -1)
2087 return 0;
2088
2089 return first + regno;
2090 }
2091
2092
2093 /* Argument support functions. */
2094
2095 /* Initialize CUMULATIVE_ARGS for a function. */
2096
2097 void
init_cumulative_args(CUMULATIVE_ARGS * cum,int incoming)2098 init_cumulative_args (CUMULATIVE_ARGS *cum, int incoming)
2099 {
2100 cum->arg_words = 0;
2101 cum->incoming = incoming;
2102 }
2103
2104
2105 /* Advance the argument to the next argument position. */
2106
2107 static void
xtensa_function_arg_advance(cumulative_args_t cum,const function_arg_info & arg)2108 xtensa_function_arg_advance (cumulative_args_t cum,
2109 const function_arg_info &arg)
2110 {
2111 int words, max;
2112 int *arg_words;
2113
2114 arg_words = &get_cumulative_args (cum)->arg_words;
2115 max = MAX_ARGS_IN_REGISTERS;
2116
2117 words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
2118 / UNITS_PER_WORD);
2119
2120 if (*arg_words < max
2121 && (targetm.calls.must_pass_in_stack (arg)
2122 || *arg_words + words > max))
2123 *arg_words = max;
2124
2125 *arg_words += words;
2126 }
2127
2128
2129 /* Return an RTL expression containing the register for the given argument,
2130 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2131 if this is an incoming argument to the current function. */
2132
2133 static rtx
xtensa_function_arg_1(cumulative_args_t cum_v,const function_arg_info & arg,bool incoming_p)2134 xtensa_function_arg_1 (cumulative_args_t cum_v, const function_arg_info &arg,
2135 bool incoming_p)
2136 {
2137 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
2138 int regbase, words, max;
2139 int *arg_words;
2140 int regno;
2141
2142 arg_words = &cum->arg_words;
2143 regbase = (incoming_p ? GP_ARG_FIRST : GP_OUTGOING_ARG_FIRST);
2144 max = MAX_ARGS_IN_REGISTERS;
2145
2146 words = ((arg.promoted_size_in_bytes () + UNITS_PER_WORD - 1)
2147 / UNITS_PER_WORD);
2148
2149 if (arg.type && (TYPE_ALIGN (arg.type) > BITS_PER_WORD))
2150 {
2151 int align = MIN (TYPE_ALIGN (arg.type), STACK_BOUNDARY) / BITS_PER_WORD;
2152 *arg_words = (*arg_words + align - 1) & -align;
2153 }
2154
2155 if (*arg_words + words > max)
2156 return (rtx)0;
2157
2158 regno = regbase + *arg_words;
2159
2160 if (cum->incoming && regno <= A7_REG && regno + words > A7_REG)
2161 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI;
2162
2163 return gen_rtx_REG (arg.mode, regno);
2164 }
2165
2166 /* Implement TARGET_FUNCTION_ARG. */
2167
2168 static rtx
xtensa_function_arg(cumulative_args_t cum,const function_arg_info & arg)2169 xtensa_function_arg (cumulative_args_t cum, const function_arg_info &arg)
2170 {
2171 return xtensa_function_arg_1 (cum, arg, false);
2172 }
2173
2174 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2175
2176 static rtx
xtensa_function_incoming_arg(cumulative_args_t cum,const function_arg_info & arg)2177 xtensa_function_incoming_arg (cumulative_args_t cum,
2178 const function_arg_info &arg)
2179 {
2180 return xtensa_function_arg_1 (cum, arg, true);
2181 }
2182
2183 static unsigned int
xtensa_function_arg_boundary(machine_mode mode,const_tree type)2184 xtensa_function_arg_boundary (machine_mode mode, const_tree type)
2185 {
2186 unsigned int alignment;
2187
2188 alignment = type ? TYPE_ALIGN (type) : GET_MODE_ALIGNMENT (mode);
2189 if (alignment < PARM_BOUNDARY)
2190 alignment = PARM_BOUNDARY;
2191 if (alignment > STACK_BOUNDARY)
2192 alignment = STACK_BOUNDARY;
2193 return alignment;
2194 }
2195
2196
2197 static bool
xtensa_return_in_msb(const_tree valtype)2198 xtensa_return_in_msb (const_tree valtype)
2199 {
2200 return (TARGET_BIG_ENDIAN
2201 && AGGREGATE_TYPE_P (valtype)
2202 && int_size_in_bytes (valtype) >= UNITS_PER_WORD);
2203 }
2204
2205
2206 static void
xtensa_option_override(void)2207 xtensa_option_override (void)
2208 {
2209 int regno;
2210 machine_mode mode;
2211
2212 /* Use CONST16 in the absence of L32R.
2213 Set it in the TARGET_OPTION_OVERRIDE to avoid dependency on xtensa
2214 configuration in the xtensa-common.c */
2215
2216 if (!TARGET_L32R)
2217 target_flags |= MASK_CONST16;
2218
2219 if (!TARGET_BOOLEANS && TARGET_HARD_FLOAT)
2220 error ("boolean registers required for the floating-point option");
2221
2222 /* Set up array giving whether a given register can hold a given mode. */
2223 for (mode = VOIDmode;
2224 mode != MAX_MACHINE_MODE;
2225 mode = (machine_mode) ((int) mode + 1))
2226 {
2227 int size = GET_MODE_SIZE (mode);
2228 enum mode_class mclass = GET_MODE_CLASS (mode);
2229
2230 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
2231 {
2232 int temp;
2233
2234 if (ACC_REG_P (regno))
2235 temp = (TARGET_MAC16
2236 && (mclass == MODE_INT) && (size <= UNITS_PER_WORD));
2237 else if (GP_REG_P (regno))
2238 temp = ((regno & 1) == 0 || (size <= UNITS_PER_WORD));
2239 else if (FP_REG_P (regno))
2240 temp = (TARGET_HARD_FLOAT && (mode == SFmode));
2241 else if (BR_REG_P (regno))
2242 temp = (TARGET_BOOLEANS && (mode == CCmode));
2243 else
2244 temp = FALSE;
2245
2246 xtensa_hard_regno_mode_ok_p[(int) mode][regno] = temp;
2247 }
2248 }
2249
2250 init_machine_status = xtensa_init_machine_status;
2251
2252 /* Check PIC settings. PIC is only supported when using L32R
2253 instructions, and some targets need to always use PIC. */
2254 if (flag_pic && TARGET_CONST16)
2255 error ("%<-f%s%> is not supported with CONST16 instructions",
2256 (flag_pic > 1 ? "PIC" : "pic"));
2257 else if (TARGET_FORCE_NO_PIC)
2258 flag_pic = 0;
2259 else if (XTENSA_ALWAYS_PIC)
2260 {
2261 if (TARGET_CONST16)
2262 error ("PIC is required but not supported with CONST16 instructions");
2263 flag_pic = 1;
2264 }
2265 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2266 if (flag_pic > 1)
2267 flag_pic = 1;
2268 if (flag_pic && !flag_pie)
2269 flag_shlib = 1;
2270
2271 /* Hot/cold partitioning does not work on this architecture, because of
2272 constant pools (the load instruction cannot necessarily reach that far).
2273 Therefore disable it on this architecture. */
2274 if (flag_reorder_blocks_and_partition)
2275 {
2276 flag_reorder_blocks_and_partition = 0;
2277 flag_reorder_blocks = 1;
2278 }
2279 }
2280
2281 /* Implement TARGET_HARD_REGNO_NREGS. */
2282
2283 static unsigned int
xtensa_hard_regno_nregs(unsigned int regno,machine_mode mode)2284 xtensa_hard_regno_nregs (unsigned int regno, machine_mode mode)
2285 {
2286 if (FP_REG_P (regno))
2287 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_FPREG);
2288 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2289 }
2290
2291 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2292
2293 static bool
xtensa_hard_regno_mode_ok(unsigned int regno,machine_mode mode)2294 xtensa_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2295 {
2296 return xtensa_hard_regno_mode_ok_p[mode][regno];
2297 }
2298
2299 /* Implement TARGET_MODES_TIEABLE_P. */
2300
2301 static bool
xtensa_modes_tieable_p(machine_mode mode1,machine_mode mode2)2302 xtensa_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2303 {
2304 return ((GET_MODE_CLASS (mode1) == MODE_FLOAT
2305 || GET_MODE_CLASS (mode1) == MODE_COMPLEX_FLOAT)
2306 == (GET_MODE_CLASS (mode2) == MODE_FLOAT
2307 || GET_MODE_CLASS (mode2) == MODE_COMPLEX_FLOAT));
2308 }
2309
2310 /* A C compound statement to output to stdio stream STREAM the
2311 assembler syntax for an instruction operand X. X is an RTL
2312 expression.
2313
2314 CODE is a value that can be used to specify one of several ways
2315 of printing the operand. It is used when identical operands
2316 must be printed differently depending on the context. CODE
2317 comes from the '%' specification that was used to request
2318 printing of the operand. If the specification was just '%DIGIT'
2319 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2320 is the ASCII code for LTR.
2321
2322 If X is a register, this macro should print the register's name.
2323 The names can be found in an array 'reg_names' whose type is
2324 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2325
2326 When the machine description has a specification '%PUNCT' (a '%'
2327 followed by a punctuation character), this macro is called with
2328 a null pointer for X and the punctuation character for CODE.
2329
2330 'a', 'c', 'l', and 'n' are reserved.
2331
2332 The Xtensa specific codes are:
2333
2334 'd' CONST_INT, print as signed decimal
2335 'x' CONST_INT, print as signed hexadecimal
2336 'K' CONST_INT, print number of bits in mask for EXTUI
2337 'R' CONST_INT, print (X & 0x1f)
2338 'L' CONST_INT, print ((32 - X) & 0x1f)
2339 'D' REG, print second register of double-word register operand
2340 'N' MEM, print address of next word following a memory operand
2341 'v' MEM, if memory reference is volatile, output a MEMW before it
2342 't' any constant, add "@h" suffix for top 16 bits
2343 'b' any constant, add "@l" suffix for bottom 16 bits
2344 */
2345
2346 static void
printx(FILE * file,signed int val)2347 printx (FILE *file, signed int val)
2348 {
2349 /* Print a hexadecimal value in a nice way. */
2350 if ((val > -0xa) && (val < 0xa))
2351 fprintf (file, "%d", val);
2352 else if (val < 0)
2353 fprintf (file, "-0x%x", -val);
2354 else
2355 fprintf (file, "0x%x", val);
2356 }
2357
2358
2359 void
print_operand(FILE * file,rtx x,int letter)2360 print_operand (FILE *file, rtx x, int letter)
2361 {
2362 if (!x)
2363 error ("PRINT_OPERAND null pointer");
2364
2365 switch (letter)
2366 {
2367 case 'D':
2368 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2369 fprintf (file, "%s", reg_names[xt_true_regnum (x) + 1]);
2370 else
2371 output_operand_lossage ("invalid %%D value");
2372 break;
2373
2374 case 'v':
2375 if (GET_CODE (x) == MEM)
2376 {
2377 /* For a volatile memory reference, emit a MEMW before the
2378 load or store. */
2379 if (MEM_VOLATILE_P (x) && TARGET_SERIALIZE_VOLATILE)
2380 fprintf (file, "memw\n\t");
2381 }
2382 else
2383 output_operand_lossage ("invalid %%v value");
2384 break;
2385
2386 case 'N':
2387 if (GET_CODE (x) == MEM
2388 && (GET_MODE (x) == DFmode || GET_MODE (x) == DImode))
2389 {
2390 x = adjust_address (x, GET_MODE (x) == DFmode ? E_SFmode : E_SImode,
2391 4);
2392 output_address (GET_MODE (x), XEXP (x, 0));
2393 }
2394 else
2395 output_operand_lossage ("invalid %%N value");
2396 break;
2397
2398 case 'K':
2399 if (GET_CODE (x) == CONST_INT)
2400 {
2401 int num_bits = 0;
2402 unsigned val = INTVAL (x);
2403 while (val & 1)
2404 {
2405 num_bits += 1;
2406 val = val >> 1;
2407 }
2408 if ((val != 0) || (num_bits == 0) || (num_bits > 16))
2409 fatal_insn ("invalid mask", x);
2410
2411 fprintf (file, "%d", num_bits);
2412 }
2413 else
2414 output_operand_lossage ("invalid %%K value");
2415 break;
2416
2417 case 'L':
2418 if (GET_CODE (x) == CONST_INT)
2419 fprintf (file, HOST_WIDE_INT_PRINT_DEC, (32 - INTVAL (x)) & 0x1f);
2420 else
2421 output_operand_lossage ("invalid %%L value");
2422 break;
2423
2424 case 'R':
2425 if (GET_CODE (x) == CONST_INT)
2426 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) & 0x1f);
2427 else
2428 output_operand_lossage ("invalid %%R value");
2429 break;
2430
2431 case 'x':
2432 if (GET_CODE (x) == CONST_INT)
2433 printx (file, INTVAL (x));
2434 else
2435 output_operand_lossage ("invalid %%x value");
2436 break;
2437
2438 case 'd':
2439 if (GET_CODE (x) == CONST_INT)
2440 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2441 else
2442 output_operand_lossage ("invalid %%d value");
2443 break;
2444
2445 case 't':
2446 case 'b':
2447 if (GET_CODE (x) == CONST_INT)
2448 {
2449 printx (file, INTVAL (x));
2450 fputs (letter == 't' ? "@h" : "@l", file);
2451 }
2452 else if (GET_CODE (x) == CONST_DOUBLE)
2453 {
2454 if (GET_MODE (x) == SFmode)
2455 {
2456 long l;
2457 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
2458 fprintf (file, "0x%08lx@%c", l, letter == 't' ? 'h' : 'l');
2459 }
2460 else
2461 output_operand_lossage ("invalid %%t/%%b value");
2462 }
2463 else if (GET_CODE (x) == CONST)
2464 {
2465 /* X must be a symbolic constant on ELF. Write an expression
2466 suitable for 'const16' that sets the high or low 16 bits. */
2467 if (GET_CODE (XEXP (x, 0)) != PLUS
2468 || (GET_CODE (XEXP (XEXP (x, 0), 0)) != SYMBOL_REF
2469 && GET_CODE (XEXP (XEXP (x, 0), 0)) != LABEL_REF)
2470 || GET_CODE (XEXP (XEXP (x, 0), 1)) != CONST_INT)
2471 output_operand_lossage ("invalid %%t/%%b value");
2472 print_operand (file, XEXP (XEXP (x, 0), 0), 0);
2473 fputs (letter == 't' ? "@h" : "@l", file);
2474 /* There must be a non-alphanumeric character between 'h' or 'l'
2475 and the number. The '-' is added by print_operand() already. */
2476 if (INTVAL (XEXP (XEXP (x, 0), 1)) >= 0)
2477 fputs ("+", file);
2478 print_operand (file, XEXP (XEXP (x, 0), 1), 0);
2479 }
2480 else
2481 {
2482 output_addr_const (file, x);
2483 fputs (letter == 't' ? "@h" : "@l", file);
2484 }
2485 break;
2486
2487 case 'y':
2488 if (GET_CODE (x) == CONST_DOUBLE &&
2489 GET_MODE (x) == SFmode)
2490 {
2491 long l;
2492 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
2493 fprintf (file, "0x%08lx", l);
2494 break;
2495 }
2496
2497 /* fall through */
2498
2499 default:
2500 if (GET_CODE (x) == REG || GET_CODE (x) == SUBREG)
2501 fprintf (file, "%s", reg_names[xt_true_regnum (x)]);
2502 else if (GET_CODE (x) == MEM)
2503 output_address (GET_MODE (x), XEXP (x, 0));
2504 else if (GET_CODE (x) == CONST_INT)
2505 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
2506 else
2507 output_addr_const (file, x);
2508 }
2509 }
2510
2511
2512 /* A C compound statement to output to stdio stream STREAM the
2513 assembler syntax for an instruction operand that is a memory
2514 reference whose address is ADDR. ADDR is an RTL expression. */
2515
2516 void
print_operand_address(FILE * file,rtx addr)2517 print_operand_address (FILE *file, rtx addr)
2518 {
2519 if (!addr)
2520 error ("PRINT_OPERAND_ADDRESS, null pointer");
2521
2522 switch (GET_CODE (addr))
2523 {
2524 default:
2525 fatal_insn ("invalid address", addr);
2526 break;
2527
2528 case REG:
2529 fprintf (file, "%s, 0", reg_names [REGNO (addr)]);
2530 break;
2531
2532 case PLUS:
2533 {
2534 rtx reg = (rtx)0;
2535 rtx offset = (rtx)0;
2536 rtx arg0 = XEXP (addr, 0);
2537 rtx arg1 = XEXP (addr, 1);
2538
2539 if (GET_CODE (arg0) == REG)
2540 {
2541 reg = arg0;
2542 offset = arg1;
2543 }
2544 else if (GET_CODE (arg1) == REG)
2545 {
2546 reg = arg1;
2547 offset = arg0;
2548 }
2549 else
2550 fatal_insn ("no register in address", addr);
2551
2552 if (CONSTANT_P (offset))
2553 {
2554 fprintf (file, "%s, ", reg_names [REGNO (reg)]);
2555 output_addr_const (file, offset);
2556 }
2557 else
2558 fatal_insn ("address offset not a constant", addr);
2559 }
2560 break;
2561
2562 case LABEL_REF:
2563 case SYMBOL_REF:
2564 case CONST_INT:
2565 case CONST:
2566 output_addr_const (file, addr);
2567 break;
2568 }
2569 }
2570
2571 /* Implement TARGET_ASM_OUTPUT_ADDR_CONST_EXTRA. */
2572
2573 static bool
xtensa_output_addr_const_extra(FILE * fp,rtx x)2574 xtensa_output_addr_const_extra (FILE *fp, rtx x)
2575 {
2576 if (GET_CODE (x) == UNSPEC && XVECLEN (x, 0) == 1)
2577 {
2578 switch (XINT (x, 1))
2579 {
2580 case UNSPEC_TPOFF:
2581 output_addr_const (fp, XVECEXP (x, 0, 0));
2582 fputs ("@TPOFF", fp);
2583 return true;
2584 case UNSPEC_DTPOFF:
2585 output_addr_const (fp, XVECEXP (x, 0, 0));
2586 fputs ("@DTPOFF", fp);
2587 return true;
2588 case UNSPEC_PLT:
2589 if (flag_pic)
2590 {
2591 output_addr_const (fp, XVECEXP (x, 0, 0));
2592 fputs ("@PLT", fp);
2593 return true;
2594 }
2595 break;
2596 default:
2597 break;
2598 }
2599 }
2600 return false;
2601 }
2602
2603 static void
xtensa_output_integer_literal_parts(FILE * file,rtx x,int size)2604 xtensa_output_integer_literal_parts (FILE *file, rtx x, int size)
2605 {
2606 if (size > 4 && !(size & (size - 1)))
2607 {
2608 rtx first, second;
2609
2610 split_double (x, &first, &second);
2611 xtensa_output_integer_literal_parts (file, first, size / 2);
2612 fputs (", ", file);
2613 xtensa_output_integer_literal_parts (file, second, size / 2);
2614 }
2615 else if (size == 4)
2616 {
2617 output_addr_const (file, x);
2618 }
2619 else
2620 {
2621 gcc_unreachable();
2622 }
2623 }
2624
2625 void
xtensa_output_literal(FILE * file,rtx x,machine_mode mode,int labelno)2626 xtensa_output_literal (FILE *file, rtx x, machine_mode mode, int labelno)
2627 {
2628 long value_long[2];
2629
2630 fprintf (file, "\t.literal .LC%u, ", (unsigned) labelno);
2631
2632 switch (GET_MODE_CLASS (mode))
2633 {
2634 case MODE_FLOAT:
2635 gcc_assert (GET_CODE (x) == CONST_DOUBLE);
2636
2637 switch (mode)
2638 {
2639 case E_SFmode:
2640 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x),
2641 value_long[0]);
2642 if (HOST_BITS_PER_LONG > 32)
2643 value_long[0] &= 0xffffffff;
2644 fprintf (file, "0x%08lx\n", value_long[0]);
2645 break;
2646
2647 case E_DFmode:
2648 REAL_VALUE_TO_TARGET_DOUBLE (*CONST_DOUBLE_REAL_VALUE (x),
2649 value_long);
2650 if (HOST_BITS_PER_LONG > 32)
2651 {
2652 value_long[0] &= 0xffffffff;
2653 value_long[1] &= 0xffffffff;
2654 }
2655 fprintf (file, "0x%08lx, 0x%08lx\n",
2656 value_long[0], value_long[1]);
2657 break;
2658
2659 default:
2660 gcc_unreachable ();
2661 }
2662
2663 break;
2664
2665 case MODE_INT:
2666 case MODE_PARTIAL_INT:
2667 xtensa_output_integer_literal_parts (file, x, GET_MODE_SIZE (mode));
2668 fputs ("\n", file);
2669 break;
2670
2671 default:
2672 gcc_unreachable ();
2673 }
2674 }
2675
2676 static bool
xtensa_call_save_reg(int regno)2677 xtensa_call_save_reg(int regno)
2678 {
2679 if (TARGET_WINDOWED_ABI)
2680 return false;
2681
2682 if (regno == A0_REG)
2683 return crtl->profile || !crtl->is_leaf || crtl->calls_eh_return ||
2684 df_regs_ever_live_p (regno);
2685
2686 if (crtl->calls_eh_return && regno >= 2 && regno < 4)
2687 return true;
2688
2689 return !call_used_or_fixed_reg_p (regno) && df_regs_ever_live_p (regno);
2690 }
2691
2692 /* Return the bytes needed to compute the frame pointer from the current
2693 stack pointer. */
2694
2695 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2696 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2697
2698 long
compute_frame_size(poly_int64 size)2699 compute_frame_size (poly_int64 size)
2700 {
2701 int regno;
2702
2703 if (reload_completed && cfun->machine->frame_laid_out)
2704 return cfun->machine->current_frame_size;
2705
2706 /* Add space for the incoming static chain value. */
2707 if (cfun->static_chain_decl != NULL)
2708 size += (1 * UNITS_PER_WORD);
2709
2710 cfun->machine->callee_save_size = 0;
2711 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2712 {
2713 if (xtensa_call_save_reg(regno))
2714 cfun->machine->callee_save_size += UNITS_PER_WORD;
2715 }
2716
2717 cfun->machine->current_frame_size =
2718 XTENSA_STACK_ALIGN (size
2719 + cfun->machine->callee_save_size
2720 + crtl->outgoing_args_size
2721 + (WINDOW_SIZE * UNITS_PER_WORD));
2722 cfun->machine->callee_save_size =
2723 XTENSA_STACK_ALIGN (cfun->machine->callee_save_size);
2724 cfun->machine->frame_laid_out = true;
2725 return cfun->machine->current_frame_size;
2726 }
2727
2728
2729 bool
xtensa_frame_pointer_required(void)2730 xtensa_frame_pointer_required (void)
2731 {
2732 /* The code to expand builtin_frame_addr and builtin_return_addr
2733 currently uses the hard_frame_pointer instead of frame_pointer.
2734 This seems wrong but maybe it's necessary for other architectures.
2735 This function is derived from the i386 code. */
2736
2737 if (cfun->machine->accesses_prev_frame || cfun->has_nonlocal_label)
2738 return true;
2739
2740 return false;
2741 }
2742
2743 HOST_WIDE_INT
xtensa_initial_elimination_offset(int from,int to ATTRIBUTE_UNUSED)2744 xtensa_initial_elimination_offset (int from, int to ATTRIBUTE_UNUSED)
2745 {
2746 long frame_size = compute_frame_size (get_frame_size ());
2747 HOST_WIDE_INT offset;
2748
2749 switch (from)
2750 {
2751 case FRAME_POINTER_REGNUM:
2752 if (FRAME_GROWS_DOWNWARD)
2753 offset = frame_size - (WINDOW_SIZE * UNITS_PER_WORD)
2754 - cfun->machine->callee_save_size;
2755 else
2756 offset = 0;
2757 break;
2758 case ARG_POINTER_REGNUM:
2759 offset = frame_size;
2760 break;
2761 default:
2762 gcc_unreachable ();
2763 }
2764
2765 return offset;
2766 }
2767
2768 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2769 and the total number of words must be a multiple of 128 bits. */
2770 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2771
2772 void
xtensa_expand_prologue(void)2773 xtensa_expand_prologue (void)
2774 {
2775 HOST_WIDE_INT total_size;
2776 rtx_insn *insn = NULL;
2777 rtx note_rtx;
2778
2779
2780 total_size = compute_frame_size (get_frame_size ());
2781
2782 if (flag_stack_usage_info)
2783 current_function_static_stack_size = total_size;
2784
2785 if (TARGET_WINDOWED_ABI)
2786 {
2787 if (total_size < (1 << (12+3)))
2788 insn = emit_insn (gen_entry (GEN_INT (total_size)));
2789 else
2790 {
2791 /* Use a8 as a temporary since a0-a7 may be live. */
2792 rtx tmp_reg = gen_rtx_REG (Pmode, A8_REG);
2793 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE)));
2794 emit_move_insn (tmp_reg, GEN_INT (total_size - MIN_FRAME_SIZE));
2795 emit_insn (gen_subsi3 (tmp_reg, stack_pointer_rtx, tmp_reg));
2796 insn = emit_insn (gen_movsi (stack_pointer_rtx, tmp_reg));
2797 }
2798 }
2799 else
2800 {
2801 int regno;
2802 HOST_WIDE_INT offset = 0;
2803 int callee_save_size = cfun->machine->callee_save_size;
2804
2805 /* -128 is a limit of single addi instruction. */
2806 if (total_size > 0 && total_size <= 128)
2807 {
2808 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2809 GEN_INT (-total_size)));
2810 RTX_FRAME_RELATED_P (insn) = 1;
2811 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2812 plus_constant (Pmode, stack_pointer_rtx,
2813 -total_size));
2814 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2815 offset = total_size - UNITS_PER_WORD;
2816 }
2817 else if (callee_save_size)
2818 {
2819 /* 1020 is maximal s32i offset, if the frame is bigger than that
2820 * we move sp to the end of callee-saved save area, save and then
2821 * move it to its final location. */
2822 if (total_size > 1024)
2823 {
2824 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2825 GEN_INT (-callee_save_size)));
2826 RTX_FRAME_RELATED_P (insn) = 1;
2827 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2828 plus_constant (Pmode, stack_pointer_rtx,
2829 -callee_save_size));
2830 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2831 offset = callee_save_size - UNITS_PER_WORD;
2832 }
2833 else
2834 {
2835 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2836 emit_move_insn (tmp_reg, GEN_INT (total_size));
2837 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
2838 stack_pointer_rtx, tmp_reg));
2839 RTX_FRAME_RELATED_P (insn) = 1;
2840 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2841 plus_constant (Pmode, stack_pointer_rtx,
2842 -total_size));
2843 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2844 offset = total_size - UNITS_PER_WORD;
2845 }
2846 }
2847
2848 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2849 {
2850 if (xtensa_call_save_reg(regno))
2851 {
2852 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2853 rtx mem = gen_frame_mem (SImode, x);
2854 rtx reg = gen_rtx_REG (SImode, regno);
2855
2856 offset -= UNITS_PER_WORD;
2857 insn = emit_move_insn (mem, reg);
2858 RTX_FRAME_RELATED_P (insn) = 1;
2859 add_reg_note (insn, REG_FRAME_RELATED_EXPR,
2860 gen_rtx_SET (mem, reg));
2861 }
2862 }
2863 if (total_size > 1024
2864 || (!callee_save_size && total_size > 128))
2865 {
2866 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2867 emit_move_insn (tmp_reg, GEN_INT (total_size -
2868 callee_save_size));
2869 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
2870 stack_pointer_rtx, tmp_reg));
2871 RTX_FRAME_RELATED_P (insn) = 1;
2872 note_rtx = gen_rtx_SET (stack_pointer_rtx,
2873 plus_constant (Pmode, stack_pointer_rtx,
2874 callee_save_size -
2875 total_size));
2876 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2877 }
2878 }
2879
2880 if (frame_pointer_needed)
2881 {
2882 if (cfun->machine->set_frame_ptr_insn)
2883 {
2884 rtx_insn *first;
2885
2886 push_topmost_sequence ();
2887 first = get_insns ();
2888 pop_topmost_sequence ();
2889
2890 /* For all instructions prior to set_frame_ptr_insn, replace
2891 hard_frame_pointer references with stack_pointer. */
2892 for (insn = first;
2893 insn != cfun->machine->set_frame_ptr_insn;
2894 insn = NEXT_INSN (insn))
2895 {
2896 if (INSN_P (insn))
2897 {
2898 PATTERN (insn) = replace_rtx (copy_rtx (PATTERN (insn)),
2899 hard_frame_pointer_rtx,
2900 stack_pointer_rtx);
2901 df_insn_rescan (insn);
2902 }
2903 }
2904 }
2905 else
2906 {
2907 insn = emit_insn (gen_movsi (hard_frame_pointer_rtx,
2908 stack_pointer_rtx));
2909 if (!TARGET_WINDOWED_ABI)
2910 {
2911 note_rtx = gen_rtx_SET (hard_frame_pointer_rtx,
2912 stack_pointer_rtx);
2913 RTX_FRAME_RELATED_P (insn) = 1;
2914 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2915 }
2916 }
2917 }
2918
2919 if (TARGET_WINDOWED_ABI)
2920 {
2921 /* Create a note to describe the CFA. Because this is only used to set
2922 DW_AT_frame_base for debug info, don't bother tracking changes through
2923 each instruction in the prologue. It just takes up space. */
2924 note_rtx = gen_rtx_SET ((frame_pointer_needed
2925 ? hard_frame_pointer_rtx
2926 : stack_pointer_rtx),
2927 plus_constant (Pmode, stack_pointer_rtx,
2928 -total_size));
2929 RTX_FRAME_RELATED_P (insn) = 1;
2930 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
2931 }
2932 }
2933
2934 void
xtensa_expand_epilogue(void)2935 xtensa_expand_epilogue (void)
2936 {
2937 if (!TARGET_WINDOWED_ABI)
2938 {
2939 int regno;
2940 HOST_WIDE_INT offset;
2941
2942 if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024))
2943 {
2944 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2945 emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size -
2946 cfun->machine->callee_save_size));
2947 emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ?
2948 hard_frame_pointer_rtx : stack_pointer_rtx,
2949 tmp_reg));
2950 offset = cfun->machine->callee_save_size - UNITS_PER_WORD;
2951 }
2952 else
2953 {
2954 if (frame_pointer_needed)
2955 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
2956 offset = cfun->machine->current_frame_size - UNITS_PER_WORD;
2957 }
2958
2959 /* Prevent reordering of saved a0 update and loading it back from
2960 the save area. */
2961 if (crtl->calls_eh_return)
2962 emit_insn (gen_blockage ());
2963
2964 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
2965 {
2966 if (xtensa_call_save_reg(regno))
2967 {
2968 rtx x = gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (offset));
2969
2970 offset -= UNITS_PER_WORD;
2971 emit_move_insn (gen_rtx_REG (SImode, regno),
2972 gen_frame_mem (SImode, x));
2973 }
2974 }
2975
2976 if (cfun->machine->current_frame_size > 0)
2977 {
2978 if (frame_pointer_needed || /* always reachable with addi */
2979 cfun->machine->current_frame_size > 1024 ||
2980 cfun->machine->current_frame_size <= 127)
2981 {
2982 if (cfun->machine->current_frame_size <= 127)
2983 offset = cfun->machine->current_frame_size;
2984 else
2985 offset = cfun->machine->callee_save_size;
2986
2987 emit_insn (gen_addsi3 (stack_pointer_rtx,
2988 stack_pointer_rtx,
2989 GEN_INT (offset)));
2990 }
2991 else
2992 {
2993 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
2994 emit_move_insn (tmp_reg,
2995 GEN_INT (cfun->machine->current_frame_size));
2996 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
2997 tmp_reg));
2998 }
2999 }
3000
3001 if (crtl->calls_eh_return)
3002 emit_insn (gen_add3_insn (stack_pointer_rtx,
3003 stack_pointer_rtx,
3004 EH_RETURN_STACKADJ_RTX));
3005 }
3006 cfun->machine->epilogue_done = true;
3007 emit_jump_insn (gen_return ());
3008 }
3009
3010 bool
xtensa_use_return_instruction_p(void)3011 xtensa_use_return_instruction_p (void)
3012 {
3013 if (!reload_completed)
3014 return false;
3015 if (TARGET_WINDOWED_ABI)
3016 return true;
3017 if (compute_frame_size (get_frame_size ()) == 0)
3018 return true;
3019 return cfun->machine->epilogue_done;
3020 }
3021
3022 void
xtensa_set_return_address(rtx address,rtx scratch)3023 xtensa_set_return_address (rtx address, rtx scratch)
3024 {
3025 HOST_WIDE_INT total_size = compute_frame_size (get_frame_size ());
3026 rtx frame = frame_pointer_needed ?
3027 hard_frame_pointer_rtx : stack_pointer_rtx;
3028 rtx a0_addr = plus_constant (Pmode, frame,
3029 total_size - UNITS_PER_WORD);
3030 rtx note = gen_rtx_SET (gen_frame_mem (SImode, a0_addr),
3031 gen_rtx_REG (SImode, A0_REG));
3032 rtx insn;
3033
3034 if (total_size > 1024) {
3035 emit_move_insn (scratch, GEN_INT (total_size - UNITS_PER_WORD));
3036 emit_insn (gen_addsi3 (scratch, frame, scratch));
3037 a0_addr = scratch;
3038 }
3039
3040 insn = emit_move_insn (gen_frame_mem (SImode, a0_addr), address);
3041 RTX_FRAME_RELATED_P (insn) = 1;
3042 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note);
3043 }
3044
3045 rtx
xtensa_return_addr(int count,rtx frame)3046 xtensa_return_addr (int count, rtx frame)
3047 {
3048 rtx result, retaddr, curaddr, label;
3049
3050 if (!TARGET_WINDOWED_ABI)
3051 {
3052 if (count != 0)
3053 return const0_rtx;
3054
3055 return get_hard_reg_initial_val (Pmode, A0_REG);
3056 }
3057
3058 if (count == -1)
3059 retaddr = gen_rtx_REG (Pmode, A0_REG);
3060 else
3061 {
3062 rtx addr = plus_constant (Pmode, frame, -4 * UNITS_PER_WORD);
3063 addr = memory_address (Pmode, addr);
3064 retaddr = gen_reg_rtx (Pmode);
3065 emit_move_insn (retaddr, gen_rtx_MEM (Pmode, addr));
3066 }
3067
3068 /* The 2 most-significant bits of the return address on Xtensa hold
3069 the register window size. To get the real return address, these
3070 bits must be replaced with the high bits from some address in the
3071 code. */
3072
3073 /* Get the 2 high bits of a local label in the code. */
3074 curaddr = gen_reg_rtx (Pmode);
3075 label = gen_label_rtx ();
3076 emit_label (label);
3077 LABEL_PRESERVE_P (label) = 1;
3078 emit_move_insn (curaddr, gen_rtx_LABEL_REF (Pmode, label));
3079 emit_insn (gen_lshrsi3 (curaddr, curaddr, GEN_INT (30)));
3080 emit_insn (gen_ashlsi3 (curaddr, curaddr, GEN_INT (30)));
3081
3082 /* Clear the 2 high bits of the return address. */
3083 result = gen_reg_rtx (Pmode);
3084 emit_insn (gen_ashlsi3 (result, retaddr, GEN_INT (2)));
3085 emit_insn (gen_lshrsi3 (result, result, GEN_INT (2)));
3086
3087 /* Combine them to get the result. */
3088 emit_insn (gen_iorsi3 (result, result, curaddr));
3089 return result;
3090 }
3091
3092 /* Disable the use of word-sized or smaller complex modes for structures,
3093 and for function arguments in particular, where they cause problems with
3094 register a7. The xtensa_copy_incoming_a7 function assumes that there is
3095 a single reference to an argument in a7, but with small complex modes the
3096 real and imaginary components may be extracted separately, leading to two
3097 uses of the register, only one of which would be replaced. */
3098
3099 static bool
xtensa_member_type_forces_blk(const_tree,machine_mode mode)3100 xtensa_member_type_forces_blk (const_tree, machine_mode mode)
3101 {
3102 return mode == CQImode || mode == CHImode;
3103 }
3104
3105 /* Create the va_list data type.
3106
3107 This structure is set up by __builtin_saveregs. The __va_reg field
3108 points to a stack-allocated region holding the contents of the
3109 incoming argument registers. The __va_ndx field is an index
3110 initialized to the position of the first unnamed (variable)
3111 argument. This same index is also used to address the arguments
3112 passed in memory. Thus, the __va_stk field is initialized to point
3113 to the position of the first argument in memory offset to account
3114 for the arguments passed in registers and to account for the size
3115 of the argument registers not being 16-byte aligned. E.G., there
3116 are 6 argument registers of 4 bytes each, but we want the __va_ndx
3117 for the first stack argument to have the maximal alignment of 16
3118 bytes, so we offset the __va_stk address by 32 bytes so that
3119 __va_stk[32] references the first argument on the stack. */
3120
3121 static tree
xtensa_build_builtin_va_list(void)3122 xtensa_build_builtin_va_list (void)
3123 {
3124 tree f_stk, f_reg, f_ndx, record, type_decl;
3125
3126 record = (*lang_hooks.types.make_type) (RECORD_TYPE);
3127 type_decl = build_decl (BUILTINS_LOCATION,
3128 TYPE_DECL, get_identifier ("__va_list_tag"), record);
3129
3130 f_stk = build_decl (BUILTINS_LOCATION,
3131 FIELD_DECL, get_identifier ("__va_stk"),
3132 ptr_type_node);
3133 f_reg = build_decl (BUILTINS_LOCATION,
3134 FIELD_DECL, get_identifier ("__va_reg"),
3135 ptr_type_node);
3136 f_ndx = build_decl (BUILTINS_LOCATION,
3137 FIELD_DECL, get_identifier ("__va_ndx"),
3138 integer_type_node);
3139
3140 DECL_FIELD_CONTEXT (f_stk) = record;
3141 DECL_FIELD_CONTEXT (f_reg) = record;
3142 DECL_FIELD_CONTEXT (f_ndx) = record;
3143
3144 TYPE_STUB_DECL (record) = type_decl;
3145 TYPE_NAME (record) = type_decl;
3146 TYPE_FIELDS (record) = f_stk;
3147 DECL_CHAIN (f_stk) = f_reg;
3148 DECL_CHAIN (f_reg) = f_ndx;
3149
3150 layout_type (record);
3151 return record;
3152 }
3153
3154
3155 /* Save the incoming argument registers on the stack. Returns the
3156 address of the saved registers. */
3157
3158 static rtx
xtensa_builtin_saveregs(void)3159 xtensa_builtin_saveregs (void)
3160 {
3161 rtx gp_regs;
3162 int arg_words = crtl->args.info.arg_words;
3163 int gp_left = MAX_ARGS_IN_REGISTERS - arg_words;
3164
3165 if (gp_left <= 0)
3166 return const0_rtx;
3167
3168 /* Allocate the general-purpose register space. */
3169 gp_regs = assign_stack_local
3170 (BLKmode, MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD, -1);
3171 set_mem_alias_set (gp_regs, get_varargs_alias_set ());
3172
3173 /* Now store the incoming registers. */
3174 cfun->machine->need_a7_copy = TARGET_WINDOWED_ABI;
3175 cfun->machine->vararg_a7 = true;
3176 move_block_from_reg (GP_ARG_FIRST + arg_words,
3177 adjust_address (gp_regs, BLKmode,
3178 arg_words * UNITS_PER_WORD),
3179 gp_left);
3180 if (cfun->machine->vararg_a7_copy != 0)
3181 emit_insn_before (cfun->machine->vararg_a7_copy, get_insns ());
3182
3183 return XEXP (gp_regs, 0);
3184 }
3185
3186
3187 /* Implement `va_start' for varargs and stdarg. We look at the
3188 current function to fill in an initial va_list. */
3189
3190 static void
xtensa_va_start(tree valist,rtx nextarg ATTRIBUTE_UNUSED)3191 xtensa_va_start (tree valist, rtx nextarg ATTRIBUTE_UNUSED)
3192 {
3193 tree f_stk, stk;
3194 tree f_reg, reg;
3195 tree f_ndx, ndx;
3196 tree t, u;
3197 int arg_words;
3198
3199 arg_words = crtl->args.info.arg_words;
3200
3201 f_stk = TYPE_FIELDS (va_list_type_node);
3202 f_reg = DECL_CHAIN (f_stk);
3203 f_ndx = DECL_CHAIN (f_reg);
3204
3205 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist, f_stk, NULL_TREE);
3206 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
3207 f_reg, NULL_TREE);
3208 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
3209 f_ndx, NULL_TREE);
3210
3211 /* Call __builtin_saveregs; save the result in __va_reg */
3212 u = make_tree (sizetype, expand_builtin_saveregs ());
3213 u = fold_convert (ptr_type_node, u);
3214 t = build2 (MODIFY_EXPR, ptr_type_node, reg, u);
3215 TREE_SIDE_EFFECTS (t) = 1;
3216 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3217
3218 /* Set the __va_stk member to ($arg_ptr - 32). */
3219 u = make_tree (ptr_type_node, virtual_incoming_args_rtx);
3220 u = fold_build_pointer_plus_hwi (u, -32);
3221 t = build2 (MODIFY_EXPR, ptr_type_node, stk, u);
3222 TREE_SIDE_EFFECTS (t) = 1;
3223 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3224
3225 /* Set the __va_ndx member. If the first variable argument is on
3226 the stack, adjust __va_ndx by 2 words to account for the extra
3227 alignment offset for __va_stk. */
3228 if (arg_words >= MAX_ARGS_IN_REGISTERS)
3229 arg_words += 2;
3230 t = build2 (MODIFY_EXPR, integer_type_node, ndx,
3231 build_int_cst (integer_type_node, arg_words * UNITS_PER_WORD));
3232 TREE_SIDE_EFFECTS (t) = 1;
3233 expand_expr (t, const0_rtx, VOIDmode, EXPAND_NORMAL);
3234 }
3235
3236
3237 /* Implement `va_arg'. */
3238
3239 static tree
xtensa_gimplify_va_arg_expr(tree valist,tree type,gimple_seq * pre_p,gimple_seq * post_p ATTRIBUTE_UNUSED)3240 xtensa_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p,
3241 gimple_seq *post_p ATTRIBUTE_UNUSED)
3242 {
3243 tree f_stk, stk;
3244 tree f_reg, reg;
3245 tree f_ndx, ndx;
3246 tree type_size, array, orig_ndx, addr, size, va_size, t;
3247 tree lab_false, lab_over, lab_false2;
3248 bool indirect;
3249
3250 indirect = pass_va_arg_by_reference (type);
3251 if (indirect)
3252 type = build_pointer_type (type);
3253
3254 /* Handle complex values as separate real and imaginary parts. */
3255 if (TREE_CODE (type) == COMPLEX_TYPE)
3256 {
3257 tree real_part, imag_part;
3258
3259 real_part = xtensa_gimplify_va_arg_expr (valist, TREE_TYPE (type),
3260 pre_p, NULL);
3261 real_part = get_initialized_tmp_var (real_part, pre_p, NULL);
3262
3263 imag_part = xtensa_gimplify_va_arg_expr (unshare_expr (valist),
3264 TREE_TYPE (type),
3265 pre_p, NULL);
3266 imag_part = get_initialized_tmp_var (imag_part, pre_p, NULL);
3267
3268 return build2 (COMPLEX_EXPR, type, real_part, imag_part);
3269 }
3270
3271 f_stk = TYPE_FIELDS (va_list_type_node);
3272 f_reg = DECL_CHAIN (f_stk);
3273 f_ndx = DECL_CHAIN (f_reg);
3274
3275 stk = build3 (COMPONENT_REF, TREE_TYPE (f_stk), valist,
3276 f_stk, NULL_TREE);
3277 reg = build3 (COMPONENT_REF, TREE_TYPE (f_reg), unshare_expr (valist),
3278 f_reg, NULL_TREE);
3279 ndx = build3 (COMPONENT_REF, TREE_TYPE (f_ndx), unshare_expr (valist),
3280 f_ndx, NULL_TREE);
3281
3282 type_size = size_in_bytes (type);
3283 va_size = round_up (type_size, UNITS_PER_WORD);
3284 gimplify_expr (&va_size, pre_p, NULL, is_gimple_val, fb_rvalue);
3285
3286
3287 /* First align __va_ndx if necessary for this arg:
3288
3289 orig_ndx = (AP).__va_ndx;
3290 if (__alignof__ (TYPE) > 4 )
3291 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
3292 & -__alignof__ (TYPE)); */
3293
3294 orig_ndx = get_initialized_tmp_var (ndx, pre_p, NULL);
3295
3296 if (TYPE_ALIGN (type) > BITS_PER_WORD)
3297 {
3298 int align = MIN (TYPE_ALIGN (type), STACK_BOUNDARY) / BITS_PER_UNIT;
3299
3300 t = build2 (PLUS_EXPR, integer_type_node, unshare_expr (orig_ndx),
3301 build_int_cst (integer_type_node, align - 1));
3302 t = build2 (BIT_AND_EXPR, integer_type_node, t,
3303 build_int_cst (integer_type_node, -align));
3304 gimplify_assign (unshare_expr (orig_ndx), t, pre_p);
3305 }
3306
3307
3308 /* Increment __va_ndx to point past the argument:
3309
3310 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
3311
3312 t = fold_convert (integer_type_node, va_size);
3313 t = build2 (PLUS_EXPR, integer_type_node, orig_ndx, t);
3314 gimplify_assign (unshare_expr (ndx), t, pre_p);
3315
3316
3317 /* Check if the argument is in registers:
3318
3319 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
3320 && !must_pass_in_stack (type))
3321 __array = (AP).__va_reg; */
3322
3323 array = create_tmp_var (ptr_type_node);
3324
3325 lab_over = NULL;
3326 if (!must_pass_va_arg_in_stack (type))
3327 {
3328 lab_false = create_artificial_label (UNKNOWN_LOCATION);
3329 lab_over = create_artificial_label (UNKNOWN_LOCATION);
3330
3331 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (ndx),
3332 build_int_cst (integer_type_node,
3333 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
3334 t = build3 (COND_EXPR, void_type_node, t,
3335 build1 (GOTO_EXPR, void_type_node, lab_false),
3336 NULL_TREE);
3337 gimplify_and_add (t, pre_p);
3338
3339 gimplify_assign (unshare_expr (array), reg, pre_p);
3340
3341 t = build1 (GOTO_EXPR, void_type_node, lab_over);
3342 gimplify_and_add (t, pre_p);
3343
3344 t = build1 (LABEL_EXPR, void_type_node, lab_false);
3345 gimplify_and_add (t, pre_p);
3346 }
3347
3348
3349 /* ...otherwise, the argument is on the stack (never split between
3350 registers and the stack -- change __va_ndx if necessary):
3351
3352 else
3353 {
3354 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
3355 (AP).__va_ndx = 32 + __va_size (TYPE);
3356 __array = (AP).__va_stk;
3357 } */
3358
3359 lab_false2 = create_artificial_label (UNKNOWN_LOCATION);
3360
3361 t = build2 (GT_EXPR, boolean_type_node, unshare_expr (orig_ndx),
3362 build_int_cst (integer_type_node,
3363 MAX_ARGS_IN_REGISTERS * UNITS_PER_WORD));
3364 t = build3 (COND_EXPR, void_type_node, t,
3365 build1 (GOTO_EXPR, void_type_node, lab_false2),
3366 NULL_TREE);
3367 gimplify_and_add (t, pre_p);
3368
3369 t = size_binop (PLUS_EXPR, unshare_expr (va_size), size_int (32));
3370 t = fold_convert (integer_type_node, t);
3371 gimplify_assign (unshare_expr (ndx), t, pre_p);
3372
3373 t = build1 (LABEL_EXPR, void_type_node, lab_false2);
3374 gimplify_and_add (t, pre_p);
3375
3376 gimplify_assign (array, stk, pre_p);
3377
3378 if (lab_over)
3379 {
3380 t = build1 (LABEL_EXPR, void_type_node, lab_over);
3381 gimplify_and_add (t, pre_p);
3382 }
3383
3384
3385 /* Given the base array pointer (__array) and index to the subsequent
3386 argument (__va_ndx), find the address:
3387
3388 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
3389 ? sizeof (TYPE)
3390 : __va_size (TYPE))
3391
3392 The results are endian-dependent because values smaller than one word
3393 are aligned differently. */
3394
3395
3396 if (BYTES_BIG_ENDIAN && TREE_CODE (type_size) == INTEGER_CST)
3397 {
3398 t = fold_build2 (GE_EXPR, boolean_type_node, unshare_expr (type_size),
3399 size_int (PARM_BOUNDARY / BITS_PER_UNIT));
3400 t = fold_build3 (COND_EXPR, sizetype, t, unshare_expr (va_size),
3401 unshare_expr (type_size));
3402 size = t;
3403 }
3404 else
3405 size = unshare_expr (va_size);
3406
3407 t = fold_convert (sizetype, unshare_expr (ndx));
3408 t = build2 (MINUS_EXPR, sizetype, t, size);
3409 addr = fold_build_pointer_plus (unshare_expr (array), t);
3410
3411 addr = fold_convert (build_pointer_type (type), addr);
3412 if (indirect)
3413 addr = build_va_arg_indirect_ref (addr);
3414 return build_va_arg_indirect_ref (addr);
3415 }
3416
3417
3418 /* Builtins. */
3419
3420 enum xtensa_builtin
3421 {
3422 XTENSA_BUILTIN_UMULSIDI3,
3423 XTENSA_BUILTIN_max
3424 };
3425
3426
3427 static void
xtensa_init_builtins(void)3428 xtensa_init_builtins (void)
3429 {
3430 tree ftype, decl;
3431
3432 ftype = build_function_type_list (unsigned_intDI_type_node,
3433 unsigned_intSI_type_node,
3434 unsigned_intSI_type_node, NULL_TREE);
3435
3436 decl = add_builtin_function ("__builtin_umulsidi3", ftype,
3437 XTENSA_BUILTIN_UMULSIDI3, BUILT_IN_MD,
3438 "__umulsidi3", NULL_TREE);
3439 TREE_NOTHROW (decl) = 1;
3440 TREE_READONLY (decl) = 1;
3441 }
3442
3443
3444 static tree
xtensa_fold_builtin(tree fndecl,int n_args ATTRIBUTE_UNUSED,tree * args,bool ignore ATTRIBUTE_UNUSED)3445 xtensa_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *args,
3446 bool ignore ATTRIBUTE_UNUSED)
3447 {
3448 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
3449 tree arg0, arg1;
3450
3451 switch (fcode)
3452 {
3453 case XTENSA_BUILTIN_UMULSIDI3:
3454 arg0 = args[0];
3455 arg1 = args[1];
3456 if ((TREE_CODE (arg0) == INTEGER_CST && TREE_CODE (arg1) == INTEGER_CST)
3457 || TARGET_MUL32_HIGH)
3458 return fold_build2 (MULT_EXPR, unsigned_intDI_type_node,
3459 fold_convert (unsigned_intDI_type_node, arg0),
3460 fold_convert (unsigned_intDI_type_node, arg1));
3461 break;
3462
3463 default:
3464 internal_error ("bad builtin code");
3465 break;
3466 }
3467
3468 return NULL;
3469 }
3470
3471
3472 static rtx
xtensa_expand_builtin(tree exp,rtx target,rtx subtarget ATTRIBUTE_UNUSED,machine_mode mode ATTRIBUTE_UNUSED,int ignore)3473 xtensa_expand_builtin (tree exp, rtx target,
3474 rtx subtarget ATTRIBUTE_UNUSED,
3475 machine_mode mode ATTRIBUTE_UNUSED,
3476 int ignore)
3477 {
3478 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
3479 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
3480
3481 switch (fcode)
3482 {
3483 case XTENSA_BUILTIN_UMULSIDI3:
3484 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3485 __umulsidi3 function when the Xtensa configuration can directly
3486 implement it. If not, just call the function. */
3487 return expand_call (exp, target, ignore);
3488
3489 default:
3490 internal_error ("bad builtin code");
3491 }
3492 return NULL_RTX;
3493 }
3494
3495 /* Worker function for TARGET_PREFERRED_RELOAD_CLASS. */
3496
3497 static reg_class_t
xtensa_preferred_reload_class(rtx x,reg_class_t rclass)3498 xtensa_preferred_reload_class (rtx x, reg_class_t rclass)
3499 {
3500 if (CONSTANT_P (x) && CONST_DOUBLE_P (x))
3501 return NO_REGS;
3502
3503 /* Don't use the stack pointer or hard frame pointer for reloads!
3504 The hard frame pointer would normally be OK except that it may
3505 briefly hold an incoming argument in the prologue, and reload
3506 won't know that it is live because the hard frame pointer is
3507 treated specially. */
3508
3509 if (rclass == AR_REGS || rclass == GR_REGS)
3510 return RL_REGS;
3511
3512 return rclass;
3513 }
3514
3515 /* Worker function for TARGET_PREFERRED_OUTPUT_RELOAD_CLASS. */
3516
3517 static reg_class_t
xtensa_preferred_output_reload_class(rtx x ATTRIBUTE_UNUSED,reg_class_t rclass)3518 xtensa_preferred_output_reload_class (rtx x ATTRIBUTE_UNUSED,
3519 reg_class_t rclass)
3520 {
3521 /* Don't use the stack pointer or hard frame pointer for reloads!
3522 The hard frame pointer would normally be OK except that it may
3523 briefly hold an incoming argument in the prologue, and reload
3524 won't know that it is live because the hard frame pointer is
3525 treated specially. */
3526
3527 if (rclass == AR_REGS || rclass == GR_REGS)
3528 return RL_REGS;
3529
3530 return rclass;
3531 }
3532
3533 /* Worker function for TARGET_SECONDARY_RELOAD. */
3534
3535 static reg_class_t
xtensa_secondary_reload(bool in_p,rtx x,reg_class_t rclass,machine_mode mode,secondary_reload_info * sri)3536 xtensa_secondary_reload (bool in_p, rtx x, reg_class_t rclass,
3537 machine_mode mode, secondary_reload_info *sri)
3538 {
3539 int regno;
3540
3541 if (in_p && constantpool_mem_p (x))
3542 {
3543 if (rclass == FP_REGS)
3544 return RL_REGS;
3545
3546 if (mode == QImode)
3547 sri->icode = CODE_FOR_reloadqi_literal;
3548 else if (mode == HImode)
3549 sri->icode = CODE_FOR_reloadhi_literal;
3550 }
3551
3552 regno = xt_true_regnum (x);
3553 if (ACC_REG_P (regno))
3554 return ((rclass == GR_REGS || rclass == RL_REGS) ? NO_REGS : RL_REGS);
3555 if (rclass == ACC_REG)
3556 return (GP_REG_P (regno) ? NO_REGS : RL_REGS);
3557
3558 return NO_REGS;
3559 }
3560
3561
3562 void
order_regs_for_local_alloc(void)3563 order_regs_for_local_alloc (void)
3564 {
3565 if (!leaf_function_p ())
3566 {
3567 static const int reg_nonleaf_alloc_order[FIRST_PSEUDO_REGISTER] =
3568 REG_ALLOC_ORDER;
3569 static const int reg_nonleaf_alloc_order_call0[FIRST_PSEUDO_REGISTER] =
3570 {
3571 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 12, 13, 14, 15,
3572 18,
3573 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
3574 0, 1, 16, 17,
3575 35,
3576 };
3577
3578 memcpy (reg_alloc_order, TARGET_WINDOWED_ABI ?
3579 reg_nonleaf_alloc_order : reg_nonleaf_alloc_order_call0,
3580 FIRST_PSEUDO_REGISTER * sizeof (int));
3581 }
3582 else
3583 {
3584 int i, num_arg_regs;
3585 int nxt = 0;
3586
3587 /* Use the AR registers in increasing order (skipping a0 and a1)
3588 but save the incoming argument registers for a last resort. */
3589 num_arg_regs = crtl->args.info.arg_words;
3590 if (num_arg_regs > MAX_ARGS_IN_REGISTERS)
3591 num_arg_regs = MAX_ARGS_IN_REGISTERS;
3592 for (i = GP_ARG_FIRST; i < 16 - num_arg_regs; i++)
3593 reg_alloc_order[nxt++] = i + num_arg_regs;
3594 for (i = 0; i < num_arg_regs; i++)
3595 reg_alloc_order[nxt++] = GP_ARG_FIRST + i;
3596
3597 /* List the coprocessor registers in order. */
3598 for (i = 0; i < BR_REG_NUM; i++)
3599 reg_alloc_order[nxt++] = BR_REG_FIRST + i;
3600
3601 /* List the FP registers in order for now. */
3602 for (i = 0; i < 16; i++)
3603 reg_alloc_order[nxt++] = FP_REG_FIRST + i;
3604
3605 /* GCC requires that we list *all* the registers.... */
3606 reg_alloc_order[nxt++] = 0; /* a0 = return address */
3607 reg_alloc_order[nxt++] = 1; /* a1 = stack pointer */
3608 reg_alloc_order[nxt++] = 16; /* pseudo frame pointer */
3609 reg_alloc_order[nxt++] = 17; /* pseudo arg pointer */
3610
3611 reg_alloc_order[nxt++] = ACC_REG_FIRST; /* MAC16 accumulator */
3612 }
3613 }
3614
3615
3616 /* Some Xtensa targets support multiple bss sections. If the section
3617 name ends with ".bss", add SECTION_BSS to the flags. */
3618
3619 static unsigned int
xtensa_multibss_section_type_flags(tree decl,const char * name,int reloc)3620 xtensa_multibss_section_type_flags (tree decl, const char *name, int reloc)
3621 {
3622 unsigned int flags = default_section_type_flags (decl, name, reloc);
3623 const char *suffix;
3624
3625 suffix = strrchr (name, '.');
3626 if (suffix && strcmp (suffix, ".bss") == 0)
3627 {
3628 if (!decl || (TREE_CODE (decl) == VAR_DECL
3629 && DECL_INITIAL (decl) == NULL_TREE))
3630 flags |= SECTION_BSS; /* @nobits */
3631 else
3632 warning (0, "only uninitialized variables can be placed in a "
3633 ".bss section");
3634 }
3635
3636 return flags;
3637 }
3638
3639
3640 /* The literal pool stays with the function. */
3641
3642 static section *
xtensa_select_rtx_section(machine_mode mode ATTRIBUTE_UNUSED,rtx x ATTRIBUTE_UNUSED,unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)3643 xtensa_select_rtx_section (machine_mode mode ATTRIBUTE_UNUSED,
3644 rtx x ATTRIBUTE_UNUSED,
3645 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED)
3646 {
3647 return function_section (current_function_decl);
3648 }
3649
3650 /* Worker function for TARGET_REGISTER_MOVE_COST. */
3651
3652 static int
xtensa_register_move_cost(machine_mode mode ATTRIBUTE_UNUSED,reg_class_t from,reg_class_t to)3653 xtensa_register_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3654 reg_class_t from, reg_class_t to)
3655 {
3656 if (from == to && from != BR_REGS && to != BR_REGS)
3657 return 2;
3658 else if (reg_class_subset_p (from, AR_REGS)
3659 && reg_class_subset_p (to, AR_REGS))
3660 return 2;
3661 else if (reg_class_subset_p (from, AR_REGS) && to == ACC_REG)
3662 return 3;
3663 else if (from == ACC_REG && reg_class_subset_p (to, AR_REGS))
3664 return 3;
3665 else
3666 return 10;
3667 }
3668
3669 /* Worker function for TARGET_MEMORY_MOVE_COST. */
3670
3671 static int
xtensa_memory_move_cost(machine_mode mode ATTRIBUTE_UNUSED,reg_class_t rclass ATTRIBUTE_UNUSED,bool in ATTRIBUTE_UNUSED)3672 xtensa_memory_move_cost (machine_mode mode ATTRIBUTE_UNUSED,
3673 reg_class_t rclass ATTRIBUTE_UNUSED,
3674 bool in ATTRIBUTE_UNUSED)
3675 {
3676 return 4;
3677 }
3678
3679 /* Compute a (partial) cost for rtx X. Return true if the complete
3680 cost has been computed, and false if subexpressions should be
3681 scanned. In either case, *TOTAL contains the cost result. */
3682
3683 static bool
xtensa_rtx_costs(rtx x,machine_mode mode,int outer_code,int opno ATTRIBUTE_UNUSED,int * total,bool speed ATTRIBUTE_UNUSED)3684 xtensa_rtx_costs (rtx x, machine_mode mode, int outer_code,
3685 int opno ATTRIBUTE_UNUSED,
3686 int *total, bool speed ATTRIBUTE_UNUSED)
3687 {
3688 int code = GET_CODE (x);
3689
3690 switch (code)
3691 {
3692 case CONST_INT:
3693 switch (outer_code)
3694 {
3695 case SET:
3696 if (xtensa_simm12b (INTVAL (x)))
3697 {
3698 *total = 4;
3699 return true;
3700 }
3701 break;
3702 case PLUS:
3703 if (xtensa_simm8 (INTVAL (x))
3704 || xtensa_simm8x256 (INTVAL (x)))
3705 {
3706 *total = 0;
3707 return true;
3708 }
3709 break;
3710 case AND:
3711 if (xtensa_mask_immediate (INTVAL (x)))
3712 {
3713 *total = 0;
3714 return true;
3715 }
3716 break;
3717 case COMPARE:
3718 if ((INTVAL (x) == 0) || xtensa_b4const (INTVAL (x)))
3719 {
3720 *total = 0;
3721 return true;
3722 }
3723 break;
3724 case ASHIFT:
3725 case ASHIFTRT:
3726 case LSHIFTRT:
3727 case ROTATE:
3728 case ROTATERT:
3729 /* No way to tell if X is the 2nd operand so be conservative. */
3730 default: break;
3731 }
3732 if (xtensa_simm12b (INTVAL (x)))
3733 *total = 5;
3734 else if (TARGET_CONST16)
3735 *total = COSTS_N_INSNS (2);
3736 else
3737 *total = 6;
3738 return true;
3739
3740 case CONST:
3741 case LABEL_REF:
3742 case SYMBOL_REF:
3743 if (TARGET_CONST16)
3744 *total = COSTS_N_INSNS (2);
3745 else
3746 *total = 5;
3747 return true;
3748
3749 case CONST_DOUBLE:
3750 if (TARGET_CONST16)
3751 *total = COSTS_N_INSNS (4);
3752 else
3753 *total = 7;
3754 return true;
3755
3756 case MEM:
3757 {
3758 int num_words =
3759 (GET_MODE_SIZE (mode) > UNITS_PER_WORD) ? 2 : 1;
3760
3761 if (memory_address_p (mode, XEXP ((x), 0)))
3762 *total = COSTS_N_INSNS (num_words);
3763 else
3764 *total = COSTS_N_INSNS (2*num_words);
3765 return true;
3766 }
3767
3768 case FFS:
3769 case CTZ:
3770 *total = COSTS_N_INSNS (TARGET_NSA ? 5 : 50);
3771 return true;
3772
3773 case CLZ:
3774 *total = COSTS_N_INSNS (TARGET_NSA ? 1 : 50);
3775 return true;
3776
3777 case NOT:
3778 *total = COSTS_N_INSNS (mode == DImode ? 3 : 2);
3779 return true;
3780
3781 case AND:
3782 case IOR:
3783 case XOR:
3784 if (mode == DImode)
3785 *total = COSTS_N_INSNS (2);
3786 else
3787 *total = COSTS_N_INSNS (1);
3788 return true;
3789
3790 case ASHIFT:
3791 case ASHIFTRT:
3792 case LSHIFTRT:
3793 if (mode == DImode)
3794 *total = COSTS_N_INSNS (50);
3795 else
3796 *total = COSTS_N_INSNS (1);
3797 return true;
3798
3799 case ABS:
3800 {
3801 if (mode == SFmode)
3802 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3803 else if (mode == DFmode)
3804 *total = COSTS_N_INSNS (50);
3805 else
3806 *total = COSTS_N_INSNS (4);
3807 return true;
3808 }
3809
3810 case PLUS:
3811 case MINUS:
3812 {
3813 if (mode == SFmode)
3814 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 1 : 50);
3815 else if (mode == DFmode || mode == DImode)
3816 *total = COSTS_N_INSNS (50);
3817 else
3818 *total = COSTS_N_INSNS (1);
3819 return true;
3820 }
3821
3822 case NEG:
3823 *total = COSTS_N_INSNS (mode == DImode ? 4 : 2);
3824 return true;
3825
3826 case MULT:
3827 {
3828 if (mode == SFmode)
3829 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT ? 4 : 50);
3830 else if (mode == DFmode)
3831 *total = COSTS_N_INSNS (50);
3832 else if (mode == DImode)
3833 *total = COSTS_N_INSNS (TARGET_MUL32_HIGH ? 10 : 50);
3834 else if (TARGET_MUL32)
3835 *total = COSTS_N_INSNS (4);
3836 else if (TARGET_MAC16)
3837 *total = COSTS_N_INSNS (16);
3838 else if (TARGET_MUL16)
3839 *total = COSTS_N_INSNS (12);
3840 else
3841 *total = COSTS_N_INSNS (50);
3842 return true;
3843 }
3844
3845 case DIV:
3846 case MOD:
3847 {
3848 if (mode == SFmode)
3849 {
3850 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV ? 8 : 50);
3851 return true;
3852 }
3853 else if (mode == DFmode)
3854 {
3855 *total = COSTS_N_INSNS (50);
3856 return true;
3857 }
3858 }
3859 /* Fall through. */
3860
3861 case UDIV:
3862 case UMOD:
3863 {
3864 if (mode == DImode)
3865 *total = COSTS_N_INSNS (50);
3866 else if (TARGET_DIV32)
3867 *total = COSTS_N_INSNS (32);
3868 else
3869 *total = COSTS_N_INSNS (50);
3870 return true;
3871 }
3872
3873 case SQRT:
3874 if (mode == SFmode)
3875 *total = COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT ? 8 : 50);
3876 else
3877 *total = COSTS_N_INSNS (50);
3878 return true;
3879
3880 case SMIN:
3881 case UMIN:
3882 case SMAX:
3883 case UMAX:
3884 *total = COSTS_N_INSNS (TARGET_MINMAX ? 1 : 50);
3885 return true;
3886
3887 case SIGN_EXTRACT:
3888 case SIGN_EXTEND:
3889 *total = COSTS_N_INSNS (TARGET_SEXT ? 1 : 2);
3890 return true;
3891
3892 case ZERO_EXTRACT:
3893 case ZERO_EXTEND:
3894 *total = COSTS_N_INSNS (1);
3895 return true;
3896
3897 default:
3898 return false;
3899 }
3900 }
3901
3902 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3903
3904 static bool
xtensa_return_in_memory(const_tree type,const_tree fntype ATTRIBUTE_UNUSED)3905 xtensa_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
3906 {
3907 return ((unsigned HOST_WIDE_INT) int_size_in_bytes (type)
3908 > 4 * UNITS_PER_WORD);
3909 }
3910
3911 /* Worker function for TARGET_FUNCTION_VALUE. */
3912
3913 rtx
xtensa_function_value(const_tree valtype,const_tree func ATTRIBUTE_UNUSED,bool outgoing)3914 xtensa_function_value (const_tree valtype, const_tree func ATTRIBUTE_UNUSED,
3915 bool outgoing)
3916 {
3917 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype)
3918 && TYPE_PRECISION (valtype) < BITS_PER_WORD)
3919 ? SImode : TYPE_MODE (valtype),
3920 outgoing ? GP_OUTGOING_RETURN : GP_RETURN);
3921 }
3922
3923 /* Worker function for TARGET_LIBCALL_VALUE. */
3924
3925 static rtx
xtensa_libcall_value(machine_mode mode,const_rtx fun ATTRIBUTE_UNUSED)3926 xtensa_libcall_value (machine_mode mode, const_rtx fun ATTRIBUTE_UNUSED)
3927 {
3928 return gen_rtx_REG ((GET_MODE_CLASS (mode) == MODE_INT
3929 && GET_MODE_SIZE (mode) < UNITS_PER_WORD)
3930 ? SImode : mode, GP_RETURN);
3931 }
3932
3933 /* Worker function TARGET_FUNCTION_VALUE_REGNO_P. */
3934
3935 static bool
xtensa_function_value_regno_p(const unsigned int regno)3936 xtensa_function_value_regno_p (const unsigned int regno)
3937 {
3938 return (regno == GP_RETURN);
3939 }
3940
3941 /* The static chain is passed in memory. Provide rtx giving 'mem'
3942 expressions that denote where they are stored. */
3943
3944 static rtx
xtensa_static_chain(const_tree ARG_UNUSED (fndecl_or_type),bool incoming_p)3945 xtensa_static_chain (const_tree ARG_UNUSED (fndecl_or_type), bool incoming_p)
3946 {
3947 if (TARGET_WINDOWED_ABI)
3948 {
3949 rtx base = incoming_p ? arg_pointer_rtx : stack_pointer_rtx;
3950 return gen_frame_mem (Pmode, plus_constant (Pmode, base,
3951 -5 * UNITS_PER_WORD));
3952 }
3953 else
3954 return gen_rtx_REG (Pmode, A8_REG);
3955 }
3956
3957
3958 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3959 instruction with a minimal stack frame in order to get some free
3960 registers. Once the actual call target is known, the proper stack frame
3961 size is extracted from the ENTRY instruction at the target and the
3962 current frame is adjusted to match. The trampoline then transfers
3963 control to the instruction following the ENTRY at the target. Note:
3964 this assumes that the target begins with an ENTRY instruction. */
3965
3966 static void
xtensa_asm_trampoline_template(FILE * stream)3967 xtensa_asm_trampoline_template (FILE *stream)
3968 {
3969 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
3970
3971 fprintf (stream, "\t.begin no-transform\n");
3972
3973 if (TARGET_WINDOWED_ABI)
3974 {
3975 fprintf (stream, "\tentry\tsp, %d\n", MIN_FRAME_SIZE);
3976
3977 if (use_call0)
3978 {
3979 /* Save the return address. */
3980 fprintf (stream, "\tmov\ta10, a0\n");
3981
3982 /* Use a CALL0 instruction to skip past the constants and in the
3983 process get the PC into A0. This allows PC-relative access to
3984 the constants without relying on L32R. */
3985 fprintf (stream, "\tcall0\t.Lskipconsts\n");
3986 }
3987 else
3988 fprintf (stream, "\tj\t.Lskipconsts\n");
3989
3990 fprintf (stream, "\t.align\t4\n");
3991 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
3992 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
3993 fprintf (stream, ".Lskipconsts:\n");
3994
3995 /* Load the static chain and function address from the trampoline. */
3996 if (use_call0)
3997 {
3998 fprintf (stream, "\taddi\ta0, a0, 3\n");
3999 fprintf (stream, "\tl32i\ta9, a0, 0\n");
4000 fprintf (stream, "\tl32i\ta8, a0, 4\n");
4001 }
4002 else
4003 {
4004 fprintf (stream, "\tl32r\ta9, .Lchainval\n");
4005 fprintf (stream, "\tl32r\ta8, .Lfnaddr\n");
4006 }
4007
4008 /* Store the static chain. */
4009 fprintf (stream, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE - 20);
4010
4011 /* Set the proper stack pointer value. */
4012 fprintf (stream, "\tl32i\ta9, a8, 0\n");
4013 fprintf (stream, "\textui\ta9, a9, %d, 12\n",
4014 TARGET_BIG_ENDIAN ? 8 : 12);
4015 fprintf (stream, "\tslli\ta9, a9, 3\n");
4016 fprintf (stream, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE);
4017 fprintf (stream, "\tsub\ta9, sp, a9\n");
4018 fprintf (stream, "\tmovsp\tsp, a9\n");
4019
4020 if (use_call0)
4021 /* Restore the return address. */
4022 fprintf (stream, "\tmov\ta0, a10\n");
4023
4024 /* Jump to the instruction following the ENTRY. */
4025 fprintf (stream, "\taddi\ta8, a8, 3\n");
4026 fprintf (stream, "\tjx\ta8\n");
4027
4028 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4029 if (use_call0)
4030 fprintf (stream, "\t.byte\t0\n");
4031 else
4032 fprintf (stream, "\tnop\n");
4033 }
4034 else
4035 {
4036 if (use_call0)
4037 {
4038 /* Save the return address. */
4039 fprintf (stream, "\tmov\ta10, a0\n");
4040
4041 /* Use a CALL0 instruction to skip past the constants and in the
4042 process get the PC into A0. This allows PC-relative access to
4043 the constants without relying on L32R. */
4044 fprintf (stream, "\tcall0\t.Lskipconsts\n");
4045 }
4046 else
4047 fprintf (stream, "\tj\t.Lskipconsts\n");
4048
4049 fprintf (stream, "\t.align\t4\n");
4050 fprintf (stream, ".Lchainval:%s0\n", integer_asm_op (4, TRUE));
4051 fprintf (stream, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE));
4052 fprintf (stream, ".Lskipconsts:\n");
4053
4054 /* Load the static chain and function address from the trampoline. */
4055 if (use_call0)
4056 {
4057 fprintf (stream, "\taddi\ta0, a0, 3\n");
4058 fprintf (stream, "\tl32i\ta8, a0, 0\n");
4059 fprintf (stream, "\tl32i\ta9, a0, 4\n");
4060 fprintf (stream, "\tmov\ta0, a10\n");
4061 }
4062 else
4063 {
4064 fprintf (stream, "\tl32r\ta8, .Lchainval\n");
4065 fprintf (stream, "\tl32r\ta9, .Lfnaddr\n");
4066 }
4067 fprintf (stream, "\tjx\ta9\n");
4068
4069 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
4070 if (use_call0)
4071 fprintf (stream, "\t.byte\t0\n");
4072 else
4073 fprintf (stream, "\tnop\n");
4074 }
4075 fprintf (stream, "\t.end no-transform\n");
4076 }
4077
4078 static void
xtensa_trampoline_init(rtx m_tramp,tree fndecl,rtx chain)4079 xtensa_trampoline_init (rtx m_tramp, tree fndecl, rtx chain)
4080 {
4081 rtx func = XEXP (DECL_RTL (fndecl), 0);
4082 bool use_call0 = (TARGET_CONST16 || TARGET_ABSOLUTE_LITERALS);
4083 int chain_off;
4084 int func_off;
4085
4086 if (TARGET_WINDOWED_ABI)
4087 {
4088 chain_off = use_call0 ? 12 : 8;
4089 func_off = use_call0 ? 16 : 12;
4090 }
4091 else
4092 {
4093 chain_off = use_call0 ? 8 : 4;
4094 func_off = use_call0 ? 12 : 8;
4095 }
4096
4097 emit_block_move (m_tramp, assemble_trampoline_template (),
4098 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4099
4100 emit_move_insn (adjust_address (m_tramp, SImode, chain_off), chain);
4101 emit_move_insn (adjust_address (m_tramp, SImode, func_off), func);
4102 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__xtensa_sync_caches"),
4103 LCT_NORMAL, VOIDmode, XEXP (m_tramp, 0), Pmode);
4104 }
4105
4106 /* Implement TARGET_LEGITIMATE_CONSTANT_P. */
4107
4108 static bool
xtensa_legitimate_constant_p(machine_mode mode ATTRIBUTE_UNUSED,rtx x)4109 xtensa_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
4110 {
4111 return !xtensa_tls_referenced_p (x);
4112 }
4113
4114 /* Implement TARGET_CAN_USE_DOLOOP_P. */
4115
4116 static bool
xtensa_can_use_doloop_p(const widest_int &,const widest_int &,unsigned int loop_depth,bool entered_at_top)4117 xtensa_can_use_doloop_p (const widest_int &, const widest_int &,
4118 unsigned int loop_depth, bool entered_at_top)
4119 {
4120 /* Considering limitations in the hardware, only use doloop
4121 for innermost loops which must be entered from the top. */
4122 if (loop_depth > 1 || !entered_at_top)
4123 return false;
4124
4125 return true;
4126 }
4127
4128 /* NULL if INSN insn is valid within a low-overhead loop.
4129 Otherwise return why doloop cannot be applied. */
4130
4131 static const char *
xtensa_invalid_within_doloop(const rtx_insn * insn)4132 xtensa_invalid_within_doloop (const rtx_insn *insn)
4133 {
4134 if (CALL_P (insn))
4135 return "Function call in the loop.";
4136
4137 if (JUMP_P (insn) && INSN_CODE (insn) == CODE_FOR_return)
4138 return "Return from a call instruction in the loop.";
4139
4140 return NULL;
4141 }
4142
4143 /* Optimize LOOP. */
4144
4145 static bool
hwloop_optimize(hwloop_info loop)4146 hwloop_optimize (hwloop_info loop)
4147 {
4148 int i;
4149 edge entry_edge;
4150 basic_block entry_bb;
4151 rtx iter_reg;
4152 rtx_insn *insn, *seq, *entry_after;
4153
4154 if (loop->depth > 1)
4155 {
4156 if (dump_file)
4157 fprintf (dump_file, ";; loop %d is not innermost\n",
4158 loop->loop_no);
4159 return false;
4160 }
4161
4162 if (!loop->incoming_dest)
4163 {
4164 if (dump_file)
4165 fprintf (dump_file, ";; loop %d has more than one entry\n",
4166 loop->loop_no);
4167 return false;
4168 }
4169
4170 if (loop->incoming_dest != loop->head)
4171 {
4172 if (dump_file)
4173 fprintf (dump_file, ";; loop %d is not entered from head\n",
4174 loop->loop_no);
4175 return false;
4176 }
4177
4178 if (loop->has_call || loop->has_asm)
4179 {
4180 if (dump_file)
4181 fprintf (dump_file, ";; loop %d has invalid insn\n",
4182 loop->loop_no);
4183 return false;
4184 }
4185
4186 /* Scan all the blocks to make sure they don't use iter_reg. */
4187 if (loop->iter_reg_used || loop->iter_reg_used_outside)
4188 {
4189 if (dump_file)
4190 fprintf (dump_file, ";; loop %d uses iterator\n",
4191 loop->loop_no);
4192 return false;
4193 }
4194
4195 /* Check if start_label appears before doloop_end. */
4196 insn = loop->start_label;
4197 while (insn && insn != loop->loop_end)
4198 insn = NEXT_INSN (insn);
4199
4200 if (!insn)
4201 {
4202 if (dump_file)
4203 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
4204 loop->loop_no);
4205 return false;
4206 }
4207
4208 /* Get the loop iteration register. */
4209 iter_reg = loop->iter_reg;
4210
4211 gcc_assert (REG_P (iter_reg));
4212
4213 entry_edge = NULL;
4214
4215 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
4216 if (entry_edge->flags & EDGE_FALLTHRU)
4217 break;
4218
4219 if (entry_edge == NULL)
4220 return false;
4221
4222 /* Place the zero_cost_loop_start instruction before the loop. */
4223 entry_bb = entry_edge->src;
4224
4225 start_sequence ();
4226
4227 insn = emit_insn (gen_zero_cost_loop_start (loop->iter_reg,
4228 loop->start_label,
4229 loop->iter_reg));
4230
4231 seq = get_insns ();
4232
4233 entry_after = BB_END (entry_bb);
4234 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
4235 || !entry_after)
4236 {
4237 basic_block new_bb;
4238 edge e;
4239 edge_iterator ei;
4240
4241 emit_insn_before (seq, BB_HEAD (loop->head));
4242 seq = emit_label_before (gen_label_rtx (), seq);
4243 new_bb = create_basic_block (seq, insn, entry_bb);
4244 FOR_EACH_EDGE (e, ei, loop->incoming)
4245 {
4246 if (!(e->flags & EDGE_FALLTHRU))
4247 redirect_edge_and_branch_force (e, new_bb);
4248 else
4249 redirect_edge_succ (e, new_bb);
4250 }
4251
4252 make_edge (new_bb, loop->head, 0);
4253 }
4254 else
4255 {
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);
4260
4261 emit_insn_after (seq, entry_after);
4262 }
4263
4264 end_sequence ();
4265
4266 return true;
4267 }
4268
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. */
4272
4273 static void
hwloop_fail(hwloop_info loop)4274 hwloop_fail (hwloop_info loop)
4275 {
4276 rtx test;
4277 rtx_insn *insn = loop->loop_end;
4278
4279 emit_insn_before (gen_addsi3 (loop->iter_reg,
4280 loop->iter_reg,
4281 constm1_rtx),
4282 loop->loop_end);
4283
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);
4289
4290 JUMP_LABEL (insn) = loop->start_label;
4291 LABEL_NUSES (loop->start_label)++;
4292 delete_insn (loop->loop_end);
4293 }
4294
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. */
4298
4299 static rtx
hwloop_pattern_reg(rtx_insn * insn)4300 hwloop_pattern_reg (rtx_insn *insn)
4301 {
4302 rtx reg;
4303
4304 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
4305 return NULL_RTX;
4306
4307 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
4308 if (!REG_P (reg))
4309 return NULL_RTX;
4310
4311 return reg;
4312 }
4313
4314
4315 static struct hw_doloop_hooks xtensa_doloop_hooks =
4316 {
4317 hwloop_pattern_reg,
4318 hwloop_optimize,
4319 hwloop_fail
4320 };
4321
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. */
4325
4326 static void
xtensa_reorg_loops(void)4327 xtensa_reorg_loops (void)
4328 {
4329 if (TARGET_LOOPS)
4330 reorg_loops (false, &xtensa_doloop_hooks);
4331 }
4332
4333 /* Implement the TARGET_MACHINE_DEPENDENT_REORG pass. */
4334
4335 static void
xtensa_reorg(void)4336 xtensa_reorg (void)
4337 {
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 ();
4341
4342 df_analyze ();
4343
4344 /* Doloop optimization. */
4345 xtensa_reorg_loops ();
4346 }
4347
4348 /* Update register usage after having seen the compiler flags. */
4349
4350 static void
xtensa_conditional_register_usage(void)4351 xtensa_conditional_register_usage (void)
4352 {
4353 unsigned i, c_mask;
4354
4355 c_mask = TARGET_WINDOWED_ABI ? (1 << 1) : (1 << 2);
4356
4357 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
4358 {
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);
4363 }
4364
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);
4368 }
4369
4370 /* Map hard register number to register class */
4371
xtensa_regno_to_class(int regno)4372 enum reg_class xtensa_regno_to_class (int regno)
4373 {
4374 static const enum reg_class regno_to_class[FIRST_PSEUDO_REGISTER] =
4375 {
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,
4386 };
4387
4388 if (regno == HARD_FRAME_POINTER_REGNUM)
4389 return GR_REGS;
4390 else
4391 return regno_to_class[regno];
4392 }
4393
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. */
4399
4400 static HOST_WIDE_INT
xtensa_constant_alignment(const_tree exp,HOST_WIDE_INT align)4401 xtensa_constant_alignment (const_tree exp, HOST_WIDE_INT align)
4402 {
4403 if ((TREE_CODE (exp) == STRING_CST || TREE_CODE (exp) == CONSTRUCTOR)
4404 && !optimize_size)
4405 return MAX (align, BITS_PER_WORD);
4406 return align;
4407 }
4408
4409 /* Implement TARGET_STARTING_FRAME_OFFSET. */
4410
4411 static HOST_WIDE_INT
xtensa_starting_frame_offset(void)4412 xtensa_starting_frame_offset (void)
4413 {
4414 if (FRAME_GROWS_DOWNWARD)
4415 return 0;
4416 return crtl->outgoing_args_size;
4417 }
4418
4419 /* Implement TARGET_ASAN_SHADOW_OFFSET. */
4420
4421 static unsigned HOST_WIDE_INT
xtensa_asan_shadow_offset(void)4422 xtensa_asan_shadow_offset (void)
4423 {
4424 return HOST_WIDE_INT_UC (0x10000000);
4425 }
4426
4427 #include "gt-xtensa.h"
4428