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