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