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