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