1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
3 Free Software Foundation, Inc.
4 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
30 #include "insn-config.h"
31 #include "conditions.h"
32 #include "insn-flags.h"
33 #include "insn-attr.h"
34 #include "insn-codes.h"
48 #include "target-def.h"
49 #include "langhooks.h"
54 /* Enumeration for all of the relational tests, so that we can build
55 arrays indexed by the test type, and not worry about the order
73 /* Array giving truth value on whether or not a given hard register
74 can support a given mode. */
75 char xtensa_hard_regno_mode_ok
[(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
77 /* Current frame size calculated by compute_frame_size. */
78 unsigned xtensa_current_frame_size
;
80 /* Largest block move to handle in-line. */
81 #define LARGEST_MOVE_RATIO 15
83 /* Define the structure for the machine field in struct function. */
84 struct GTY(()) machine_function
86 int accesses_prev_frame
;
90 rtx set_frame_ptr_insn
;
93 /* Vector, indexed by hard register number, which contains 1 for a
94 register that is allowable in a candidate for leaf function
97 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
99 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
101 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105 /* Map hard register number to register class */
106 const enum reg_class xtensa_regno_to_class
[FIRST_PSEUDO_REGISTER
] =
108 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
109 RL_REGS
, RL_REGS
, RL_REGS
, GR_REGS
,
110 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
111 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
112 AR_REGS
, AR_REGS
, BR_REGS
,
113 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
114 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
115 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
116 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
120 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
121 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
, int *);
122 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
123 static rtx
gen_conditional_move (enum rtx_code
, enum machine_mode
, rtx
, rtx
);
124 static rtx
fixup_subreg_mem (rtx
);
125 static struct machine_function
* xtensa_init_machine_status (void);
126 static rtx
xtensa_legitimize_tls_address (rtx
);
127 static rtx
xtensa_legitimize_address (rtx
, rtx
, enum machine_mode
);
128 static bool xtensa_return_in_msb (const_tree
);
129 static void printx (FILE *, signed int);
130 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT
);
131 static rtx
xtensa_builtin_saveregs (void);
132 static bool xtensa_legitimate_address_p (enum machine_mode
, rtx
, bool);
133 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
134 int) ATTRIBUTE_UNUSED
;
135 static section
*xtensa_select_rtx_section (enum machine_mode
, rtx
,
136 unsigned HOST_WIDE_INT
);
137 static bool xtensa_rtx_costs (rtx
, int, int, int *, bool);
138 static tree
xtensa_build_builtin_va_list (void);
139 static bool xtensa_return_in_memory (const_tree
, const_tree
);
140 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
142 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
143 static void xtensa_init_builtins (void);
144 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
145 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
146 static void xtensa_va_start (tree
, rtx
);
147 static bool xtensa_frame_pointer_required (void);
148 static rtx
xtensa_static_chain (const_tree
, bool);
149 static void xtensa_asm_trampoline_template (FILE *);
150 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
152 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
156 /* This macro generates the assembly code for function exit,
157 on machines that need it. If FUNCTION_EPILOGUE is not defined
158 then individual return instructions are generated for each
159 return statement. Args are same as for FUNCTION_PROLOGUE. */
161 #undef TARGET_ASM_FUNCTION_EPILOGUE
162 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
164 /* These hooks specify assembly directives for creating certain kinds
165 of integer object. */
167 #undef TARGET_ASM_ALIGNED_SI_OP
168 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
170 #undef TARGET_ASM_SELECT_RTX_SECTION
171 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
173 #undef TARGET_DEFAULT_TARGET_FLAGS
174 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT | MASK_FUSED_MADD)
176 #undef TARGET_LEGITIMIZE_ADDRESS
177 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
179 #undef TARGET_RTX_COSTS
180 #define TARGET_RTX_COSTS xtensa_rtx_costs
181 #undef TARGET_ADDRESS_COST
182 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
184 #undef TARGET_BUILD_BUILTIN_VA_LIST
185 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
187 #undef TARGET_EXPAND_BUILTIN_VA_START
188 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
190 #undef TARGET_PROMOTE_FUNCTION_MODE
191 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
192 #undef TARGET_PROMOTE_PROTOTYPES
193 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
195 #undef TARGET_RETURN_IN_MEMORY
196 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
197 #undef TARGET_FUNCTION_VALUE
198 #define TARGET_FUNCTION_VALUE xtensa_function_value
199 #undef TARGET_SPLIT_COMPLEX_ARG
200 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
201 #undef TARGET_MUST_PASS_IN_STACK
202 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
204 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
205 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
206 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
207 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
209 #undef TARGET_RETURN_IN_MSB
210 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
212 #undef TARGET_INIT_BUILTINS
213 #define TARGET_INIT_BUILTINS xtensa_init_builtins
214 #undef TARGET_FOLD_BUILTIN
215 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
216 #undef TARGET_EXPAND_BUILTIN
217 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
219 #undef TARGET_SECONDARY_RELOAD
220 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
222 #undef TARGET_HAVE_TLS
223 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
225 #undef TARGET_CANNOT_FORCE_CONST_MEM
226 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
228 #undef TARGET_LEGITIMATE_ADDRESS_P
229 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
231 #undef TARGET_FRAME_POINTER_REQUIRED
232 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
234 #undef TARGET_STATIC_CHAIN
235 #define TARGET_STATIC_CHAIN xtensa_static_chain
236 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
237 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
238 #undef TARGET_TRAMPOLINE_INIT
239 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
241 struct gcc_target targetm
= TARGET_INITIALIZER
;
244 /* Functions to test Xtensa immediate operand validity. */
247 xtensa_simm8 (HOST_WIDE_INT v
)
249 return v
>= -128 && v
<= 127;
254 xtensa_simm8x256 (HOST_WIDE_INT v
)
256 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
261 xtensa_simm12b (HOST_WIDE_INT v
)
263 return v
>= -2048 && v
<= 2047;
268 xtensa_uimm8 (HOST_WIDE_INT v
)
270 return v
>= 0 && v
<= 255;
275 xtensa_uimm8x2 (HOST_WIDE_INT v
)
277 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
282 xtensa_uimm8x4 (HOST_WIDE_INT v
)
284 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
289 xtensa_b4const (HOST_WIDE_INT v
)
316 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
320 return xtensa_b4const (v
);
325 xtensa_b4constu (HOST_WIDE_INT v
)
352 xtensa_mask_immediate (HOST_WIDE_INT v
)
354 #define MAX_MASK_SIZE 16
357 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
370 /* This is just like the standard true_regnum() function except that it
371 works even when reg_renumber is not initialized. */
374 xt_true_regnum (rtx x
)
376 if (GET_CODE (x
) == REG
)
379 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
380 && reg_renumber
[REGNO (x
)] >= 0)
381 return reg_renumber
[REGNO (x
)];
384 if (GET_CODE (x
) == SUBREG
)
386 int base
= xt_true_regnum (SUBREG_REG (x
));
387 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
388 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
389 GET_MODE (SUBREG_REG (x
)),
390 SUBREG_BYTE (x
), GET_MODE (x
));
397 xtensa_valid_move (enum machine_mode mode
, rtx
*operands
)
399 /* Either the destination or source must be a register, and the
400 MAC16 accumulator doesn't count. */
402 if (register_operand (operands
[0], mode
))
404 int dst_regnum
= xt_true_regnum (operands
[0]);
406 /* The stack pointer can only be assigned with a MOVSP opcode. */
407 if (dst_regnum
== STACK_POINTER_REGNUM
)
408 return (mode
== SImode
409 && register_operand (operands
[1], mode
)
410 && !ACC_REG_P (xt_true_regnum (operands
[1])));
412 if (!ACC_REG_P (dst_regnum
))
415 if (register_operand (operands
[1], mode
))
417 int src_regnum
= xt_true_regnum (operands
[1]);
418 if (!ACC_REG_P (src_regnum
))
426 smalloffset_mem_p (rtx op
)
428 if (GET_CODE (op
) == MEM
)
430 rtx addr
= XEXP (op
, 0);
431 if (GET_CODE (addr
) == REG
)
432 return BASE_REG_P (addr
, 0);
433 if (GET_CODE (addr
) == PLUS
)
435 rtx offset
= XEXP (addr
, 0);
437 if (GET_CODE (offset
) != CONST_INT
)
438 offset
= XEXP (addr
, 1);
439 if (GET_CODE (offset
) != CONST_INT
)
442 val
= INTVAL (offset
);
443 return (val
& 3) == 0 && (val
>= 0 && val
<= 60);
451 constantpool_address_p (rtx addr
)
455 if (GET_CODE (addr
) == CONST
)
459 /* Only handle (PLUS (SYM, OFFSET)) form. */
460 addr
= XEXP (addr
, 0);
461 if (GET_CODE (addr
) != PLUS
)
464 /* Make sure the address is word aligned. */
465 offset
= XEXP (addr
, 1);
466 if ((GET_CODE (offset
) != CONST_INT
)
467 || ((INTVAL (offset
) & 3) != 0))
470 sym
= XEXP (addr
, 0);
473 if ((GET_CODE (sym
) == SYMBOL_REF
)
474 && CONSTANT_POOL_ADDRESS_P (sym
))
481 constantpool_mem_p (rtx op
)
483 if (GET_CODE (op
) == SUBREG
)
484 op
= SUBREG_REG (op
);
485 if (GET_CODE (op
) == MEM
)
486 return constantpool_address_p (XEXP (op
, 0));
491 /* Return TRUE if X is a thread-local symbol. */
494 xtensa_tls_symbol_p (rtx x
)
496 if (! TARGET_HAVE_TLS
)
499 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
504 xtensa_extend_reg (rtx dst
, rtx src
)
506 rtx temp
= gen_reg_rtx (SImode
);
507 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
509 /* Generate paradoxical subregs as needed so that the modes match. */
510 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
511 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
513 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
514 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
519 xtensa_mem_offset (unsigned v
, enum machine_mode mode
)
524 /* Handle the worst case for block moves. See xtensa_expand_block_move
525 where we emit an optimized block move operation if the block can be
526 moved in < "move_ratio" pieces. The worst case is when the block is
527 aligned but has a size of (3 mod 4) (does this happen?) so that the
528 last piece requires a byte load/store. */
529 return (xtensa_uimm8 (v
)
530 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
533 return xtensa_uimm8 (v
);
536 return xtensa_uimm8x2 (v
);
539 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
545 return xtensa_uimm8x4 (v
);
549 /* Make normal rtx_code into something we can index from an array. */
551 static enum internal_test
552 map_test_to_internal_test (enum rtx_code test_code
)
554 enum internal_test test
= ITEST_MAX
;
559 case EQ
: test
= ITEST_EQ
; break;
560 case NE
: test
= ITEST_NE
; break;
561 case GT
: test
= ITEST_GT
; break;
562 case GE
: test
= ITEST_GE
; break;
563 case LT
: test
= ITEST_LT
; break;
564 case LE
: test
= ITEST_LE
; break;
565 case GTU
: test
= ITEST_GTU
; break;
566 case GEU
: test
= ITEST_GEU
; break;
567 case LTU
: test
= ITEST_LTU
; break;
568 case LEU
: test
= ITEST_LEU
; break;
575 /* Generate the code to compare two integer values. The return value is
576 the comparison expression. */
579 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
580 rtx cmp0
, /* first operand to compare */
581 rtx cmp1
, /* second operand to compare */
582 int *p_invert
/* whether branch needs to reverse test */)
586 enum rtx_code test_code
; /* test code to use in insn */
587 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
588 int const_add
; /* constant to add (convert LE -> LT) */
589 int reverse_regs
; /* reverse registers in test */
590 int invert_const
; /* != 0 if invert value if cmp1 is constant */
591 int invert_reg
; /* != 0 if invert value if cmp1 is register */
592 int unsignedp
; /* != 0 for unsigned comparisons. */
595 static struct cmp_info info
[ (int)ITEST_MAX
] = {
597 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
598 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
600 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
601 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
602 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
603 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
605 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
606 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
607 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
608 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
611 enum internal_test test
;
612 enum machine_mode mode
;
613 struct cmp_info
*p_info
;
615 test
= map_test_to_internal_test (test_code
);
616 gcc_assert (test
!= ITEST_MAX
);
618 p_info
= &info
[ (int)test
];
620 mode
= GET_MODE (cmp0
);
621 if (mode
== VOIDmode
)
622 mode
= GET_MODE (cmp1
);
624 /* Make sure we can handle any constants given to us. */
625 if (GET_CODE (cmp1
) == CONST_INT
)
627 HOST_WIDE_INT value
= INTVAL (cmp1
);
628 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
630 /* if the immediate overflows or does not fit in the immediate field,
631 spill it to a register */
633 if ((p_info
->unsignedp
?
634 (uvalue
+ p_info
->const_add
> uvalue
) :
635 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
637 cmp1
= force_reg (mode
, cmp1
);
639 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
641 cmp1
= force_reg (mode
, cmp1
);
644 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
646 cmp1
= force_reg (mode
, cmp1
);
649 /* See if we need to invert the result. */
650 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
651 ? p_info
->invert_const
652 : p_info
->invert_reg
);
654 /* Comparison to constants, may involve adding 1 to change a LT into LE.
655 Comparison between two registers, may involve switching operands. */
656 if (GET_CODE (cmp1
) == CONST_INT
)
658 if (p_info
->const_add
!= 0)
659 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
662 else if (p_info
->reverse_regs
)
669 return gen_rtx_fmt_ee (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
673 /* Generate the code to compare two float values. The return value is
674 the comparison expression. */
677 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
678 rtx cmp0
, /* first operand to compare */
679 rtx cmp1
/* second operand to compare */)
681 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
683 int reverse_regs
, invert
;
687 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
688 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
689 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
690 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
691 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
692 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
693 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
694 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
695 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
696 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
697 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
698 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
700 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
702 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
704 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
705 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
715 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
716 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
718 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
723 xtensa_expand_conditional_branch (rtx
*operands
, enum machine_mode mode
)
725 enum rtx_code test_code
= GET_CODE (operands
[0]);
726 rtx cmp0
= operands
[1];
727 rtx cmp1
= operands
[2];
736 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
740 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
744 if (!TARGET_HARD_FLOAT
)
745 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
,
748 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
752 /* Generate the branch. */
754 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
763 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
764 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
771 gen_conditional_move (enum rtx_code code
, enum machine_mode mode
,
778 /* Jump optimization calls get_condition() which canonicalizes
779 comparisons like (GE x <const>) to (GT x <const-1>).
780 Transform those comparisons back to GE, since that is the
781 comparison supported in Xtensa. We shouldn't have to
782 transform <LE x const> comparisons, because neither
783 xtensa_expand_conditional_branch() nor get_condition() will
786 if ((code
== GT
) && (op1
== constm1_rtx
))
791 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
793 if (boolean_operator (cmp
, VOIDmode
))
795 /* Swap the operands to make const0 second. */
796 if (op0
== const0_rtx
)
802 /* If not comparing against zero, emit a comparison (subtract). */
803 if (op1
!= const0_rtx
)
805 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
806 0, 0, OPTAB_LIB_WIDEN
);
810 else if (branch_operator (cmp
, VOIDmode
))
812 /* Swap the operands to make const0 second. */
813 if (op0
== const0_rtx
)
820 case LT
: code
= GE
; break;
821 case GE
: code
= LT
; break;
822 default: gcc_unreachable ();
826 if (op1
!= const0_rtx
)
832 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
835 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
836 return gen_float_relational (code
, op0
, op1
);
843 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
845 rtx dest
= operands
[0];
846 rtx cmp
= operands
[1];
847 enum machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
848 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
850 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
851 XEXP (cmp
, 0), XEXP (cmp
, 1))))
855 gen_fn
= (cmp_mode
== SImode
856 ? gen_movsfcc_internal0
857 : gen_movsfcc_internal1
);
859 gen_fn
= (cmp_mode
== SImode
860 ? gen_movsicc_internal0
861 : gen_movsicc_internal1
);
863 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
869 xtensa_expand_scc (rtx operands
[4], enum machine_mode cmp_mode
)
871 rtx dest
= operands
[0];
873 rtx one_tmp
, zero_tmp
;
874 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
876 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
877 operands
[2], operands
[3])))
880 one_tmp
= gen_reg_rtx (SImode
);
881 zero_tmp
= gen_reg_rtx (SImode
);
882 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
883 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
885 gen_fn
= (cmp_mode
== SImode
886 ? gen_movsicc_internal0
887 : gen_movsicc_internal1
);
888 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
893 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
894 for the output, i.e., the input operands are twice as big as MODE. */
897 xtensa_split_operand_pair (rtx operands
[4], enum machine_mode mode
)
899 switch (GET_CODE (operands
[1]))
902 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
903 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
907 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
908 operands
[2] = adjust_address (operands
[1], mode
, 0);
913 split_double (operands
[1], &operands
[2], &operands
[3]);
920 switch (GET_CODE (operands
[0]))
923 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
924 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
928 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
929 operands
[0] = adjust_address (operands
[0], mode
, 0);
938 /* Emit insns to move operands[1] into operands[0].
939 Return 1 if we have written out everything that needs to be done to
940 do the move. Otherwise, return 0 and the caller will emit the move
944 xtensa_emit_move_sequence (rtx
*operands
, enum machine_mode mode
)
946 rtx src
= operands
[1];
949 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
951 rtx dst
= operands
[0];
953 if (xtensa_tls_referenced_p (src
))
957 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
959 addend
= XEXP (XEXP (src
, 0), 1);
960 src
= XEXP (XEXP (src
, 0), 0);
963 src
= xtensa_legitimize_tls_address (src
);
966 src
= gen_rtx_PLUS (mode
, src
, addend
);
967 src
= force_operand (src
, dst
);
969 emit_move_insn (dst
, src
);
973 if (! TARGET_CONST16
)
975 src
= force_const_mem (SImode
, src
);
979 /* PC-relative loads are always SImode, and CONST16 is only
980 supported in the movsi pattern, so add a SUBREG for any other
985 if (register_operand (dst
, mode
))
987 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
992 src
= force_reg (SImode
, src
);
993 src
= gen_lowpart_SUBREG (mode
, src
);
999 if (!(reload_in_progress
| reload_completed
)
1000 && !xtensa_valid_move (mode
, operands
))
1001 operands
[1] = force_reg (mode
, operands
[1]);
1003 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1005 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1006 instruction won't be recognized after reload, so we remove the
1007 subreg and adjust mem accordingly. */
1008 if (reload_in_progress
)
1010 operands
[0] = fixup_subreg_mem (operands
[0]);
1011 operands
[1] = fixup_subreg_mem (operands
[1]);
1018 fixup_subreg_mem (rtx x
)
1020 if (GET_CODE (x
) == SUBREG
1021 && GET_CODE (SUBREG_REG (x
)) == REG
1022 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1025 gen_rtx_SUBREG (GET_MODE (x
),
1026 reg_equiv_mem
[REGNO (SUBREG_REG (x
))],
1028 x
= alter_subreg (&temp
);
1034 /* Check if an incoming argument in a7 is expected to be used soon and
1035 if OPND is a register or register pair that includes a7. If so,
1036 create a new pseudo and copy a7 into that pseudo at the very
1037 beginning of the function, followed by the special "set_frame_ptr"
1038 unspec_volatile insn. The return value is either the original
1039 operand, if it is not a7, or the new pseudo containing a copy of
1040 the incoming argument. This is necessary because the register
1041 allocator will ignore conflicts with a7 and may either assign some
1042 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1043 the incoming argument in a7. By copying the argument out of a7 as
1044 the very first thing, and then immediately following that with an
1045 unspec_volatile to keep the scheduler away, we should avoid any
1046 problems. Putting the set_frame_ptr insn at the beginning, with
1047 only the a7 copy before it, also makes it easier for the prologue
1048 expander to initialize the frame pointer after the a7 copy and to
1049 fix up the a7 copy to use the stack pointer instead of the frame
1053 xtensa_copy_incoming_a7 (rtx opnd
)
1055 rtx entry_insns
= 0;
1057 enum machine_mode mode
;
1059 if (!cfun
->machine
->need_a7_copy
)
1062 /* This function should never be called again once a7 has been copied. */
1063 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1065 mode
= GET_MODE (opnd
);
1067 /* The operand using a7 may come in a later instruction, so just return
1068 the original operand if it doesn't use a7. */
1070 if (GET_CODE (reg
) == SUBREG
)
1072 gcc_assert (SUBREG_BYTE (reg
) == 0);
1073 reg
= SUBREG_REG (reg
);
1075 if (GET_CODE (reg
) != REG
1076 || REGNO (reg
) > A7_REG
1077 || REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) <= A7_REG
)
1080 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1081 gcc_assert (REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) - 1 == A7_REG
);
1083 cfun
->machine
->need_a7_copy
= false;
1085 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1086 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1089 tmp
= gen_reg_rtx (mode
);
1095 /* Copy the value out of A7 here but keep the first word in A6 until
1096 after the set_frame_ptr insn. Otherwise, the register allocator
1097 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1099 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1100 gen_raw_REG (SImode
, A7_REG
)));
1103 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1106 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1109 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1112 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1118 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1120 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1121 if (mode
== DFmode
|| mode
== DImode
)
1122 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1123 gen_rtx_REG (SImode
, A7_REG
- 1)));
1124 entry_insns
= get_insns ();
1127 if (cfun
->machine
->vararg_a7
)
1129 /* This is called from within builtin_saveregs, which will insert the
1130 saveregs code at the function entry, ahead of anything placed at
1131 the function entry now. Instead, save the sequence to be inserted
1132 at the beginning of the saveregs code. */
1133 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1137 /* Put entry_insns after the NOTE that starts the function. If
1138 this is inside a start_sequence, make the outer-level insn
1139 chain current, so the code is placed at the start of the
1141 push_topmost_sequence ();
1142 /* Do not use entry_of_function() here. This is called from within
1143 expand_function_start, when the CFG still holds GIMPLE. */
1144 emit_insn_after (entry_insns
, get_insns ());
1145 pop_topmost_sequence ();
1152 /* Try to expand a block move operation to a sequence of RTL move
1153 instructions. If not optimizing, or if the block size is not a
1154 constant, or if the block is too large, the expansion fails and GCC
1155 falls back to calling memcpy().
1157 operands[0] is the destination
1158 operands[1] is the source
1159 operands[2] is the length
1160 operands[3] is the alignment */
1163 xtensa_expand_block_move (rtx
*operands
)
1165 static const enum machine_mode mode_from_align
[] =
1167 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1170 rtx dst_mem
= operands
[0];
1171 rtx src_mem
= operands
[1];
1172 HOST_WIDE_INT bytes
, align
;
1173 int num_pieces
, move_ratio
;
1175 enum machine_mode mode
[2];
1184 /* If this is not a fixed size move, just call memcpy. */
1185 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1188 bytes
= INTVAL (operands
[2]);
1189 align
= INTVAL (operands
[3]);
1191 /* Anything to move? */
1195 if (align
> MOVE_MAX
)
1198 /* Decide whether to expand inline based on the optimization level. */
1201 move_ratio
= LARGEST_MOVE_RATIO
;
1202 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* Close enough anyway. */
1203 if (num_pieces
> move_ratio
)
1206 x
= XEXP (dst_mem
, 0);
1209 x
= force_reg (Pmode
, x
);
1210 dst_mem
= replace_equiv_address (dst_mem
, x
);
1213 x
= XEXP (src_mem
, 0);
1216 x
= force_reg (Pmode
, x
);
1217 src_mem
= replace_equiv_address (src_mem
, x
);
1220 active
[0] = active
[1] = false;
1231 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1232 next_amount
= MIN (next_amount
, align
);
1234 amount
[next
] = next_amount
;
1235 mode
[next
] = mode_from_align
[next_amount
];
1236 temp
[next
] = gen_reg_rtx (mode
[next
]);
1238 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1239 emit_insn (gen_rtx_SET (VOIDmode
, temp
[next
], x
));
1241 offset_ld
+= next_amount
;
1242 bytes
-= next_amount
;
1243 active
[next
] = true;
1248 active
[phase
] = false;
1250 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1251 emit_insn (gen_rtx_SET (VOIDmode
, x
, temp
[phase
]));
1253 offset_st
+= amount
[phase
];
1256 while (active
[next
]);
1263 xtensa_expand_nonlocal_goto (rtx
*operands
)
1265 rtx goto_handler
= operands
[1];
1266 rtx containing_fp
= operands
[3];
1268 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1269 is too big to generate in-line. */
1271 if (GET_CODE (containing_fp
) != REG
)
1272 containing_fp
= force_reg (Pmode
, containing_fp
);
1274 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1276 containing_fp
, Pmode
,
1277 goto_handler
, Pmode
);
1281 static struct machine_function
*
1282 xtensa_init_machine_status (void)
1284 return GGC_CNEW (struct machine_function
);
1288 /* Shift VAL of mode MODE left by COUNT bits. */
1291 xtensa_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
1293 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1294 NULL_RTX
, 1, OPTAB_DIRECT
);
1295 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1296 NULL_RTX
, 1, OPTAB_DIRECT
);
1300 /* Structure to hold the initial parameters for a compare_and_swap operation
1301 in HImode and QImode. */
1303 struct alignment_context
1305 rtx memsi
; /* SI aligned memory location. */
1306 rtx shift
; /* Bit offset with regard to lsb. */
1307 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1308 rtx modemaski
; /* ~modemask */
1312 /* Initialize structure AC for word access to HI and QI mode memory. */
1315 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1317 enum machine_mode mode
= GET_MODE (mem
);
1318 rtx byteoffset
= NULL_RTX
;
1319 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1322 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1325 /* Alignment is unknown. */
1328 /* Force the address into a register. */
1329 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1331 /* Align it to SImode. */
1332 align
= expand_simple_binop (Pmode
, AND
, addr
,
1333 GEN_INT (-GET_MODE_SIZE (SImode
)),
1334 NULL_RTX
, 1, OPTAB_DIRECT
);
1336 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1337 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1338 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1339 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1341 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1342 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1343 NULL_RTX
, 1, OPTAB_DIRECT
);
1346 /* Calculate shiftcount. */
1347 if (TARGET_BIG_ENDIAN
)
1349 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1351 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1352 NULL_RTX
, 1, OPTAB_DIRECT
);
1357 ac
->shift
= NULL_RTX
;
1359 ac
->shift
= byteoffset
;
1362 if (ac
->shift
!= NULL_RTX
)
1364 /* Shift is the byte count, but we need the bitcount. */
1365 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
,
1366 GEN_INT (BITS_PER_UNIT
),
1367 NULL_RTX
, 1, OPTAB_DIRECT
);
1368 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1369 GEN_INT (GET_MODE_MASK (mode
)),
1371 NULL_RTX
, 1, OPTAB_DIRECT
);
1374 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1376 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1380 /* Expand an atomic compare and swap operation for HImode and QImode.
1381 MEM is the memory location, CMP the old value to compare MEM with
1382 and NEW_RTX the value to set if CMP == MEM. */
1385 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1387 enum machine_mode mode
= GET_MODE (mem
);
1388 struct alignment_context ac
;
1389 rtx tmp
, cmpv
, newv
, val
;
1390 rtx oldval
= gen_reg_rtx (SImode
);
1391 rtx res
= gen_reg_rtx (SImode
);
1392 rtx csloop
= gen_label_rtx ();
1393 rtx csend
= gen_label_rtx ();
1395 init_alignment_context (&ac
, mem
);
1397 if (ac
.shift
!= NULL_RTX
)
1399 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1400 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1403 /* Load the surrounding word into VAL with the MEM value masked out. */
1404 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1405 ac
.modemaski
, NULL_RTX
, 1,
1407 emit_label (csloop
);
1409 /* Patch CMP and NEW_RTX into VAL at correct position. */
1410 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1411 NULL_RTX
, 1, OPTAB_DIRECT
));
1412 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1413 NULL_RTX
, 1, OPTAB_DIRECT
));
1415 /* Jump to end if we're done. */
1416 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1417 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1419 /* Check for changes outside mode. */
1420 emit_move_insn (oldval
, val
);
1421 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1422 val
, 1, OPTAB_DIRECT
);
1424 emit_move_insn (val
, tmp
);
1426 /* Loop internal if so. */
1427 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1431 /* Return the correct part of the bitfield. */
1432 convert_move (target
,
1433 (ac
.shift
== NULL_RTX
? res
1434 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1435 NULL_RTX
, 1, OPTAB_DIRECT
)),
1440 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1441 the default expansion works fine for SImode). MEM is the memory location
1442 and VAL the value to play with. If AFTER is true then store the value
1443 MEM holds after the operation, if AFTER is false then store the value MEM
1444 holds before the operation. If TARGET is zero then discard that value, else
1445 store it to TARGET. */
1448 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1451 enum machine_mode mode
= GET_MODE (mem
);
1452 struct alignment_context ac
;
1453 rtx csloop
= gen_label_rtx ();
1455 rtx old
= gen_reg_rtx (SImode
);
1456 rtx new_rtx
= gen_reg_rtx (SImode
);
1457 rtx orig
= NULL_RTX
;
1459 init_alignment_context (&ac
, mem
);
1461 /* Prepare values before the compare-and-swap loop. */
1462 if (ac
.shift
!= NULL_RTX
)
1463 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1468 orig
= gen_reg_rtx (SImode
);
1469 convert_move (orig
, val
, 1);
1477 case MULT
: /* NAND */
1479 /* val = "11..1<val>11..1" */
1480 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1481 NULL_RTX
, 1, OPTAB_DIRECT
);
1488 /* Load full word. Subsequent loads are performed by S32C1I. */
1489 cmp
= force_reg (SImode
, ac
.memsi
);
1491 emit_label (csloop
);
1492 emit_move_insn (old
, cmp
);
1498 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1499 NULL_RTX
, 1, OPTAB_DIRECT
);
1500 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1501 NULL_RTX
, 1, OPTAB_DIRECT
);
1504 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1505 NULL_RTX
, 1, OPTAB_DIRECT
);
1506 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1507 new_rtx
, 1, OPTAB_DIRECT
);
1513 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
1514 new_rtx
, 1, OPTAB_DIRECT
);
1517 case MULT
: /* NAND */
1518 tmp
= expand_simple_binop (SImode
, XOR
, old
, ac
.modemask
,
1519 NULL_RTX
, 1, OPTAB_DIRECT
);
1520 tmp
= expand_simple_binop (SImode
, AND
, tmp
, val
,
1521 new_rtx
, 1, OPTAB_DIRECT
);
1529 emit_move_insn (new_rtx
, tmp
);
1530 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
1531 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
1535 tmp
= (after
? new_rtx
: cmp
);
1536 convert_move (target
,
1537 (ac
.shift
== NULL_RTX
? tmp
1538 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
1539 NULL_RTX
, 1, OPTAB_DIRECT
)),
1546 xtensa_setup_frame_addresses (void)
1548 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1549 cfun
->machine
->accesses_prev_frame
= 1;
1552 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1557 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1558 a comment showing where the end of the loop is. However, if there is a
1559 label or a branch at the end of the loop then we need to place a nop
1560 there. If the loop ends with a label we need the nop so that branches
1561 targeting that label will target the nop (and thus remain in the loop),
1562 instead of targeting the instruction after the loop (and thus exiting
1563 the loop). If the loop ends with a branch, we need the nop in case the
1564 branch is targeting a location inside the loop. When the branch
1565 executes it will cause the loop count to be decremented even if it is
1566 taken (because it is the last instruction in the loop), so we need to
1567 nop after the branch to prevent the loop count from being decremented
1568 when the branch is taken. */
1571 xtensa_emit_loop_end (rtx insn
, rtx
*operands
)
1575 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1577 switch (GET_CODE (insn
))
1584 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1590 rtx body
= PATTERN (insn
);
1592 if (GET_CODE (body
) == JUMP_INSN
)
1594 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1597 else if ((GET_CODE (body
) != USE
)
1598 && (GET_CODE (body
) != CLOBBER
))
1605 output_asm_insn ("# loop end for %0", operands
);
1610 xtensa_emit_branch (bool inverted
, bool immed
, rtx
*operands
)
1612 static char result
[64];
1616 code
= GET_CODE (operands
[3]);
1619 case EQ
: op
= inverted
? "ne" : "eq"; break;
1620 case NE
: op
= inverted
? "eq" : "ne"; break;
1621 case LT
: op
= inverted
? "ge" : "lt"; break;
1622 case GE
: op
= inverted
? "lt" : "ge"; break;
1623 case LTU
: op
= inverted
? "geu" : "ltu"; break;
1624 case GEU
: op
= inverted
? "ltu" : "geu"; break;
1625 default: gcc_unreachable ();
1630 if (INTVAL (operands
[1]) == 0)
1631 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
1632 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
1634 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1637 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1644 xtensa_emit_bit_branch (bool inverted
, bool immed
, rtx
*operands
)
1646 static char result
[64];
1649 switch (GET_CODE (operands
[3]))
1651 case EQ
: op
= inverted
? "bs" : "bc"; break;
1652 case NE
: op
= inverted
? "bc" : "bs"; break;
1653 default: gcc_unreachable ();
1658 unsigned bitnum
= INTVAL (operands
[1]) & 0x1f;
1659 operands
[1] = GEN_INT (bitnum
);
1660 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1663 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1670 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
1672 static char result
[64];
1676 code
= GET_CODE (operands
[4]);
1681 case EQ
: op
= inverted
? "t" : "f"; break;
1682 case NE
: op
= inverted
? "f" : "t"; break;
1683 default: gcc_unreachable ();
1690 case EQ
: op
= inverted
? "nez" : "eqz"; break;
1691 case NE
: op
= inverted
? "eqz" : "nez"; break;
1692 case LT
: op
= inverted
? "gez" : "ltz"; break;
1693 case GE
: op
= inverted
? "ltz" : "gez"; break;
1694 default: gcc_unreachable ();
1698 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
1699 op
, isfp
? ".s" : "", inverted
? 3 : 2);
1705 xtensa_emit_call (int callop
, rtx
*operands
)
1707 static char result
[64];
1708 rtx tgt
= operands
[callop
];
1710 if (GET_CODE (tgt
) == CONST_INT
)
1711 sprintf (result
, "call8\t0x%lx", INTVAL (tgt
));
1712 else if (register_operand (tgt
, VOIDmode
))
1713 sprintf (result
, "callx8\t%%%d", callop
);
1715 sprintf (result
, "call8\t%%%d", callop
);
1722 xtensa_legitimate_address_p (enum machine_mode mode
, rtx addr
, bool strict
)
1724 /* Allow constant pool addresses. */
1725 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
1726 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
1727 && ! xtensa_tls_referenced_p (addr
))
1730 while (GET_CODE (addr
) == SUBREG
)
1731 addr
= SUBREG_REG (addr
);
1733 /* Allow base registers. */
1734 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
1737 /* Check for "register + offset" addressing. */
1738 if (GET_CODE (addr
) == PLUS
)
1740 rtx xplus0
= XEXP (addr
, 0);
1741 rtx xplus1
= XEXP (addr
, 1);
1742 enum rtx_code code0
;
1743 enum rtx_code code1
;
1745 while (GET_CODE (xplus0
) == SUBREG
)
1746 xplus0
= SUBREG_REG (xplus0
);
1747 code0
= GET_CODE (xplus0
);
1749 while (GET_CODE (xplus1
) == SUBREG
)
1750 xplus1
= SUBREG_REG (xplus1
);
1751 code1
= GET_CODE (xplus1
);
1753 /* Swap operands if necessary so the register is first. */
1754 if (code0
!= REG
&& code1
== REG
)
1756 xplus0
= XEXP (addr
, 1);
1757 xplus1
= XEXP (addr
, 0);
1758 code0
= GET_CODE (xplus0
);
1759 code1
= GET_CODE (xplus1
);
1762 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
1763 && code1
== CONST_INT
1764 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
1772 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1774 static GTY(()) rtx xtensa_tls_module_base_symbol
;
1777 xtensa_tls_module_base (void)
1779 if (! xtensa_tls_module_base_symbol
)
1781 xtensa_tls_module_base_symbol
=
1782 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
1783 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
1784 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
1787 return xtensa_tls_module_base_symbol
;
1792 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
1794 rtx fn
, arg
, a10
, call_insn
, insns
;
1797 fn
= gen_reg_rtx (Pmode
);
1798 arg
= gen_reg_rtx (Pmode
);
1799 a10
= gen_rtx_REG (Pmode
, 10);
1801 emit_insn (gen_tls_func (fn
, sym
));
1802 emit_insn (gen_tls_arg (arg
, sym
));
1803 emit_move_insn (a10
, arg
);
1804 call_insn
= emit_call_insn (gen_tls_call (a10
, fn
, sym
, const1_rtx
));
1805 CALL_INSN_FUNCTION_USAGE (call_insn
)
1806 = gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_USE (VOIDmode
, a10
),
1807 CALL_INSN_FUNCTION_USAGE (call_insn
));
1808 insns
= get_insns ();
1817 xtensa_legitimize_tls_address (rtx x
)
1819 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
1820 rtx dest
, tp
, ret
, modbase
, base
, addend
, insns
;
1822 dest
= gen_reg_rtx (Pmode
);
1825 case TLS_MODEL_GLOBAL_DYNAMIC
:
1826 insns
= xtensa_call_tls_desc (x
, &ret
);
1827 emit_libcall_block (insns
, dest
, ret
, x
);
1830 case TLS_MODEL_LOCAL_DYNAMIC
:
1831 base
= gen_reg_rtx (Pmode
);
1832 modbase
= xtensa_tls_module_base ();
1833 insns
= xtensa_call_tls_desc (modbase
, &ret
);
1834 emit_libcall_block (insns
, base
, ret
, modbase
);
1835 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
1836 emit_insn (gen_addsi3 (dest
, base
, addend
));
1839 case TLS_MODEL_INITIAL_EXEC
:
1840 case TLS_MODEL_LOCAL_EXEC
:
1841 tp
= gen_reg_rtx (SImode
);
1842 emit_insn (gen_load_tp (tp
));
1843 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
1844 emit_insn (gen_addsi3 (dest
, tp
, addend
));
1856 xtensa_legitimize_address (rtx x
,
1857 rtx oldx ATTRIBUTE_UNUSED
,
1858 enum machine_mode mode
)
1860 if (xtensa_tls_symbol_p (x
))
1861 return xtensa_legitimize_tls_address (x
);
1863 if (GET_CODE (x
) == PLUS
)
1865 rtx plus0
= XEXP (x
, 0);
1866 rtx plus1
= XEXP (x
, 1);
1868 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1870 plus0
= XEXP (x
, 1);
1871 plus1
= XEXP (x
, 0);
1874 /* Try to split up the offset to use an ADDMI instruction. */
1875 if (GET_CODE (plus0
) == REG
1876 && GET_CODE (plus1
) == CONST_INT
1877 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
1878 && !xtensa_simm8 (INTVAL (plus1
))
1879 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
1880 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
1882 rtx temp
= gen_reg_rtx (Pmode
);
1883 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
1884 emit_insn (gen_rtx_SET (Pmode
, temp
,
1885 gen_rtx_PLUS (Pmode
, plus0
, addmi_offset
)));
1886 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
1894 /* Helper for xtensa_tls_referenced_p. */
1897 xtensa_tls_referenced_p_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
1899 if (GET_CODE (*x
) == SYMBOL_REF
)
1900 return SYMBOL_REF_TLS_MODEL (*x
) != 0;
1902 /* Ignore TLS references that have already been legitimized. */
1903 if (GET_CODE (*x
) == UNSPEC
)
1905 switch (XINT (*x
, 1))
1909 case UNSPEC_TLS_FUNC
:
1910 case UNSPEC_TLS_ARG
:
1911 case UNSPEC_TLS_CALL
:
1922 /* Return TRUE if X contains any TLS symbol references. */
1925 xtensa_tls_referenced_p (rtx x
)
1927 if (! TARGET_HAVE_TLS
)
1930 return for_each_rtx (&x
, xtensa_tls_referenced_p_1
, NULL
);
1934 /* Return the debugger register number to use for 'regno'. */
1937 xtensa_dbx_register_number (int regno
)
1941 if (GP_REG_P (regno
))
1943 regno
-= GP_REG_FIRST
;
1946 else if (BR_REG_P (regno
))
1948 regno
-= BR_REG_FIRST
;
1951 else if (FP_REG_P (regno
))
1953 regno
-= FP_REG_FIRST
;
1956 else if (ACC_REG_P (regno
))
1958 first
= 0x200; /* Start of Xtensa special registers. */
1959 regno
= 16; /* ACCLO is special register 16. */
1962 /* When optimizing, we sometimes get asked about pseudo-registers
1963 that don't represent hard registers. Return 0 for these. */
1967 return first
+ regno
;
1971 /* Argument support functions. */
1973 /* Initialize CUMULATIVE_ARGS for a function. */
1976 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
1979 cum
->incoming
= incoming
;
1983 /* Advance the argument to the next argument position. */
1986 function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
)
1991 arg_words
= &cum
->arg_words
;
1992 max
= MAX_ARGS_IN_REGISTERS
;
1994 words
= (((mode
!= BLKmode
)
1995 ? (int) GET_MODE_SIZE (mode
)
1996 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1998 if (*arg_words
< max
1999 && (targetm
.calls
.must_pass_in_stack (mode
, type
)
2000 || *arg_words
+ words
> max
))
2003 *arg_words
+= words
;
2007 /* Return an RTL expression containing the register for the given mode,
2008 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2009 if this is an incoming argument to the current function. */
2012 function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
, tree type
,
2015 int regbase
, words
, max
;
2019 arg_words
= &cum
->arg_words
;
2020 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2021 max
= MAX_ARGS_IN_REGISTERS
;
2023 words
= (((mode
!= BLKmode
)
2024 ? (int) GET_MODE_SIZE (mode
)
2025 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2027 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
2029 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2030 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2033 if (*arg_words
+ words
> max
)
2036 regno
= regbase
+ *arg_words
;
2038 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2039 cfun
->machine
->need_a7_copy
= true;
2041 return gen_rtx_REG (mode
, regno
);
2046 function_arg_boundary (enum machine_mode mode
, tree type
)
2048 unsigned int alignment
;
2050 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2051 if (alignment
< PARM_BOUNDARY
)
2052 alignment
= PARM_BOUNDARY
;
2053 if (alignment
> STACK_BOUNDARY
)
2054 alignment
= STACK_BOUNDARY
;
2060 xtensa_return_in_msb (const_tree valtype
)
2062 return (TARGET_BIG_ENDIAN
2063 && AGGREGATE_TYPE_P (valtype
)
2064 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2069 override_options (void)
2072 enum machine_mode mode
;
2074 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2075 error ("boolean registers required for the floating-point option");
2077 /* Set up array giving whether a given register can hold a given mode. */
2078 for (mode
= VOIDmode
;
2079 mode
!= MAX_MACHINE_MODE
;
2080 mode
= (enum machine_mode
) ((int) mode
+ 1))
2082 int size
= GET_MODE_SIZE (mode
);
2083 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2085 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2089 if (ACC_REG_P (regno
))
2090 temp
= (TARGET_MAC16
2091 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2092 else if (GP_REG_P (regno
))
2093 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2094 else if (FP_REG_P (regno
))
2095 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2096 else if (BR_REG_P (regno
))
2097 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2101 xtensa_hard_regno_mode_ok
[(int) mode
][regno
] = temp
;
2105 init_machine_status
= xtensa_init_machine_status
;
2107 /* Check PIC settings. PIC is only supported when using L32R
2108 instructions, and some targets need to always use PIC. */
2109 if (flag_pic
&& TARGET_CONST16
)
2110 error ("-f%s is not supported with CONST16 instructions",
2111 (flag_pic
> 1 ? "PIC" : "pic"));
2112 else if (TARGET_FORCE_NO_PIC
)
2114 else if (XTENSA_ALWAYS_PIC
)
2117 error ("PIC is required but not supported with CONST16 instructions");
2120 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2123 if (flag_pic
&& !flag_pie
)
2126 /* Hot/cold partitioning does not work on this architecture, because of
2127 constant pools (the load instruction cannot necessarily reach that far).
2128 Therefore disable it on this architecture. */
2129 if (flag_reorder_blocks_and_partition
)
2131 flag_reorder_blocks_and_partition
= 0;
2132 flag_reorder_blocks
= 1;
2137 /* A C compound statement to output to stdio stream STREAM the
2138 assembler syntax for an instruction operand X. X is an RTL
2141 CODE is a value that can be used to specify one of several ways
2142 of printing the operand. It is used when identical operands
2143 must be printed differently depending on the context. CODE
2144 comes from the '%' specification that was used to request
2145 printing of the operand. If the specification was just '%DIGIT'
2146 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2147 is the ASCII code for LTR.
2149 If X is a register, this macro should print the register's name.
2150 The names can be found in an array 'reg_names' whose type is
2151 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2153 When the machine description has a specification '%PUNCT' (a '%'
2154 followed by a punctuation character), this macro is called with
2155 a null pointer for X and the punctuation character for CODE.
2157 'a', 'c', 'l', and 'n' are reserved.
2159 The Xtensa specific codes are:
2161 'd' CONST_INT, print as signed decimal
2162 'x' CONST_INT, print as signed hexadecimal
2163 'K' CONST_INT, print number of bits in mask for EXTUI
2164 'R' CONST_INT, print (X & 0x1f)
2165 'L' CONST_INT, print ((32 - X) & 0x1f)
2166 'D' REG, print second register of double-word register operand
2167 'N' MEM, print address of next word following a memory operand
2168 'v' MEM, if memory reference is volatile, output a MEMW before it
2169 't' any constant, add "@h" suffix for top 16 bits
2170 'b' any constant, add "@l" suffix for bottom 16 bits
2174 printx (FILE *file
, signed int val
)
2176 /* Print a hexadecimal value in a nice way. */
2177 if ((val
> -0xa) && (val
< 0xa))
2178 fprintf (file
, "%d", val
);
2180 fprintf (file
, "-0x%x", -val
);
2182 fprintf (file
, "0x%x", val
);
2187 print_operand (FILE *file
, rtx x
, int letter
)
2190 error ("PRINT_OPERAND null pointer");
2195 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2196 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2198 output_operand_lossage ("invalid %%D value");
2202 if (GET_CODE (x
) == MEM
)
2204 /* For a volatile memory reference, emit a MEMW before the
2206 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2207 fprintf (file
, "memw\n\t");
2210 output_operand_lossage ("invalid %%v value");
2214 if (GET_CODE (x
) == MEM
2215 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2217 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? SFmode
: SImode
, 4);
2218 output_address (XEXP (x
, 0));
2221 output_operand_lossage ("invalid %%N value");
2225 if (GET_CODE (x
) == CONST_INT
)
2228 unsigned val
= INTVAL (x
);
2234 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2235 fatal_insn ("invalid mask", x
);
2237 fprintf (file
, "%d", num_bits
);
2240 output_operand_lossage ("invalid %%K value");
2244 if (GET_CODE (x
) == CONST_INT
)
2245 fprintf (file
, "%ld", (32 - INTVAL (x
)) & 0x1f);
2247 output_operand_lossage ("invalid %%L value");
2251 if (GET_CODE (x
) == CONST_INT
)
2252 fprintf (file
, "%ld", INTVAL (x
) & 0x1f);
2254 output_operand_lossage ("invalid %%R value");
2258 if (GET_CODE (x
) == CONST_INT
)
2259 printx (file
, INTVAL (x
));
2261 output_operand_lossage ("invalid %%x value");
2265 if (GET_CODE (x
) == CONST_INT
)
2266 fprintf (file
, "%ld", INTVAL (x
));
2268 output_operand_lossage ("invalid %%d value");
2273 if (GET_CODE (x
) == CONST_INT
)
2275 printx (file
, INTVAL (x
));
2276 fputs (letter
== 't' ? "@h" : "@l", file
);
2278 else if (GET_CODE (x
) == CONST_DOUBLE
)
2281 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2282 if (GET_MODE (x
) == SFmode
)
2285 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
2286 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2289 output_operand_lossage ("invalid %%t/%%b value");
2291 else if (GET_CODE (x
) == CONST
)
2293 /* X must be a symbolic constant on ELF. Write an expression
2294 suitable for 'const16' that sets the high or low 16 bits. */
2295 if (GET_CODE (XEXP (x
, 0)) != PLUS
2296 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2297 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2298 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2299 output_operand_lossage ("invalid %%t/%%b value");
2300 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2301 fputs (letter
== 't' ? "@h" : "@l", file
);
2302 /* There must be a non-alphanumeric character between 'h' or 'l'
2303 and the number. The '-' is added by print_operand() already. */
2304 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2306 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2310 output_addr_const (file
, x
);
2311 fputs (letter
== 't' ? "@h" : "@l", file
);
2316 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2317 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2318 else if (GET_CODE (x
) == MEM
)
2319 output_address (XEXP (x
, 0));
2320 else if (GET_CODE (x
) == CONST_INT
)
2321 fprintf (file
, "%ld", INTVAL (x
));
2323 output_addr_const (file
, x
);
2328 /* A C compound statement to output to stdio stream STREAM the
2329 assembler syntax for an instruction operand that is a memory
2330 reference whose address is ADDR. ADDR is an RTL expression. */
2333 print_operand_address (FILE *file
, rtx addr
)
2336 error ("PRINT_OPERAND_ADDRESS, null pointer");
2338 switch (GET_CODE (addr
))
2341 fatal_insn ("invalid address", addr
);
2345 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2351 rtx offset
= (rtx
)0;
2352 rtx arg0
= XEXP (addr
, 0);
2353 rtx arg1
= XEXP (addr
, 1);
2355 if (GET_CODE (arg0
) == REG
)
2360 else if (GET_CODE (arg1
) == REG
)
2366 fatal_insn ("no register in address", addr
);
2368 if (CONSTANT_P (offset
))
2370 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2371 output_addr_const (file
, offset
);
2374 fatal_insn ("address offset not a constant", addr
);
2382 output_addr_const (file
, addr
);
2389 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2391 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2393 switch (XINT (x
, 1))
2396 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2397 fputs ("@TPOFF", fp
);
2400 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2401 fputs ("@DTPOFF", fp
);
2406 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2420 xtensa_output_literal (FILE *file
, rtx x
, enum machine_mode mode
, int labelno
)
2427 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2429 switch (GET_MODE_CLASS (mode
))
2432 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
2434 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2438 REAL_VALUE_TO_TARGET_SINGLE (r
, value_long
[0]);
2439 if (HOST_BITS_PER_LONG
> 32)
2440 value_long
[0] &= 0xffffffff;
2441 fprintf (file
, "0x%08lx\n", value_long
[0]);
2445 REAL_VALUE_TO_TARGET_DOUBLE (r
, value_long
);
2446 if (HOST_BITS_PER_LONG
> 32)
2448 value_long
[0] &= 0xffffffff;
2449 value_long
[1] &= 0xffffffff;
2451 fprintf (file
, "0x%08lx, 0x%08lx\n",
2452 value_long
[0], value_long
[1]);
2462 case MODE_PARTIAL_INT
:
2463 size
= GET_MODE_SIZE (mode
);
2467 output_addr_const (file
, x
);
2472 split_double (x
, &first
, &second
);
2473 output_addr_const (file
, first
);
2475 output_addr_const (file
, second
);
2490 /* Return the bytes needed to compute the frame pointer from the current
2493 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2494 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2497 compute_frame_size (int size
)
2499 /* Add space for the incoming static chain value. */
2500 if (cfun
->static_chain_decl
!= NULL
)
2501 size
+= (1 * UNITS_PER_WORD
);
2503 xtensa_current_frame_size
=
2504 XTENSA_STACK_ALIGN (size
2505 + crtl
->outgoing_args_size
2506 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2507 return xtensa_current_frame_size
;
2512 xtensa_frame_pointer_required (void)
2514 /* The code to expand builtin_frame_addr and builtin_return_addr
2515 currently uses the hard_frame_pointer instead of frame_pointer.
2516 This seems wrong but maybe it's necessary for other architectures.
2517 This function is derived from the i386 code. */
2519 if (cfun
->machine
->accesses_prev_frame
)
2526 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2527 and the total number of words must be a multiple of 128 bits. */
2528 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2531 xtensa_expand_prologue (void)
2533 HOST_WIDE_INT total_size
;
2537 total_size
= compute_frame_size (get_frame_size ());
2538 size_rtx
= GEN_INT (total_size
);
2540 if (total_size
< (1 << (12+3)))
2541 insn
= emit_insn (gen_entry (size_rtx
));
2544 /* Use a8 as a temporary since a0-a7 may be live. */
2545 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2546 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
2547 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2548 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2549 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
2552 if (frame_pointer_needed
)
2554 if (cfun
->machine
->set_frame_ptr_insn
)
2558 push_topmost_sequence ();
2559 first
= get_insns ();
2560 pop_topmost_sequence ();
2562 /* For all instructions prior to set_frame_ptr_insn, replace
2563 hard_frame_pointer references with stack_pointer. */
2565 insn
!= cfun
->machine
->set_frame_ptr_insn
;
2566 insn
= NEXT_INSN (insn
))
2570 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2571 hard_frame_pointer_rtx
,
2573 df_insn_rescan (insn
);
2578 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2579 stack_pointer_rtx
));
2582 /* Create a note to describe the CFA. Because this is only used to set
2583 DW_AT_frame_base for debug info, don't bother tracking changes through
2584 each instruction in the prologue. It just takes up space. */
2585 note_rtx
= gen_rtx_SET (VOIDmode
, (frame_pointer_needed
2586 ? hard_frame_pointer_rtx
2587 : stack_pointer_rtx
),
2588 plus_constant (stack_pointer_rtx
, -total_size
));
2589 RTX_FRAME_RELATED_P (insn
) = 1;
2590 REG_NOTES (insn
) = gen_rtx_EXPR_LIST (REG_FRAME_RELATED_EXPR
,
2591 note_rtx
, REG_NOTES (insn
));
2595 /* Clear variables at function end. */
2598 xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
2599 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
2601 xtensa_current_frame_size
= 0;
2606 xtensa_return_addr (int count
, rtx frame
)
2608 rtx result
, retaddr
, curaddr
, label
;
2611 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
2614 rtx addr
= plus_constant (frame
, -4 * UNITS_PER_WORD
);
2615 addr
= memory_address (Pmode
, addr
);
2616 retaddr
= gen_reg_rtx (Pmode
);
2617 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
2620 /* The 2 most-significant bits of the return address on Xtensa hold
2621 the register window size. To get the real return address, these
2622 bits must be replaced with the high bits from some address in the
2625 /* Get the 2 high bits of a local label in the code. */
2626 curaddr
= gen_reg_rtx (Pmode
);
2627 label
= gen_label_rtx ();
2629 LABEL_PRESERVE_P (label
) = 1;
2630 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
2631 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
2632 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
2634 /* Clear the 2 high bits of the return address. */
2635 result
= gen_reg_rtx (Pmode
);
2636 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
2637 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
2639 /* Combine them to get the result. */
2640 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
2645 /* Create the va_list data type.
2647 This structure is set up by __builtin_saveregs. The __va_reg field
2648 points to a stack-allocated region holding the contents of the
2649 incoming argument registers. The __va_ndx field is an index
2650 initialized to the position of the first unnamed (variable)
2651 argument. This same index is also used to address the arguments
2652 passed in memory. Thus, the __va_stk field is initialized to point
2653 to the position of the first argument in memory offset to account
2654 for the arguments passed in registers and to account for the size
2655 of the argument registers not being 16-byte aligned. E.G., there
2656 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2657 for the first stack argument to have the maximal alignment of 16
2658 bytes, so we offset the __va_stk address by 32 bytes so that
2659 __va_stk[32] references the first argument on the stack. */
2662 xtensa_build_builtin_va_list (void)
2664 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
2666 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2667 type_decl
= build_decl (BUILTINS_LOCATION
,
2668 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
2670 f_stk
= build_decl (BUILTINS_LOCATION
,
2671 FIELD_DECL
, get_identifier ("__va_stk"),
2673 f_reg
= build_decl (BUILTINS_LOCATION
,
2674 FIELD_DECL
, get_identifier ("__va_reg"),
2676 f_ndx
= build_decl (BUILTINS_LOCATION
,
2677 FIELD_DECL
, get_identifier ("__va_ndx"),
2680 DECL_FIELD_CONTEXT (f_stk
) = record
;
2681 DECL_FIELD_CONTEXT (f_reg
) = record
;
2682 DECL_FIELD_CONTEXT (f_ndx
) = record
;
2684 TREE_CHAIN (record
) = type_decl
;
2685 TYPE_NAME (record
) = type_decl
;
2686 TYPE_FIELDS (record
) = f_stk
;
2687 TREE_CHAIN (f_stk
) = f_reg
;
2688 TREE_CHAIN (f_reg
) = f_ndx
;
2690 layout_type (record
);
2695 /* Save the incoming argument registers on the stack. Returns the
2696 address of the saved registers. */
2699 xtensa_builtin_saveregs (void)
2702 int arg_words
= crtl
->args
.info
.arg_words
;
2703 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
2708 /* Allocate the general-purpose register space. */
2709 gp_regs
= assign_stack_local
2710 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
2711 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
2713 /* Now store the incoming registers. */
2714 cfun
->machine
->need_a7_copy
= true;
2715 cfun
->machine
->vararg_a7
= true;
2716 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
2717 adjust_address (gp_regs
, BLKmode
,
2718 arg_words
* UNITS_PER_WORD
),
2720 gcc_assert (cfun
->machine
->vararg_a7_copy
!= 0);
2721 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
2723 return XEXP (gp_regs
, 0);
2727 /* Implement `va_start' for varargs and stdarg. We look at the
2728 current function to fill in an initial va_list. */
2731 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
2739 arg_words
= crtl
->args
.info
.arg_words
;
2741 f_stk
= TYPE_FIELDS (va_list_type_node
);
2742 f_reg
= TREE_CHAIN (f_stk
);
2743 f_ndx
= TREE_CHAIN (f_reg
);
2745 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
2746 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
2748 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
2751 /* Call __builtin_saveregs; save the result in __va_reg */
2752 u
= make_tree (sizetype
, expand_builtin_saveregs ());
2753 u
= fold_convert (ptr_type_node
, u
);
2754 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
2755 TREE_SIDE_EFFECTS (t
) = 1;
2756 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2758 /* Set the __va_stk member to ($arg_ptr - 32). */
2759 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
2760 u
= fold_build2 (POINTER_PLUS_EXPR
, ptr_type_node
, u
, size_int (-32));
2761 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
2762 TREE_SIDE_EFFECTS (t
) = 1;
2763 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2765 /* Set the __va_ndx member. If the first variable argument is on
2766 the stack, adjust __va_ndx by 2 words to account for the extra
2767 alignment offset for __va_stk. */
2768 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
2770 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
2771 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
2772 TREE_SIDE_EFFECTS (t
) = 1;
2773 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2777 /* Implement `va_arg'. */
2780 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
2781 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
2786 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
2787 tree lab_false
, lab_over
, lab_false2
;
2790 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
2792 type
= build_pointer_type (type
);
2794 /* Handle complex values as separate real and imaginary parts. */
2795 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2797 tree real_part
, imag_part
;
2799 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
2801 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
2803 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
2806 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
2808 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
2811 f_stk
= TYPE_FIELDS (va_list_type_node
);
2812 f_reg
= TREE_CHAIN (f_stk
);
2813 f_ndx
= TREE_CHAIN (f_reg
);
2815 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
2817 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
2819 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
2822 type_size
= size_in_bytes (type
);
2823 va_size
= round_up (type_size
, UNITS_PER_WORD
);
2824 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
2827 /* First align __va_ndx if necessary for this arg:
2829 orig_ndx = (AP).__va_ndx;
2830 if (__alignof__ (TYPE) > 4 )
2831 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2832 & -__alignof__ (TYPE)); */
2834 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
2836 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
2838 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
2840 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
2841 build_int_cst (integer_type_node
, align
- 1));
2842 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
2843 build_int_cst (integer_type_node
, -align
));
2844 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
2848 /* Increment __va_ndx to point past the argument:
2850 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2852 t
= fold_convert (integer_type_node
, va_size
);
2853 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
2854 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
2857 /* Check if the argument is in registers:
2859 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2860 && !must_pass_in_stack (type))
2861 __array = (AP).__va_reg; */
2863 array
= create_tmp_var (ptr_type_node
, NULL
);
2866 if (!targetm
.calls
.must_pass_in_stack (TYPE_MODE (type
), type
))
2868 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
2869 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
2871 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
2872 build_int_cst (integer_type_node
,
2873 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
2874 t
= build3 (COND_EXPR
, void_type_node
, t
,
2875 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
2877 gimplify_and_add (t
, pre_p
);
2879 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
2881 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
2882 gimplify_and_add (t
, pre_p
);
2884 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
2885 gimplify_and_add (t
, pre_p
);
2889 /* ...otherwise, the argument is on the stack (never split between
2890 registers and the stack -- change __va_ndx if necessary):
2894 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2895 (AP).__va_ndx = 32 + __va_size (TYPE);
2896 __array = (AP).__va_stk;
2899 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
2901 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
2902 build_int_cst (integer_type_node
,
2903 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
2904 t
= build3 (COND_EXPR
, void_type_node
, t
,
2905 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
2907 gimplify_and_add (t
, pre_p
);
2909 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
2910 t
= fold_convert (integer_type_node
, t
);
2911 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
2913 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
2914 gimplify_and_add (t
, pre_p
);
2916 gimplify_assign (array
, stk
, pre_p
);
2920 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
2921 gimplify_and_add (t
, pre_p
);
2925 /* Given the base array pointer (__array) and index to the subsequent
2926 argument (__va_ndx), find the address:
2928 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2932 The results are endian-dependent because values smaller than one word
2933 are aligned differently. */
2936 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
2938 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
2939 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
2940 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
2941 unshare_expr (type_size
));
2945 size
= unshare_expr (va_size
);
2947 t
= fold_convert (sizetype
, unshare_expr (ndx
));
2948 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
2949 addr
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, unshare_expr (array
), t
);
2951 addr
= fold_convert (build_pointer_type (type
), addr
);
2953 addr
= build_va_arg_indirect_ref (addr
);
2954 return build_va_arg_indirect_ref (addr
);
2962 XTENSA_BUILTIN_UMULSIDI3
,
2963 XTENSA_BUILTIN_THREAD_POINTER
,
2964 XTENSA_BUILTIN_SET_THREAD_POINTER
,
2970 xtensa_init_builtins (void)
2974 ftype
= build_function_type_list (unsigned_intDI_type_node
,
2975 unsigned_intSI_type_node
,
2976 unsigned_intSI_type_node
, NULL_TREE
);
2978 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
2979 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
2980 "__umulsidi3", NULL_TREE
);
2981 TREE_NOTHROW (decl
) = 1;
2982 TREE_READONLY (decl
) = 1;
2984 if (TARGET_THREADPTR
)
2986 ftype
= build_function_type (ptr_type_node
, void_list_node
);
2987 decl
= add_builtin_function ("__builtin_thread_pointer", ftype
,
2988 XTENSA_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
2990 TREE_READONLY (decl
) = 1;
2991 TREE_NOTHROW (decl
) = 1;
2993 ftype
= build_function_type_list (void_type_node
, ptr_type_node
,
2995 decl
= add_builtin_function ("__builtin_set_thread_pointer", ftype
,
2996 XTENSA_BUILTIN_SET_THREAD_POINTER
,
2997 BUILT_IN_MD
, NULL
, NULL_TREE
);
2998 TREE_NOTHROW (decl
) = 1;
3004 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3005 bool ignore ATTRIBUTE_UNUSED
)
3007 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3012 case XTENSA_BUILTIN_UMULSIDI3
:
3015 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3016 || TARGET_MUL32_HIGH
)
3017 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3018 fold_convert (unsigned_intDI_type_node
, arg0
),
3019 fold_convert (unsigned_intDI_type_node
, arg1
));
3022 case XTENSA_BUILTIN_THREAD_POINTER
:
3023 case XTENSA_BUILTIN_SET_THREAD_POINTER
:
3027 internal_error ("bad builtin code");
3036 xtensa_expand_builtin (tree exp
, rtx target
,
3037 rtx subtarget ATTRIBUTE_UNUSED
,
3038 enum machine_mode mode ATTRIBUTE_UNUSED
,
3041 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3042 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3047 case XTENSA_BUILTIN_UMULSIDI3
:
3048 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3049 __umulsidi3 function when the Xtensa configuration can directly
3050 implement it. If not, just call the function. */
3051 return expand_call (exp
, target
, ignore
);
3053 case XTENSA_BUILTIN_THREAD_POINTER
:
3054 if (!target
|| !register_operand (target
, Pmode
))
3055 target
= gen_reg_rtx (Pmode
);
3056 emit_insn (gen_load_tp (target
));
3059 case XTENSA_BUILTIN_SET_THREAD_POINTER
:
3060 arg
= expand_normal (CALL_EXPR_ARG (exp
, 0));
3061 if (!register_operand (arg
, Pmode
))
3062 arg
= copy_to_mode_reg (Pmode
, arg
);
3063 emit_insn (gen_set_tp (arg
));
3067 internal_error ("bad builtin code");
3074 xtensa_preferred_reload_class (rtx x
, enum reg_class rclass
, int isoutput
)
3076 if (!isoutput
&& CONSTANT_P (x
) && GET_CODE (x
) == CONST_DOUBLE
)
3079 /* Don't use the stack pointer or hard frame pointer for reloads!
3080 The hard frame pointer would normally be OK except that it may
3081 briefly hold an incoming argument in the prologue, and reload
3082 won't know that it is live because the hard frame pointer is
3083 treated specially. */
3085 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3093 xtensa_secondary_reload (bool in_p
, rtx x
, enum reg_class rclass
,
3094 enum machine_mode mode
, secondary_reload_info
*sri
)
3098 if (in_p
&& constantpool_mem_p (x
))
3100 if (rclass
== FP_REGS
)
3104 sri
->icode
= CODE_FOR_reloadqi_literal
;
3105 else if (mode
== HImode
)
3106 sri
->icode
= CODE_FOR_reloadhi_literal
;
3109 regno
= xt_true_regnum (x
);
3110 if (ACC_REG_P (regno
))
3111 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3112 if (rclass
== ACC_REG
)
3113 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3120 order_regs_for_local_alloc (void)
3122 if (!leaf_function_p ())
3124 memcpy (reg_alloc_order
, reg_nonleaf_alloc_order
,
3125 FIRST_PSEUDO_REGISTER
* sizeof (int));
3129 int i
, num_arg_regs
;
3132 /* Use the AR registers in increasing order (skipping a0 and a1)
3133 but save the incoming argument registers for a last resort. */
3134 num_arg_regs
= crtl
->args
.info
.arg_words
;
3135 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
3136 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
3137 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
3138 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
3139 for (i
= 0; i
< num_arg_regs
; i
++)
3140 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
3142 /* List the coprocessor registers in order. */
3143 for (i
= 0; i
< BR_REG_NUM
; i
++)
3144 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
3146 /* List the FP registers in order for now. */
3147 for (i
= 0; i
< 16; i
++)
3148 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
3150 /* GCC requires that we list *all* the registers.... */
3151 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
3152 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
3153 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
3154 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
3156 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
3161 /* Some Xtensa targets support multiple bss sections. If the section
3162 name ends with ".bss", add SECTION_BSS to the flags. */
3165 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
3167 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
3170 suffix
= strrchr (name
, '.');
3171 if (suffix
&& strcmp (suffix
, ".bss") == 0)
3173 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
3174 && DECL_INITIAL (decl
) == NULL_TREE
))
3175 flags
|= SECTION_BSS
; /* @nobits */
3177 warning (0, "only uninitialized variables can be placed in a "
3185 /* The literal pool stays with the function. */
3188 xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED
,
3189 rtx x ATTRIBUTE_UNUSED
,
3190 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
3192 return function_section (current_function_decl
);
3196 /* Compute a (partial) cost for rtx X. Return true if the complete
3197 cost has been computed, and false if subexpressions should be
3198 scanned. In either case, *TOTAL contains the cost result. */
3201 xtensa_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
3202 bool speed ATTRIBUTE_UNUSED
)
3210 if (xtensa_simm12b (INTVAL (x
)))
3217 if (xtensa_simm8 (INTVAL (x
))
3218 || xtensa_simm8x256 (INTVAL (x
)))
3225 if (xtensa_mask_immediate (INTVAL (x
)))
3232 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
3243 /* No way to tell if X is the 2nd operand so be conservative. */
3246 if (xtensa_simm12b (INTVAL (x
)))
3248 else if (TARGET_CONST16
)
3249 *total
= COSTS_N_INSNS (2);
3258 *total
= COSTS_N_INSNS (2);
3265 *total
= COSTS_N_INSNS (4);
3273 (GET_MODE_SIZE (GET_MODE (x
)) > UNITS_PER_WORD
) ? 2 : 1;
3275 if (memory_address_p (GET_MODE (x
), XEXP ((x
), 0)))
3276 *total
= COSTS_N_INSNS (num_words
);
3278 *total
= COSTS_N_INSNS (2*num_words
);
3284 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
3288 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
3292 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 3 : 2);
3298 if (GET_MODE (x
) == DImode
)
3299 *total
= COSTS_N_INSNS (2);
3301 *total
= COSTS_N_INSNS (1);
3307 if (GET_MODE (x
) == DImode
)
3308 *total
= COSTS_N_INSNS (50);
3310 *total
= COSTS_N_INSNS (1);
3315 enum machine_mode xmode
= GET_MODE (x
);
3316 if (xmode
== SFmode
)
3317 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3318 else if (xmode
== DFmode
)
3319 *total
= COSTS_N_INSNS (50);
3321 *total
= COSTS_N_INSNS (4);
3328 enum machine_mode xmode
= GET_MODE (x
);
3329 if (xmode
== SFmode
)
3330 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3331 else if (xmode
== DFmode
|| xmode
== DImode
)
3332 *total
= COSTS_N_INSNS (50);
3334 *total
= COSTS_N_INSNS (1);
3339 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 4 : 2);
3344 enum machine_mode xmode
= GET_MODE (x
);
3345 if (xmode
== SFmode
)
3346 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3347 else if (xmode
== DFmode
)
3348 *total
= COSTS_N_INSNS (50);
3349 else if (xmode
== DImode
)
3350 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
3351 else if (TARGET_MUL32
)
3352 *total
= COSTS_N_INSNS (4);
3353 else if (TARGET_MAC16
)
3354 *total
= COSTS_N_INSNS (16);
3355 else if (TARGET_MUL16
)
3356 *total
= COSTS_N_INSNS (12);
3358 *total
= COSTS_N_INSNS (50);
3365 enum machine_mode xmode
= GET_MODE (x
);
3366 if (xmode
== SFmode
)
3368 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3371 else if (xmode
== DFmode
)
3373 *total
= COSTS_N_INSNS (50);
3382 enum machine_mode xmode
= GET_MODE (x
);
3383 if (xmode
== DImode
)
3384 *total
= COSTS_N_INSNS (50);
3385 else if (TARGET_DIV32
)
3386 *total
= COSTS_N_INSNS (32);
3388 *total
= COSTS_N_INSNS (50);
3393 if (GET_MODE (x
) == SFmode
)
3394 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3396 *total
= COSTS_N_INSNS (50);
3403 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3408 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3413 *total
= COSTS_N_INSNS (1);
3421 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3424 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3426 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
3427 > 4 * UNITS_PER_WORD
);
3430 /* Worker function for TARGET_FUNCTION_VALUE. */
3433 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
3436 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
3437 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
3438 ? SImode
: TYPE_MODE (valtype
),
3439 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
3442 /* The static chain is passed in memory. Provide rtx giving 'mem'
3443 expressions that denote where they are stored. */
3446 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl
), bool incoming_p
)
3448 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
3449 return gen_frame_mem (Pmode
, plus_constant (base
, -5 * UNITS_PER_WORD
));
3453 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3454 instruction with a minimal stack frame in order to get some free
3455 registers. Once the actual call target is known, the proper stack frame
3456 size is extracted from the ENTRY instruction at the target and the
3457 current frame is adjusted to match. The trampoline then transfers
3458 control to the instruction following the ENTRY at the target. Note:
3459 this assumes that the target begins with an ENTRY instruction. */
3462 xtensa_asm_trampoline_template (FILE *stream
)
3464 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3466 fprintf (stream
, "\t.begin no-transform\n");
3467 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
3471 /* Save the return address. */
3472 fprintf (stream
, "\tmov\ta10, a0\n");
3474 /* Use a CALL0 instruction to skip past the constants and in the
3475 process get the PC into A0. This allows PC-relative access to
3476 the constants without relying on L32R. */
3477 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
3480 fprintf (stream
, "\tj\t.Lskipconsts\n");
3482 fprintf (stream
, "\t.align\t4\n");
3483 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
3484 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
3485 fprintf (stream
, ".Lskipconsts:\n");
3487 /* Load the static chain and function address from the trampoline. */
3490 fprintf (stream
, "\taddi\ta0, a0, 3\n");
3491 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
3492 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
3496 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
3497 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
3500 /* Store the static chain. */
3501 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
3503 /* Set the proper stack pointer value. */
3504 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
3505 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
3506 TARGET_BIG_ENDIAN
? 8 : 12);
3507 fprintf (stream
, "\tslli\ta9, a9, 3\n");
3508 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
3509 fprintf (stream
, "\tsub\ta9, sp, a9\n");
3510 fprintf (stream
, "\tmovsp\tsp, a9\n");
3513 /* Restore the return address. */
3514 fprintf (stream
, "\tmov\ta0, a10\n");
3516 /* Jump to the instruction following the ENTRY. */
3517 fprintf (stream
, "\taddi\ta8, a8, 3\n");
3518 fprintf (stream
, "\tjx\ta8\n");
3520 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3522 fprintf (stream
, "\t.byte\t0\n");
3524 fprintf (stream
, "\tnop\n");
3526 fprintf (stream
, "\t.end no-transform\n");
3530 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
3532 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
3533 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3534 int chain_off
= use_call0
? 12 : 8;
3535 int func_off
= use_call0
? 16 : 12;
3537 emit_block_move (m_tramp
, assemble_trampoline_template (),
3538 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3540 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
3541 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
3542 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
3543 0, VOIDmode
, 1, XEXP (m_tramp
, 0), Pmode
);
3547 #include "gt-xtensa.h"