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