1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
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"
43 #include "diagnostic-core.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 void xtensa_option_override (void);
121 static enum internal_test
map_test_to_internal_test (enum rtx_code
);
122 static rtx
gen_int_relational (enum rtx_code
, rtx
, rtx
, int *);
123 static rtx
gen_float_relational (enum rtx_code
, rtx
, rtx
);
124 static rtx
gen_conditional_move (enum rtx_code
, enum machine_mode
, rtx
, rtx
);
125 static rtx
fixup_subreg_mem (rtx
);
126 static struct machine_function
* xtensa_init_machine_status (void);
127 static rtx
xtensa_legitimize_tls_address (rtx
);
128 static rtx
xtensa_legitimize_address (rtx
, rtx
, enum machine_mode
);
129 static bool xtensa_return_in_msb (const_tree
);
130 static void printx (FILE *, signed int);
131 static void xtensa_function_epilogue (FILE *, HOST_WIDE_INT
);
132 static rtx
xtensa_builtin_saveregs (void);
133 static bool xtensa_legitimate_address_p (enum machine_mode
, rtx
, bool);
134 static unsigned int xtensa_multibss_section_type_flags (tree
, const char *,
135 int) ATTRIBUTE_UNUSED
;
136 static section
*xtensa_select_rtx_section (enum machine_mode
, rtx
,
137 unsigned HOST_WIDE_INT
);
138 static bool xtensa_rtx_costs (rtx
, int, int, int *, bool);
139 static tree
xtensa_build_builtin_va_list (void);
140 static bool xtensa_return_in_memory (const_tree
, const_tree
);
141 static tree
xtensa_gimplify_va_arg_expr (tree
, tree
, gimple_seq
*,
143 static void xtensa_function_arg_advance (CUMULATIVE_ARGS
*, enum machine_mode
,
145 static rtx
xtensa_function_arg (CUMULATIVE_ARGS
*, enum machine_mode
,
147 static rtx
xtensa_function_incoming_arg (CUMULATIVE_ARGS
*,
148 enum machine_mode
, const_tree
, bool);
149 static rtx
xtensa_function_value (const_tree
, const_tree
, bool);
150 static unsigned int xtensa_function_arg_boundary (enum machine_mode
,
152 static void xtensa_init_builtins (void);
153 static tree
xtensa_fold_builtin (tree
, int, tree
*, bool);
154 static rtx
xtensa_expand_builtin (tree
, rtx
, rtx
, enum machine_mode
, int);
155 static void xtensa_va_start (tree
, rtx
);
156 static bool xtensa_frame_pointer_required (void);
157 static rtx
xtensa_static_chain (const_tree
, bool);
158 static void xtensa_asm_trampoline_template (FILE *);
159 static void xtensa_trampoline_init (rtx
, tree
, rtx
);
161 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
164 /* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
166 static const struct default_options xtensa_option_optimization_table
[] =
168 { OPT_LEVELS_1_PLUS
, OPT_fomit_frame_pointer
, NULL
, 1 },
169 /* Reordering blocks for Xtensa is not a good idea unless the
170 compiler understands the range of conditional branches.
171 Currently all branch relaxation for Xtensa is handled in the
172 assembler, so GCC cannot do a good job of reordering blocks.
173 Do not enable reordering unless it is explicitly requested. */
174 { OPT_LEVELS_ALL
, OPT_freorder_blocks
, NULL
, 0 },
175 { OPT_LEVELS_NONE
, 0, NULL
, 0 }
179 /* This macro generates the assembly code for function exit,
180 on machines that need it. If FUNCTION_EPILOGUE is not defined
181 then individual return instructions are generated for each
182 return statement. Args are same as for FUNCTION_PROLOGUE. */
184 #undef TARGET_ASM_FUNCTION_EPILOGUE
185 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
187 /* These hooks specify assembly directives for creating certain kinds
188 of integer object. */
190 #undef TARGET_ASM_ALIGNED_SI_OP
191 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
193 #undef TARGET_ASM_SELECT_RTX_SECTION
194 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
196 #undef TARGET_DEFAULT_TARGET_FLAGS
197 #define TARGET_DEFAULT_TARGET_FLAGS (TARGET_DEFAULT)
199 #undef TARGET_LEGITIMIZE_ADDRESS
200 #define TARGET_LEGITIMIZE_ADDRESS xtensa_legitimize_address
202 #undef TARGET_RTX_COSTS
203 #define TARGET_RTX_COSTS xtensa_rtx_costs
204 #undef TARGET_ADDRESS_COST
205 #define TARGET_ADDRESS_COST hook_int_rtx_bool_0
207 #undef TARGET_BUILD_BUILTIN_VA_LIST
208 #define TARGET_BUILD_BUILTIN_VA_LIST xtensa_build_builtin_va_list
210 #undef TARGET_EXPAND_BUILTIN_VA_START
211 #define TARGET_EXPAND_BUILTIN_VA_START xtensa_va_start
213 #undef TARGET_PROMOTE_FUNCTION_MODE
214 #define TARGET_PROMOTE_FUNCTION_MODE default_promote_function_mode_always_promote
215 #undef TARGET_PROMOTE_PROTOTYPES
216 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
218 #undef TARGET_RETURN_IN_MEMORY
219 #define TARGET_RETURN_IN_MEMORY xtensa_return_in_memory
220 #undef TARGET_FUNCTION_VALUE
221 #define TARGET_FUNCTION_VALUE xtensa_function_value
222 #undef TARGET_SPLIT_COMPLEX_ARG
223 #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true
224 #undef TARGET_MUST_PASS_IN_STACK
225 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
226 #undef TARGET_FUNCTION_ARG_ADVANCE
227 #define TARGET_FUNCTION_ARG_ADVANCE xtensa_function_arg_advance
228 #undef TARGET_FUNCTION_ARG
229 #define TARGET_FUNCTION_ARG xtensa_function_arg
230 #undef TARGET_FUNCTION_INCOMING_ARG
231 #define TARGET_FUNCTION_INCOMING_ARG xtensa_function_incoming_arg
232 #undef TARGET_FUNCTION_ARG_BOUNDARY
233 #define TARGET_FUNCTION_ARG_BOUNDARY xtensa_function_arg_boundary
235 #undef TARGET_EXPAND_BUILTIN_SAVEREGS
236 #define TARGET_EXPAND_BUILTIN_SAVEREGS xtensa_builtin_saveregs
237 #undef TARGET_GIMPLIFY_VA_ARG_EXPR
238 #define TARGET_GIMPLIFY_VA_ARG_EXPR xtensa_gimplify_va_arg_expr
240 #undef TARGET_RETURN_IN_MSB
241 #define TARGET_RETURN_IN_MSB xtensa_return_in_msb
243 #undef TARGET_INIT_BUILTINS
244 #define TARGET_INIT_BUILTINS xtensa_init_builtins
245 #undef TARGET_FOLD_BUILTIN
246 #define TARGET_FOLD_BUILTIN xtensa_fold_builtin
247 #undef TARGET_EXPAND_BUILTIN
248 #define TARGET_EXPAND_BUILTIN xtensa_expand_builtin
250 #undef TARGET_SECONDARY_RELOAD
251 #define TARGET_SECONDARY_RELOAD xtensa_secondary_reload
253 #undef TARGET_HAVE_TLS
254 #define TARGET_HAVE_TLS (TARGET_THREADPTR && HAVE_AS_TLS)
256 #undef TARGET_CANNOT_FORCE_CONST_MEM
257 #define TARGET_CANNOT_FORCE_CONST_MEM xtensa_tls_referenced_p
259 #undef TARGET_LEGITIMATE_ADDRESS_P
260 #define TARGET_LEGITIMATE_ADDRESS_P xtensa_legitimate_address_p
262 #undef TARGET_FRAME_POINTER_REQUIRED
263 #define TARGET_FRAME_POINTER_REQUIRED xtensa_frame_pointer_required
265 #undef TARGET_STATIC_CHAIN
266 #define TARGET_STATIC_CHAIN xtensa_static_chain
267 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
268 #define TARGET_ASM_TRAMPOLINE_TEMPLATE xtensa_asm_trampoline_template
269 #undef TARGET_TRAMPOLINE_INIT
270 #define TARGET_TRAMPOLINE_INIT xtensa_trampoline_init
272 #undef TARGET_OPTION_OVERRIDE
273 #define TARGET_OPTION_OVERRIDE xtensa_option_override
274 #undef TARGET_OPTION_OPTIMIZATION_TABLE
275 #define TARGET_OPTION_OPTIMIZATION_TABLE xtensa_option_optimization_table
277 struct gcc_target targetm
= TARGET_INITIALIZER
;
280 /* Functions to test Xtensa immediate operand validity. */
283 xtensa_simm8 (HOST_WIDE_INT v
)
285 return v
>= -128 && v
<= 127;
290 xtensa_simm8x256 (HOST_WIDE_INT v
)
292 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
297 xtensa_simm12b (HOST_WIDE_INT v
)
299 return v
>= -2048 && v
<= 2047;
304 xtensa_uimm8 (HOST_WIDE_INT v
)
306 return v
>= 0 && v
<= 255;
311 xtensa_uimm8x2 (HOST_WIDE_INT v
)
313 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
318 xtensa_uimm8x4 (HOST_WIDE_INT v
)
320 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
325 xtensa_b4const (HOST_WIDE_INT v
)
352 xtensa_b4const_or_zero (HOST_WIDE_INT v
)
356 return xtensa_b4const (v
);
361 xtensa_b4constu (HOST_WIDE_INT v
)
388 xtensa_mask_immediate (HOST_WIDE_INT v
)
390 #define MAX_MASK_SIZE 16
393 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
406 /* This is just like the standard true_regnum() function except that it
407 works even when reg_renumber is not initialized. */
410 xt_true_regnum (rtx x
)
412 if (GET_CODE (x
) == REG
)
415 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
416 && reg_renumber
[REGNO (x
)] >= 0)
417 return reg_renumber
[REGNO (x
)];
420 if (GET_CODE (x
) == SUBREG
)
422 int base
= xt_true_regnum (SUBREG_REG (x
));
423 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
424 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
425 GET_MODE (SUBREG_REG (x
)),
426 SUBREG_BYTE (x
), GET_MODE (x
));
433 xtensa_valid_move (enum machine_mode mode
, rtx
*operands
)
435 /* Either the destination or source must be a register, and the
436 MAC16 accumulator doesn't count. */
438 if (register_operand (operands
[0], mode
))
440 int dst_regnum
= xt_true_regnum (operands
[0]);
442 /* The stack pointer can only be assigned with a MOVSP opcode. */
443 if (dst_regnum
== STACK_POINTER_REGNUM
)
444 return (mode
== SImode
445 && register_operand (operands
[1], mode
)
446 && !ACC_REG_P (xt_true_regnum (operands
[1])));
448 if (!ACC_REG_P (dst_regnum
))
451 if (register_operand (operands
[1], mode
))
453 int src_regnum
= xt_true_regnum (operands
[1]);
454 if (!ACC_REG_P (src_regnum
))
462 smalloffset_mem_p (rtx op
)
464 if (GET_CODE (op
) == MEM
)
466 rtx addr
= XEXP (op
, 0);
467 if (GET_CODE (addr
) == REG
)
468 return BASE_REG_P (addr
, 0);
469 if (GET_CODE (addr
) == PLUS
)
471 rtx offset
= XEXP (addr
, 0);
473 if (GET_CODE (offset
) != CONST_INT
)
474 offset
= XEXP (addr
, 1);
475 if (GET_CODE (offset
) != CONST_INT
)
478 val
= INTVAL (offset
);
479 return (val
& 3) == 0 && (val
>= 0 && val
<= 60);
487 constantpool_address_p (rtx addr
)
491 if (GET_CODE (addr
) == CONST
)
495 /* Only handle (PLUS (SYM, OFFSET)) form. */
496 addr
= XEXP (addr
, 0);
497 if (GET_CODE (addr
) != PLUS
)
500 /* Make sure the address is word aligned. */
501 offset
= XEXP (addr
, 1);
502 if ((GET_CODE (offset
) != CONST_INT
)
503 || ((INTVAL (offset
) & 3) != 0))
506 sym
= XEXP (addr
, 0);
509 if ((GET_CODE (sym
) == SYMBOL_REF
)
510 && CONSTANT_POOL_ADDRESS_P (sym
))
517 constantpool_mem_p (rtx op
)
519 if (GET_CODE (op
) == SUBREG
)
520 op
= SUBREG_REG (op
);
521 if (GET_CODE (op
) == MEM
)
522 return constantpool_address_p (XEXP (op
, 0));
527 /* Return TRUE if X is a thread-local symbol. */
530 xtensa_tls_symbol_p (rtx x
)
532 if (! TARGET_HAVE_TLS
)
535 return GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
) != 0;
540 xtensa_extend_reg (rtx dst
, rtx src
)
542 rtx temp
= gen_reg_rtx (SImode
);
543 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
545 /* Generate paradoxical subregs as needed so that the modes match. */
546 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
547 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
549 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
550 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
555 xtensa_mem_offset (unsigned v
, enum machine_mode mode
)
560 /* Handle the worst case for block moves. See xtensa_expand_block_move
561 where we emit an optimized block move operation if the block can be
562 moved in < "move_ratio" pieces. The worst case is when the block is
563 aligned but has a size of (3 mod 4) (does this happen?) so that the
564 last piece requires a byte load/store. */
565 return (xtensa_uimm8 (v
)
566 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
569 return xtensa_uimm8 (v
);
572 return xtensa_uimm8x2 (v
);
575 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
581 return xtensa_uimm8x4 (v
);
585 /* Make normal rtx_code into something we can index from an array. */
587 static enum internal_test
588 map_test_to_internal_test (enum rtx_code test_code
)
590 enum internal_test test
= ITEST_MAX
;
595 case EQ
: test
= ITEST_EQ
; break;
596 case NE
: test
= ITEST_NE
; break;
597 case GT
: test
= ITEST_GT
; break;
598 case GE
: test
= ITEST_GE
; break;
599 case LT
: test
= ITEST_LT
; break;
600 case LE
: test
= ITEST_LE
; break;
601 case GTU
: test
= ITEST_GTU
; break;
602 case GEU
: test
= ITEST_GEU
; break;
603 case LTU
: test
= ITEST_LTU
; break;
604 case LEU
: test
= ITEST_LEU
; break;
611 /* Generate the code to compare two integer values. The return value is
612 the comparison expression. */
615 gen_int_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
616 rtx cmp0
, /* first operand to compare */
617 rtx cmp1
, /* second operand to compare */
618 int *p_invert
/* whether branch needs to reverse test */)
622 enum rtx_code test_code
; /* test code to use in insn */
623 bool (*const_range_p
) (HOST_WIDE_INT
); /* range check function */
624 int const_add
; /* constant to add (convert LE -> LT) */
625 int reverse_regs
; /* reverse registers in test */
626 int invert_const
; /* != 0 if invert value if cmp1 is constant */
627 int invert_reg
; /* != 0 if invert value if cmp1 is register */
628 int unsignedp
; /* != 0 for unsigned comparisons. */
631 static struct cmp_info info
[ (int)ITEST_MAX
] = {
633 { EQ
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
634 { NE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
636 { LT
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
637 { GE
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
638 { LT
, xtensa_b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
639 { GE
, xtensa_b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
641 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
642 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
643 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
644 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
647 enum internal_test test
;
648 enum machine_mode mode
;
649 struct cmp_info
*p_info
;
651 test
= map_test_to_internal_test (test_code
);
652 gcc_assert (test
!= ITEST_MAX
);
654 p_info
= &info
[ (int)test
];
656 mode
= GET_MODE (cmp0
);
657 if (mode
== VOIDmode
)
658 mode
= GET_MODE (cmp1
);
660 /* Make sure we can handle any constants given to us. */
661 if (GET_CODE (cmp1
) == CONST_INT
)
663 HOST_WIDE_INT value
= INTVAL (cmp1
);
664 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
666 /* if the immediate overflows or does not fit in the immediate field,
667 spill it to a register */
669 if ((p_info
->unsignedp
?
670 (uvalue
+ p_info
->const_add
> uvalue
) :
671 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
673 cmp1
= force_reg (mode
, cmp1
);
675 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
677 cmp1
= force_reg (mode
, cmp1
);
680 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
682 cmp1
= force_reg (mode
, cmp1
);
685 /* See if we need to invert the result. */
686 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
687 ? p_info
->invert_const
688 : p_info
->invert_reg
);
690 /* Comparison to constants, may involve adding 1 to change a LT into LE.
691 Comparison between two registers, may involve switching operands. */
692 if (GET_CODE (cmp1
) == CONST_INT
)
694 if (p_info
->const_add
!= 0)
695 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
698 else if (p_info
->reverse_regs
)
705 return gen_rtx_fmt_ee (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
709 /* Generate the code to compare two float values. The return value is
710 the comparison expression. */
713 gen_float_relational (enum rtx_code test_code
, /* relational test (EQ, etc) */
714 rtx cmp0
, /* first operand to compare */
715 rtx cmp1
/* second operand to compare */)
717 rtx (*gen_fn
) (rtx
, rtx
, rtx
);
719 int reverse_regs
, invert
;
723 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
724 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
725 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
726 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
727 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
728 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
729 case UNEQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_suneq_sf
; break;
730 case LTGT
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_suneq_sf
; break;
731 case UNLE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunle_sf
; break;
732 case UNGT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
733 case UNLT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunlt_sf
; break;
734 case UNGE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sunle_sf
; break;
736 reverse_regs
= 0; invert
= 0; gen_fn
= gen_sunordered_sf
; break;
738 reverse_regs
= 0; invert
= 1; gen_fn
= gen_sunordered_sf
; break;
740 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
741 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
751 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
752 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
754 return gen_rtx_fmt_ee (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
759 xtensa_expand_conditional_branch (rtx
*operands
, enum machine_mode mode
)
761 enum rtx_code test_code
= GET_CODE (operands
[0]);
762 rtx cmp0
= operands
[1];
763 rtx cmp1
= operands
[2];
772 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
, cmp0
, cmp1
));
776 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
780 if (!TARGET_HARD_FLOAT
)
781 fatal_insn ("bad test", gen_rtx_fmt_ee (test_code
, VOIDmode
,
784 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
788 /* Generate the branch. */
790 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[3]);
799 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
800 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
807 gen_conditional_move (enum rtx_code code
, enum machine_mode mode
,
814 /* Jump optimization calls get_condition() which canonicalizes
815 comparisons like (GE x <const>) to (GT x <const-1>).
816 Transform those comparisons back to GE, since that is the
817 comparison supported in Xtensa. We shouldn't have to
818 transform <LE x const> comparisons, because neither
819 xtensa_expand_conditional_branch() nor get_condition() will
822 if ((code
== GT
) && (op1
== constm1_rtx
))
827 cmp
= gen_rtx_fmt_ee (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
829 if (boolean_operator (cmp
, VOIDmode
))
831 /* Swap the operands to make const0 second. */
832 if (op0
== const0_rtx
)
838 /* If not comparing against zero, emit a comparison (subtract). */
839 if (op1
!= const0_rtx
)
841 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
842 0, 0, OPTAB_LIB_WIDEN
);
846 else if (branch_operator (cmp
, VOIDmode
))
848 /* Swap the operands to make const0 second. */
849 if (op0
== const0_rtx
)
856 case LT
: code
= GE
; break;
857 case GE
: code
= LT
; break;
858 default: gcc_unreachable ();
862 if (op1
!= const0_rtx
)
868 return gen_rtx_fmt_ee (code
, VOIDmode
, op0
, op1
);
871 if (TARGET_HARD_FLOAT
&& mode
== SFmode
)
872 return gen_float_relational (code
, op0
, op1
);
879 xtensa_expand_conditional_move (rtx
*operands
, int isflt
)
881 rtx dest
= operands
[0];
882 rtx cmp
= operands
[1];
883 enum machine_mode cmp_mode
= GET_MODE (XEXP (cmp
, 0));
884 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
886 if (!(cmp
= gen_conditional_move (GET_CODE (cmp
), cmp_mode
,
887 XEXP (cmp
, 0), XEXP (cmp
, 1))))
891 gen_fn
= (cmp_mode
== SImode
892 ? gen_movsfcc_internal0
893 : gen_movsfcc_internal1
);
895 gen_fn
= (cmp_mode
== SImode
896 ? gen_movsicc_internal0
897 : gen_movsicc_internal1
);
899 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), operands
[2], operands
[3], cmp
));
905 xtensa_expand_scc (rtx operands
[4], enum machine_mode cmp_mode
)
907 rtx dest
= operands
[0];
909 rtx one_tmp
, zero_tmp
;
910 rtx (*gen_fn
) (rtx
, rtx
, rtx
, rtx
, rtx
);
912 if (!(cmp
= gen_conditional_move (GET_CODE (operands
[1]), cmp_mode
,
913 operands
[2], operands
[3])))
916 one_tmp
= gen_reg_rtx (SImode
);
917 zero_tmp
= gen_reg_rtx (SImode
);
918 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
919 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
921 gen_fn
= (cmp_mode
== SImode
922 ? gen_movsicc_internal0
923 : gen_movsicc_internal1
);
924 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
929 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
930 for the output, i.e., the input operands are twice as big as MODE. */
933 xtensa_split_operand_pair (rtx operands
[4], enum machine_mode mode
)
935 switch (GET_CODE (operands
[1]))
938 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
939 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
943 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
944 operands
[2] = adjust_address (operands
[1], mode
, 0);
949 split_double (operands
[1], &operands
[2], &operands
[3]);
956 switch (GET_CODE (operands
[0]))
959 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
960 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
964 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
965 operands
[0] = adjust_address (operands
[0], mode
, 0);
974 /* Emit insns to move operands[1] into operands[0].
975 Return 1 if we have written out everything that needs to be done to
976 do the move. Otherwise, return 0 and the caller will emit the move
980 xtensa_emit_move_sequence (rtx
*operands
, enum machine_mode mode
)
982 rtx src
= operands
[1];
985 && (GET_CODE (src
) != CONST_INT
|| ! xtensa_simm12b (INTVAL (src
))))
987 rtx dst
= operands
[0];
989 if (xtensa_tls_referenced_p (src
))
993 if (GET_CODE (src
) == CONST
&& GET_CODE (XEXP (src
, 0)) == PLUS
)
995 addend
= XEXP (XEXP (src
, 0), 1);
996 src
= XEXP (XEXP (src
, 0), 0);
999 src
= xtensa_legitimize_tls_address (src
);
1002 src
= gen_rtx_PLUS (mode
, src
, addend
);
1003 src
= force_operand (src
, dst
);
1005 emit_move_insn (dst
, src
);
1009 if (! TARGET_CONST16
)
1011 src
= force_const_mem (SImode
, src
);
1015 /* PC-relative loads are always SImode, and CONST16 is only
1016 supported in the movsi pattern, so add a SUBREG for any other
1021 if (register_operand (dst
, mode
))
1023 emit_move_insn (simplify_gen_subreg (SImode
, dst
, mode
, 0), src
);
1028 src
= force_reg (SImode
, src
);
1029 src
= gen_lowpart_SUBREG (mode
, src
);
1035 if (!(reload_in_progress
| reload_completed
)
1036 && !xtensa_valid_move (mode
, operands
))
1037 operands
[1] = force_reg (mode
, operands
[1]);
1039 operands
[1] = xtensa_copy_incoming_a7 (operands
[1]);
1041 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1042 instruction won't be recognized after reload, so we remove the
1043 subreg and adjust mem accordingly. */
1044 if (reload_in_progress
)
1046 operands
[0] = fixup_subreg_mem (operands
[0]);
1047 operands
[1] = fixup_subreg_mem (operands
[1]);
1054 fixup_subreg_mem (rtx x
)
1056 if (GET_CODE (x
) == SUBREG
1057 && GET_CODE (SUBREG_REG (x
)) == REG
1058 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1061 gen_rtx_SUBREG (GET_MODE (x
),
1062 reg_equiv_mem
[REGNO (SUBREG_REG (x
))],
1064 x
= alter_subreg (&temp
);
1070 /* Check if an incoming argument in a7 is expected to be used soon and
1071 if OPND is a register or register pair that includes a7. If so,
1072 create a new pseudo and copy a7 into that pseudo at the very
1073 beginning of the function, followed by the special "set_frame_ptr"
1074 unspec_volatile insn. The return value is either the original
1075 operand, if it is not a7, or the new pseudo containing a copy of
1076 the incoming argument. This is necessary because the register
1077 allocator will ignore conflicts with a7 and may either assign some
1078 other pseudo to a7 or use a7 as the hard_frame_pointer, clobbering
1079 the incoming argument in a7. By copying the argument out of a7 as
1080 the very first thing, and then immediately following that with an
1081 unspec_volatile to keep the scheduler away, we should avoid any
1082 problems. Putting the set_frame_ptr insn at the beginning, with
1083 only the a7 copy before it, also makes it easier for the prologue
1084 expander to initialize the frame pointer after the a7 copy and to
1085 fix up the a7 copy to use the stack pointer instead of the frame
1089 xtensa_copy_incoming_a7 (rtx opnd
)
1091 rtx entry_insns
= 0;
1093 enum machine_mode mode
;
1095 if (!cfun
->machine
->need_a7_copy
)
1098 /* This function should never be called again once a7 has been copied. */
1099 gcc_assert (!cfun
->machine
->set_frame_ptr_insn
);
1101 mode
= GET_MODE (opnd
);
1103 /* The operand using a7 may come in a later instruction, so just return
1104 the original operand if it doesn't use a7. */
1106 if (GET_CODE (reg
) == SUBREG
)
1108 gcc_assert (SUBREG_BYTE (reg
) == 0);
1109 reg
= SUBREG_REG (reg
);
1111 if (GET_CODE (reg
) != REG
1112 || REGNO (reg
) > A7_REG
1113 || REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) <= A7_REG
)
1116 /* 1-word args will always be in a7; 2-word args in a6/a7. */
1117 gcc_assert (REGNO (reg
) + HARD_REGNO_NREGS (A7_REG
, mode
) - 1 == A7_REG
);
1119 cfun
->machine
->need_a7_copy
= false;
1121 /* Copy a7 to a new pseudo at the function entry. Use gen_raw_REG to
1122 create the REG for a7 so that hard_frame_pointer_rtx is not used. */
1125 tmp
= gen_reg_rtx (mode
);
1131 /* Copy the value out of A7 here but keep the first word in A6 until
1132 after the set_frame_ptr insn. Otherwise, the register allocator
1133 may decide to put "subreg (tmp, 0)" in A7 and clobber the incoming
1135 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 4),
1136 gen_raw_REG (SImode
, A7_REG
)));
1139 emit_insn (gen_movsf_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1142 emit_insn (gen_movsi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1145 emit_insn (gen_movhi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1148 emit_insn (gen_movqi_internal (tmp
, gen_raw_REG (mode
, A7_REG
)));
1154 cfun
->machine
->set_frame_ptr_insn
= emit_insn (gen_set_frame_ptr ());
1156 /* For DF and DI mode arguments, copy the incoming value in A6 now. */
1157 if (mode
== DFmode
|| mode
== DImode
)
1158 emit_insn (gen_movsi_internal (gen_rtx_SUBREG (SImode
, tmp
, 0),
1159 gen_rtx_REG (SImode
, A7_REG
- 1)));
1160 entry_insns
= get_insns ();
1163 if (cfun
->machine
->vararg_a7
)
1165 /* This is called from within builtin_saveregs, which will insert the
1166 saveregs code at the function entry, ahead of anything placed at
1167 the function entry now. Instead, save the sequence to be inserted
1168 at the beginning of the saveregs code. */
1169 cfun
->machine
->vararg_a7_copy
= entry_insns
;
1173 /* Put entry_insns after the NOTE that starts the function. If
1174 this is inside a start_sequence, make the outer-level insn
1175 chain current, so the code is placed at the start of the
1177 push_topmost_sequence ();
1178 /* Do not use entry_of_function() here. This is called from within
1179 expand_function_start, when the CFG still holds GIMPLE. */
1180 emit_insn_after (entry_insns
, get_insns ());
1181 pop_topmost_sequence ();
1188 /* Try to expand a block move operation to a sequence of RTL move
1189 instructions. If not optimizing, or if the block size is not a
1190 constant, or if the block is too large, the expansion fails and GCC
1191 falls back to calling memcpy().
1193 operands[0] is the destination
1194 operands[1] is the source
1195 operands[2] is the length
1196 operands[3] is the alignment */
1199 xtensa_expand_block_move (rtx
*operands
)
1201 static const enum machine_mode mode_from_align
[] =
1203 VOIDmode
, QImode
, HImode
, VOIDmode
, SImode
,
1206 rtx dst_mem
= operands
[0];
1207 rtx src_mem
= operands
[1];
1208 HOST_WIDE_INT bytes
, align
;
1209 int num_pieces
, move_ratio
;
1211 enum machine_mode mode
[2];
1220 /* If this is not a fixed size move, just call memcpy. */
1221 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1224 bytes
= INTVAL (operands
[2]);
1225 align
= INTVAL (operands
[3]);
1227 /* Anything to move? */
1231 if (align
> MOVE_MAX
)
1234 /* Decide whether to expand inline based on the optimization level. */
1237 move_ratio
= LARGEST_MOVE_RATIO
;
1238 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* Close enough anyway. */
1239 if (num_pieces
> move_ratio
)
1242 x
= XEXP (dst_mem
, 0);
1245 x
= force_reg (Pmode
, x
);
1246 dst_mem
= replace_equiv_address (dst_mem
, x
);
1249 x
= XEXP (src_mem
, 0);
1252 x
= force_reg (Pmode
, x
);
1253 src_mem
= replace_equiv_address (src_mem
, x
);
1256 active
[0] = active
[1] = false;
1267 next_amount
= (bytes
>= 4 ? 4 : (bytes
>= 2 ? 2 : 1));
1268 next_amount
= MIN (next_amount
, align
);
1270 amount
[next
] = next_amount
;
1271 mode
[next
] = mode_from_align
[next_amount
];
1272 temp
[next
] = gen_reg_rtx (mode
[next
]);
1274 x
= adjust_address (src_mem
, mode
[next
], offset_ld
);
1275 emit_insn (gen_rtx_SET (VOIDmode
, temp
[next
], x
));
1277 offset_ld
+= next_amount
;
1278 bytes
-= next_amount
;
1279 active
[next
] = true;
1284 active
[phase
] = false;
1286 x
= adjust_address (dst_mem
, mode
[phase
], offset_st
);
1287 emit_insn (gen_rtx_SET (VOIDmode
, x
, temp
[phase
]));
1289 offset_st
+= amount
[phase
];
1292 while (active
[next
]);
1299 xtensa_expand_nonlocal_goto (rtx
*operands
)
1301 rtx goto_handler
= operands
[1];
1302 rtx containing_fp
= operands
[3];
1304 /* Generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1305 is too big to generate in-line. */
1307 if (GET_CODE (containing_fp
) != REG
)
1308 containing_fp
= force_reg (Pmode
, containing_fp
);
1310 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1311 LCT_NORMAL
, VOIDmode
, 2,
1312 containing_fp
, Pmode
,
1313 goto_handler
, Pmode
);
1317 static struct machine_function
*
1318 xtensa_init_machine_status (void)
1320 return ggc_alloc_cleared_machine_function ();
1324 /* Shift VAL of mode MODE left by COUNT bits. */
1327 xtensa_expand_mask_and_shift (rtx val
, enum machine_mode mode
, rtx count
)
1329 val
= expand_simple_binop (SImode
, AND
, val
, GEN_INT (GET_MODE_MASK (mode
)),
1330 NULL_RTX
, 1, OPTAB_DIRECT
);
1331 return expand_simple_binop (SImode
, ASHIFT
, val
, count
,
1332 NULL_RTX
, 1, OPTAB_DIRECT
);
1336 /* Structure to hold the initial parameters for a compare_and_swap operation
1337 in HImode and QImode. */
1339 struct alignment_context
1341 rtx memsi
; /* SI aligned memory location. */
1342 rtx shift
; /* Bit offset with regard to lsb. */
1343 rtx modemask
; /* Mask of the HQImode shifted by SHIFT bits. */
1344 rtx modemaski
; /* ~modemask */
1348 /* Initialize structure AC for word access to HI and QI mode memory. */
1351 init_alignment_context (struct alignment_context
*ac
, rtx mem
)
1353 enum machine_mode mode
= GET_MODE (mem
);
1354 rtx byteoffset
= NULL_RTX
;
1355 bool aligned
= (MEM_ALIGN (mem
) >= GET_MODE_BITSIZE (SImode
));
1358 ac
->memsi
= adjust_address (mem
, SImode
, 0); /* Memory is aligned. */
1361 /* Alignment is unknown. */
1364 /* Force the address into a register. */
1365 addr
= force_reg (Pmode
, XEXP (mem
, 0));
1367 /* Align it to SImode. */
1368 align
= expand_simple_binop (Pmode
, AND
, addr
,
1369 GEN_INT (-GET_MODE_SIZE (SImode
)),
1370 NULL_RTX
, 1, OPTAB_DIRECT
);
1372 ac
->memsi
= gen_rtx_MEM (SImode
, align
);
1373 MEM_VOLATILE_P (ac
->memsi
) = MEM_VOLATILE_P (mem
);
1374 set_mem_alias_set (ac
->memsi
, ALIAS_SET_MEMORY_BARRIER
);
1375 set_mem_align (ac
->memsi
, GET_MODE_BITSIZE (SImode
));
1377 byteoffset
= expand_simple_binop (Pmode
, AND
, addr
,
1378 GEN_INT (GET_MODE_SIZE (SImode
) - 1),
1379 NULL_RTX
, 1, OPTAB_DIRECT
);
1382 /* Calculate shiftcount. */
1383 if (TARGET_BIG_ENDIAN
)
1385 ac
->shift
= GEN_INT (GET_MODE_SIZE (SImode
) - GET_MODE_SIZE (mode
));
1387 ac
->shift
= expand_simple_binop (SImode
, MINUS
, ac
->shift
, byteoffset
,
1388 NULL_RTX
, 1, OPTAB_DIRECT
);
1393 ac
->shift
= NULL_RTX
;
1395 ac
->shift
= byteoffset
;
1398 if (ac
->shift
!= NULL_RTX
)
1400 /* Shift is the byte count, but we need the bitcount. */
1401 ac
->shift
= expand_simple_binop (SImode
, MULT
, ac
->shift
,
1402 GEN_INT (BITS_PER_UNIT
),
1403 NULL_RTX
, 1, OPTAB_DIRECT
);
1404 ac
->modemask
= expand_simple_binop (SImode
, ASHIFT
,
1405 GEN_INT (GET_MODE_MASK (mode
)),
1407 NULL_RTX
, 1, OPTAB_DIRECT
);
1410 ac
->modemask
= GEN_INT (GET_MODE_MASK (mode
));
1412 ac
->modemaski
= expand_simple_unop (SImode
, NOT
, ac
->modemask
, NULL_RTX
, 1);
1416 /* Expand an atomic compare and swap operation for HImode and QImode.
1417 MEM is the memory location, CMP the old value to compare MEM with
1418 and NEW_RTX the value to set if CMP == MEM. */
1421 xtensa_expand_compare_and_swap (rtx target
, rtx mem
, rtx cmp
, rtx new_rtx
)
1423 enum machine_mode mode
= GET_MODE (mem
);
1424 struct alignment_context ac
;
1425 rtx tmp
, cmpv
, newv
, val
;
1426 rtx oldval
= gen_reg_rtx (SImode
);
1427 rtx res
= gen_reg_rtx (SImode
);
1428 rtx csloop
= gen_label_rtx ();
1429 rtx csend
= gen_label_rtx ();
1431 init_alignment_context (&ac
, mem
);
1433 if (ac
.shift
!= NULL_RTX
)
1435 cmp
= xtensa_expand_mask_and_shift (cmp
, mode
, ac
.shift
);
1436 new_rtx
= xtensa_expand_mask_and_shift (new_rtx
, mode
, ac
.shift
);
1439 /* Load the surrounding word into VAL with the MEM value masked out. */
1440 val
= force_reg (SImode
, expand_simple_binop (SImode
, AND
, ac
.memsi
,
1441 ac
.modemaski
, NULL_RTX
, 1,
1443 emit_label (csloop
);
1445 /* Patch CMP and NEW_RTX into VAL at correct position. */
1446 cmpv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, cmp
, val
,
1447 NULL_RTX
, 1, OPTAB_DIRECT
));
1448 newv
= force_reg (SImode
, expand_simple_binop (SImode
, IOR
, new_rtx
, val
,
1449 NULL_RTX
, 1, OPTAB_DIRECT
));
1451 /* Jump to end if we're done. */
1452 emit_insn (gen_sync_compare_and_swapsi (res
, ac
.memsi
, cmpv
, newv
));
1453 emit_cmp_and_jump_insns (res
, cmpv
, EQ
, const0_rtx
, SImode
, true, csend
);
1455 /* Check for changes outside mode. */
1456 emit_move_insn (oldval
, val
);
1457 tmp
= expand_simple_binop (SImode
, AND
, res
, ac
.modemaski
,
1458 val
, 1, OPTAB_DIRECT
);
1460 emit_move_insn (val
, tmp
);
1462 /* Loop internal if so. */
1463 emit_cmp_and_jump_insns (oldval
, val
, NE
, const0_rtx
, SImode
, true, csloop
);
1467 /* Return the correct part of the bitfield. */
1468 convert_move (target
,
1469 (ac
.shift
== NULL_RTX
? res
1470 : expand_simple_binop (SImode
, LSHIFTRT
, res
, ac
.shift
,
1471 NULL_RTX
, 1, OPTAB_DIRECT
)),
1476 /* Expand an atomic operation CODE of mode MODE (either HImode or QImode --
1477 the default expansion works fine for SImode). MEM is the memory location
1478 and VAL the value to play with. If AFTER is true then store the value
1479 MEM holds after the operation, if AFTER is false then store the value MEM
1480 holds before the operation. If TARGET is zero then discard that value, else
1481 store it to TARGET. */
1484 xtensa_expand_atomic (enum rtx_code code
, rtx target
, rtx mem
, rtx val
,
1487 enum machine_mode mode
= GET_MODE (mem
);
1488 struct alignment_context ac
;
1489 rtx csloop
= gen_label_rtx ();
1491 rtx old
= gen_reg_rtx (SImode
);
1492 rtx new_rtx
= gen_reg_rtx (SImode
);
1493 rtx orig
= NULL_RTX
;
1495 init_alignment_context (&ac
, mem
);
1497 /* Prepare values before the compare-and-swap loop. */
1498 if (ac
.shift
!= NULL_RTX
)
1499 val
= xtensa_expand_mask_and_shift (val
, mode
, ac
.shift
);
1504 orig
= gen_reg_rtx (SImode
);
1505 convert_move (orig
, val
, 1);
1513 case MULT
: /* NAND */
1515 /* val = "11..1<val>11..1" */
1516 val
= expand_simple_binop (SImode
, XOR
, val
, ac
.modemaski
,
1517 NULL_RTX
, 1, OPTAB_DIRECT
);
1524 /* Load full word. Subsequent loads are performed by S32C1I. */
1525 cmp
= force_reg (SImode
, ac
.memsi
);
1527 emit_label (csloop
);
1528 emit_move_insn (old
, cmp
);
1534 val
= expand_simple_binop (SImode
, code
, old
, orig
,
1535 NULL_RTX
, 1, OPTAB_DIRECT
);
1536 val
= expand_simple_binop (SImode
, AND
, val
, ac
.modemask
,
1537 NULL_RTX
, 1, OPTAB_DIRECT
);
1540 tmp
= expand_simple_binop (SImode
, AND
, old
, ac
.modemaski
,
1541 NULL_RTX
, 1, OPTAB_DIRECT
);
1542 tmp
= expand_simple_binop (SImode
, IOR
, tmp
, val
,
1543 new_rtx
, 1, OPTAB_DIRECT
);
1549 tmp
= expand_simple_binop (SImode
, code
, old
, val
,
1550 new_rtx
, 1, OPTAB_DIRECT
);
1553 case MULT
: /* NAND */
1554 tmp
= expand_simple_binop (SImode
, XOR
, old
, ac
.modemask
,
1555 NULL_RTX
, 1, OPTAB_DIRECT
);
1556 tmp
= expand_simple_binop (SImode
, AND
, tmp
, val
,
1557 new_rtx
, 1, OPTAB_DIRECT
);
1565 emit_move_insn (new_rtx
, tmp
);
1566 emit_insn (gen_sync_compare_and_swapsi (cmp
, ac
.memsi
, old
, new_rtx
));
1567 emit_cmp_and_jump_insns (cmp
, old
, NE
, const0_rtx
, SImode
, true, csloop
);
1571 tmp
= (after
? new_rtx
: cmp
);
1572 convert_move (target
,
1573 (ac
.shift
== NULL_RTX
? tmp
1574 : expand_simple_binop (SImode
, LSHIFTRT
, tmp
, ac
.shift
,
1575 NULL_RTX
, 1, OPTAB_DIRECT
)),
1582 xtensa_setup_frame_addresses (void)
1584 /* Set flag to cause TARGET_FRAME_POINTER_REQUIRED to return true. */
1585 cfun
->machine
->accesses_prev_frame
= 1;
1588 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1589 LCT_NORMAL
, VOIDmode
, 0);
1593 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1594 a comment showing where the end of the loop is. However, if there is a
1595 label or a branch at the end of the loop then we need to place a nop
1596 there. If the loop ends with a label we need the nop so that branches
1597 targeting that label will target the nop (and thus remain in the loop),
1598 instead of targeting the instruction after the loop (and thus exiting
1599 the loop). If the loop ends with a branch, we need the nop in case the
1600 branch is targeting a location inside the loop. When the branch
1601 executes it will cause the loop count to be decremented even if it is
1602 taken (because it is the last instruction in the loop), so we need to
1603 nop after the branch to prevent the loop count from being decremented
1604 when the branch is taken. */
1607 xtensa_emit_loop_end (rtx insn
, rtx
*operands
)
1611 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1613 switch (GET_CODE (insn
))
1620 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1626 rtx body
= PATTERN (insn
);
1628 if (GET_CODE (body
) == JUMP_INSN
)
1630 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1633 else if ((GET_CODE (body
) != USE
)
1634 && (GET_CODE (body
) != CLOBBER
))
1641 output_asm_insn ("# loop end for %0", operands
);
1646 xtensa_emit_branch (bool inverted
, bool immed
, rtx
*operands
)
1648 static char result
[64];
1652 code
= GET_CODE (operands
[3]);
1655 case EQ
: op
= inverted
? "ne" : "eq"; break;
1656 case NE
: op
= inverted
? "eq" : "ne"; break;
1657 case LT
: op
= inverted
? "ge" : "lt"; break;
1658 case GE
: op
= inverted
? "lt" : "ge"; break;
1659 case LTU
: op
= inverted
? "geu" : "ltu"; break;
1660 case GEU
: op
= inverted
? "ltu" : "geu"; break;
1661 default: gcc_unreachable ();
1666 if (INTVAL (operands
[1]) == 0)
1667 sprintf (result
, "b%sz%s\t%%0, %%2", op
,
1668 (TARGET_DENSITY
&& (code
== EQ
|| code
== NE
)) ? ".n" : "");
1670 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1673 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1680 xtensa_emit_bit_branch (bool inverted
, bool immed
, rtx
*operands
)
1682 static char result
[64];
1685 switch (GET_CODE (operands
[3]))
1687 case EQ
: op
= inverted
? "bs" : "bc"; break;
1688 case NE
: op
= inverted
? "bc" : "bs"; break;
1689 default: gcc_unreachable ();
1694 unsigned bitnum
= INTVAL (operands
[1]) & 0x1f;
1695 operands
[1] = GEN_INT (bitnum
);
1696 sprintf (result
, "b%si\t%%0, %%d1, %%2", op
);
1699 sprintf (result
, "b%s\t%%0, %%1, %%2", op
);
1706 xtensa_emit_movcc (bool inverted
, bool isfp
, bool isbool
, rtx
*operands
)
1708 static char result
[64];
1712 code
= GET_CODE (operands
[4]);
1717 case EQ
: op
= inverted
? "t" : "f"; break;
1718 case NE
: op
= inverted
? "f" : "t"; break;
1719 default: gcc_unreachable ();
1726 case EQ
: op
= inverted
? "nez" : "eqz"; break;
1727 case NE
: op
= inverted
? "eqz" : "nez"; break;
1728 case LT
: op
= inverted
? "gez" : "ltz"; break;
1729 case GE
: op
= inverted
? "ltz" : "gez"; break;
1730 default: gcc_unreachable ();
1734 sprintf (result
, "mov%s%s\t%%0, %%%d, %%1",
1735 op
, isfp
? ".s" : "", inverted
? 3 : 2);
1741 xtensa_emit_call (int callop
, rtx
*operands
)
1743 static char result
[64];
1744 rtx tgt
= operands
[callop
];
1746 if (GET_CODE (tgt
) == CONST_INT
)
1747 sprintf (result
, "call8\t0x%lx", INTVAL (tgt
));
1748 else if (register_operand (tgt
, VOIDmode
))
1749 sprintf (result
, "callx8\t%%%d", callop
);
1751 sprintf (result
, "call8\t%%%d", callop
);
1758 xtensa_legitimate_address_p (enum machine_mode mode
, rtx addr
, bool strict
)
1760 /* Allow constant pool addresses. */
1761 if (mode
!= BLKmode
&& GET_MODE_SIZE (mode
) >= UNITS_PER_WORD
1762 && ! TARGET_CONST16
&& constantpool_address_p (addr
)
1763 && ! xtensa_tls_referenced_p (addr
))
1766 while (GET_CODE (addr
) == SUBREG
)
1767 addr
= SUBREG_REG (addr
);
1769 /* Allow base registers. */
1770 if (GET_CODE (addr
) == REG
&& BASE_REG_P (addr
, strict
))
1773 /* Check for "register + offset" addressing. */
1774 if (GET_CODE (addr
) == PLUS
)
1776 rtx xplus0
= XEXP (addr
, 0);
1777 rtx xplus1
= XEXP (addr
, 1);
1778 enum rtx_code code0
;
1779 enum rtx_code code1
;
1781 while (GET_CODE (xplus0
) == SUBREG
)
1782 xplus0
= SUBREG_REG (xplus0
);
1783 code0
= GET_CODE (xplus0
);
1785 while (GET_CODE (xplus1
) == SUBREG
)
1786 xplus1
= SUBREG_REG (xplus1
);
1787 code1
= GET_CODE (xplus1
);
1789 /* Swap operands if necessary so the register is first. */
1790 if (code0
!= REG
&& code1
== REG
)
1792 xplus0
= XEXP (addr
, 1);
1793 xplus1
= XEXP (addr
, 0);
1794 code0
= GET_CODE (xplus0
);
1795 code1
= GET_CODE (xplus1
);
1798 if (code0
== REG
&& BASE_REG_P (xplus0
, strict
)
1799 && code1
== CONST_INT
1800 && xtensa_mem_offset (INTVAL (xplus1
), mode
))
1808 /* Construct the SYMBOL_REF for the _TLS_MODULE_BASE_ symbol. */
1810 static GTY(()) rtx xtensa_tls_module_base_symbol
;
1813 xtensa_tls_module_base (void)
1815 if (! xtensa_tls_module_base_symbol
)
1817 xtensa_tls_module_base_symbol
=
1818 gen_rtx_SYMBOL_REF (Pmode
, "_TLS_MODULE_BASE_");
1819 SYMBOL_REF_FLAGS (xtensa_tls_module_base_symbol
)
1820 |= TLS_MODEL_GLOBAL_DYNAMIC
<< SYMBOL_FLAG_TLS_SHIFT
;
1823 return xtensa_tls_module_base_symbol
;
1828 xtensa_call_tls_desc (rtx sym
, rtx
*retp
)
1830 rtx fn
, arg
, a10
, call_insn
, insns
;
1833 fn
= gen_reg_rtx (Pmode
);
1834 arg
= gen_reg_rtx (Pmode
);
1835 a10
= gen_rtx_REG (Pmode
, 10);
1837 emit_insn (gen_tls_func (fn
, sym
));
1838 emit_insn (gen_tls_arg (arg
, sym
));
1839 emit_move_insn (a10
, arg
);
1840 call_insn
= emit_call_insn (gen_tls_call (a10
, fn
, sym
, const1_rtx
));
1841 CALL_INSN_FUNCTION_USAGE (call_insn
)
1842 = gen_rtx_EXPR_LIST (VOIDmode
, gen_rtx_USE (VOIDmode
, a10
),
1843 CALL_INSN_FUNCTION_USAGE (call_insn
));
1844 insns
= get_insns ();
1853 xtensa_legitimize_tls_address (rtx x
)
1855 unsigned int model
= SYMBOL_REF_TLS_MODEL (x
);
1856 rtx dest
, tp
, ret
, modbase
, base
, addend
, insns
;
1858 dest
= gen_reg_rtx (Pmode
);
1861 case TLS_MODEL_GLOBAL_DYNAMIC
:
1862 insns
= xtensa_call_tls_desc (x
, &ret
);
1863 emit_libcall_block (insns
, dest
, ret
, x
);
1866 case TLS_MODEL_LOCAL_DYNAMIC
:
1867 base
= gen_reg_rtx (Pmode
);
1868 modbase
= xtensa_tls_module_base ();
1869 insns
= xtensa_call_tls_desc (modbase
, &ret
);
1870 emit_libcall_block (insns
, base
, ret
, modbase
);
1871 addend
= force_reg (SImode
, gen_sym_DTPOFF (x
));
1872 emit_insn (gen_addsi3 (dest
, base
, addend
));
1875 case TLS_MODEL_INITIAL_EXEC
:
1876 case TLS_MODEL_LOCAL_EXEC
:
1877 tp
= gen_reg_rtx (SImode
);
1878 emit_insn (gen_load_tp (tp
));
1879 addend
= force_reg (SImode
, gen_sym_TPOFF (x
));
1880 emit_insn (gen_addsi3 (dest
, tp
, addend
));
1892 xtensa_legitimize_address (rtx x
,
1893 rtx oldx ATTRIBUTE_UNUSED
,
1894 enum machine_mode mode
)
1896 if (xtensa_tls_symbol_p (x
))
1897 return xtensa_legitimize_tls_address (x
);
1899 if (GET_CODE (x
) == PLUS
)
1901 rtx plus0
= XEXP (x
, 0);
1902 rtx plus1
= XEXP (x
, 1);
1904 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
1906 plus0
= XEXP (x
, 1);
1907 plus1
= XEXP (x
, 0);
1910 /* Try to split up the offset to use an ADDMI instruction. */
1911 if (GET_CODE (plus0
) == REG
1912 && GET_CODE (plus1
) == CONST_INT
1913 && !xtensa_mem_offset (INTVAL (plus1
), mode
)
1914 && !xtensa_simm8 (INTVAL (plus1
))
1915 && xtensa_mem_offset (INTVAL (plus1
) & 0xff, mode
)
1916 && xtensa_simm8x256 (INTVAL (plus1
) & ~0xff))
1918 rtx temp
= gen_reg_rtx (Pmode
);
1919 rtx addmi_offset
= GEN_INT (INTVAL (plus1
) & ~0xff);
1920 emit_insn (gen_rtx_SET (Pmode
, temp
,
1921 gen_rtx_PLUS (Pmode
, plus0
, addmi_offset
)));
1922 return gen_rtx_PLUS (Pmode
, temp
, GEN_INT (INTVAL (plus1
) & 0xff));
1930 /* Helper for xtensa_tls_referenced_p. */
1933 xtensa_tls_referenced_p_1 (rtx
*x
, void *data ATTRIBUTE_UNUSED
)
1935 if (GET_CODE (*x
) == SYMBOL_REF
)
1936 return SYMBOL_REF_TLS_MODEL (*x
) != 0;
1938 /* Ignore TLS references that have already been legitimized. */
1939 if (GET_CODE (*x
) == UNSPEC
)
1941 switch (XINT (*x
, 1))
1945 case UNSPEC_TLS_FUNC
:
1946 case UNSPEC_TLS_ARG
:
1947 case UNSPEC_TLS_CALL
:
1958 /* Return TRUE if X contains any TLS symbol references. */
1961 xtensa_tls_referenced_p (rtx x
)
1963 if (! TARGET_HAVE_TLS
)
1966 return for_each_rtx (&x
, xtensa_tls_referenced_p_1
, NULL
);
1970 /* Return the debugger register number to use for 'regno'. */
1973 xtensa_dbx_register_number (int regno
)
1977 if (GP_REG_P (regno
))
1979 regno
-= GP_REG_FIRST
;
1982 else if (BR_REG_P (regno
))
1984 regno
-= BR_REG_FIRST
;
1987 else if (FP_REG_P (regno
))
1989 regno
-= FP_REG_FIRST
;
1992 else if (ACC_REG_P (regno
))
1994 first
= 0x200; /* Start of Xtensa special registers. */
1995 regno
= 16; /* ACCLO is special register 16. */
1998 /* When optimizing, we sometimes get asked about pseudo-registers
1999 that don't represent hard registers. Return 0 for these. */
2003 return first
+ regno
;
2007 /* Argument support functions. */
2009 /* Initialize CUMULATIVE_ARGS for a function. */
2012 init_cumulative_args (CUMULATIVE_ARGS
*cum
, int incoming
)
2015 cum
->incoming
= incoming
;
2019 /* Advance the argument to the next argument position. */
2022 xtensa_function_arg_advance (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2023 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2028 arg_words
= &cum
->arg_words
;
2029 max
= MAX_ARGS_IN_REGISTERS
;
2031 words
= (((mode
!= BLKmode
)
2032 ? (int) GET_MODE_SIZE (mode
)
2033 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2035 if (*arg_words
< max
2036 && (targetm
.calls
.must_pass_in_stack (mode
, type
)
2037 || *arg_words
+ words
> max
))
2040 *arg_words
+= words
;
2044 /* Return an RTL expression containing the register for the given mode,
2045 or 0 if the argument is to be passed on the stack. INCOMING_P is nonzero
2046 if this is an incoming argument to the current function. */
2049 xtensa_function_arg_1 (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2050 const_tree type
, bool incoming_p
)
2052 int regbase
, words
, max
;
2056 arg_words
= &cum
->arg_words
;
2057 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
2058 max
= MAX_ARGS_IN_REGISTERS
;
2060 words
= (((mode
!= BLKmode
)
2061 ? (int) GET_MODE_SIZE (mode
)
2062 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
2064 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
2066 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_WORD
;
2067 *arg_words
= (*arg_words
+ align
- 1) & -align
;
2070 if (*arg_words
+ words
> max
)
2073 regno
= regbase
+ *arg_words
;
2075 if (cum
->incoming
&& regno
<= A7_REG
&& regno
+ words
> A7_REG
)
2076 cfun
->machine
->need_a7_copy
= true;
2078 return gen_rtx_REG (mode
, regno
);
2081 /* Implement TARGET_FUNCTION_ARG. */
2084 xtensa_function_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2085 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2087 return xtensa_function_arg_1 (cum
, mode
, type
, false);
2090 /* Implement TARGET_FUNCTION_INCOMING_ARG. */
2093 xtensa_function_incoming_arg (CUMULATIVE_ARGS
*cum
, enum machine_mode mode
,
2094 const_tree type
, bool named ATTRIBUTE_UNUSED
)
2096 return xtensa_function_arg_1 (cum
, mode
, type
, true);
2100 xtensa_function_arg_boundary (enum machine_mode mode
, const_tree type
)
2102 unsigned int alignment
;
2104 alignment
= type
? TYPE_ALIGN (type
) : GET_MODE_ALIGNMENT (mode
);
2105 if (alignment
< PARM_BOUNDARY
)
2106 alignment
= PARM_BOUNDARY
;
2107 if (alignment
> STACK_BOUNDARY
)
2108 alignment
= STACK_BOUNDARY
;
2114 xtensa_return_in_msb (const_tree valtype
)
2116 return (TARGET_BIG_ENDIAN
2117 && AGGREGATE_TYPE_P (valtype
)
2118 && int_size_in_bytes (valtype
) >= UNITS_PER_WORD
);
2123 xtensa_option_override (void)
2126 enum machine_mode mode
;
2128 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
2129 error ("boolean registers required for the floating-point option");
2131 /* Set up array giving whether a given register can hold a given mode. */
2132 for (mode
= VOIDmode
;
2133 mode
!= MAX_MACHINE_MODE
;
2134 mode
= (enum machine_mode
) ((int) mode
+ 1))
2136 int size
= GET_MODE_SIZE (mode
);
2137 enum mode_class mclass
= GET_MODE_CLASS (mode
);
2139 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
2143 if (ACC_REG_P (regno
))
2144 temp
= (TARGET_MAC16
2145 && (mclass
== MODE_INT
) && (size
<= UNITS_PER_WORD
));
2146 else if (GP_REG_P (regno
))
2147 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
2148 else if (FP_REG_P (regno
))
2149 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
2150 else if (BR_REG_P (regno
))
2151 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
2155 xtensa_hard_regno_mode_ok
[(int) mode
][regno
] = temp
;
2159 init_machine_status
= xtensa_init_machine_status
;
2161 /* Check PIC settings. PIC is only supported when using L32R
2162 instructions, and some targets need to always use PIC. */
2163 if (flag_pic
&& TARGET_CONST16
)
2164 error ("-f%s is not supported with CONST16 instructions",
2165 (flag_pic
> 1 ? "PIC" : "pic"));
2166 else if (TARGET_FORCE_NO_PIC
)
2168 else if (XTENSA_ALWAYS_PIC
)
2171 error ("PIC is required but not supported with CONST16 instructions");
2174 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
2177 if (flag_pic
&& !flag_pie
)
2180 /* Hot/cold partitioning does not work on this architecture, because of
2181 constant pools (the load instruction cannot necessarily reach that far).
2182 Therefore disable it on this architecture. */
2183 if (flag_reorder_blocks_and_partition
)
2185 flag_reorder_blocks_and_partition
= 0;
2186 flag_reorder_blocks
= 1;
2190 /* A C compound statement to output to stdio stream STREAM the
2191 assembler syntax for an instruction operand X. X is an RTL
2194 CODE is a value that can be used to specify one of several ways
2195 of printing the operand. It is used when identical operands
2196 must be printed differently depending on the context. CODE
2197 comes from the '%' specification that was used to request
2198 printing of the operand. If the specification was just '%DIGIT'
2199 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
2200 is the ASCII code for LTR.
2202 If X is a register, this macro should print the register's name.
2203 The names can be found in an array 'reg_names' whose type is
2204 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
2206 When the machine description has a specification '%PUNCT' (a '%'
2207 followed by a punctuation character), this macro is called with
2208 a null pointer for X and the punctuation character for CODE.
2210 'a', 'c', 'l', and 'n' are reserved.
2212 The Xtensa specific codes are:
2214 'd' CONST_INT, print as signed decimal
2215 'x' CONST_INT, print as signed hexadecimal
2216 'K' CONST_INT, print number of bits in mask for EXTUI
2217 'R' CONST_INT, print (X & 0x1f)
2218 'L' CONST_INT, print ((32 - X) & 0x1f)
2219 'D' REG, print second register of double-word register operand
2220 'N' MEM, print address of next word following a memory operand
2221 'v' MEM, if memory reference is volatile, output a MEMW before it
2222 't' any constant, add "@h" suffix for top 16 bits
2223 'b' any constant, add "@l" suffix for bottom 16 bits
2227 printx (FILE *file
, signed int val
)
2229 /* Print a hexadecimal value in a nice way. */
2230 if ((val
> -0xa) && (val
< 0xa))
2231 fprintf (file
, "%d", val
);
2233 fprintf (file
, "-0x%x", -val
);
2235 fprintf (file
, "0x%x", val
);
2240 print_operand (FILE *file
, rtx x
, int letter
)
2243 error ("PRINT_OPERAND null pointer");
2248 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2249 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
2251 output_operand_lossage ("invalid %%D value");
2255 if (GET_CODE (x
) == MEM
)
2257 /* For a volatile memory reference, emit a MEMW before the
2259 if (MEM_VOLATILE_P (x
) && TARGET_SERIALIZE_VOLATILE
)
2260 fprintf (file
, "memw\n\t");
2263 output_operand_lossage ("invalid %%v value");
2267 if (GET_CODE (x
) == MEM
2268 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2270 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? SFmode
: SImode
, 4);
2271 output_address (XEXP (x
, 0));
2274 output_operand_lossage ("invalid %%N value");
2278 if (GET_CODE (x
) == CONST_INT
)
2281 unsigned val
= INTVAL (x
);
2287 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2288 fatal_insn ("invalid mask", x
);
2290 fprintf (file
, "%d", num_bits
);
2293 output_operand_lossage ("invalid %%K value");
2297 if (GET_CODE (x
) == CONST_INT
)
2298 fprintf (file
, "%ld", (32 - INTVAL (x
)) & 0x1f);
2300 output_operand_lossage ("invalid %%L value");
2304 if (GET_CODE (x
) == CONST_INT
)
2305 fprintf (file
, "%ld", INTVAL (x
) & 0x1f);
2307 output_operand_lossage ("invalid %%R value");
2311 if (GET_CODE (x
) == CONST_INT
)
2312 printx (file
, INTVAL (x
));
2314 output_operand_lossage ("invalid %%x value");
2318 if (GET_CODE (x
) == CONST_INT
)
2319 fprintf (file
, "%ld", INTVAL (x
));
2321 output_operand_lossage ("invalid %%d value");
2326 if (GET_CODE (x
) == CONST_INT
)
2328 printx (file
, INTVAL (x
));
2329 fputs (letter
== 't' ? "@h" : "@l", file
);
2331 else if (GET_CODE (x
) == CONST_DOUBLE
)
2334 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2335 if (GET_MODE (x
) == SFmode
)
2338 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
2339 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2342 output_operand_lossage ("invalid %%t/%%b value");
2344 else if (GET_CODE (x
) == CONST
)
2346 /* X must be a symbolic constant on ELF. Write an expression
2347 suitable for 'const16' that sets the high or low 16 bits. */
2348 if (GET_CODE (XEXP (x
, 0)) != PLUS
2349 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2350 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2351 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2352 output_operand_lossage ("invalid %%t/%%b value");
2353 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2354 fputs (letter
== 't' ? "@h" : "@l", file
);
2355 /* There must be a non-alphanumeric character between 'h' or 'l'
2356 and the number. The '-' is added by print_operand() already. */
2357 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2359 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2363 output_addr_const (file
, x
);
2364 fputs (letter
== 't' ? "@h" : "@l", file
);
2369 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2370 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2371 else if (GET_CODE (x
) == MEM
)
2372 output_address (XEXP (x
, 0));
2373 else if (GET_CODE (x
) == CONST_INT
)
2374 fprintf (file
, "%ld", INTVAL (x
));
2376 output_addr_const (file
, x
);
2381 /* A C compound statement to output to stdio stream STREAM the
2382 assembler syntax for an instruction operand that is a memory
2383 reference whose address is ADDR. ADDR is an RTL expression. */
2386 print_operand_address (FILE *file
, rtx addr
)
2389 error ("PRINT_OPERAND_ADDRESS, null pointer");
2391 switch (GET_CODE (addr
))
2394 fatal_insn ("invalid address", addr
);
2398 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2404 rtx offset
= (rtx
)0;
2405 rtx arg0
= XEXP (addr
, 0);
2406 rtx arg1
= XEXP (addr
, 1);
2408 if (GET_CODE (arg0
) == REG
)
2413 else if (GET_CODE (arg1
) == REG
)
2419 fatal_insn ("no register in address", addr
);
2421 if (CONSTANT_P (offset
))
2423 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2424 output_addr_const (file
, offset
);
2427 fatal_insn ("address offset not a constant", addr
);
2435 output_addr_const (file
, addr
);
2442 xtensa_output_addr_const_extra (FILE *fp
, rtx x
)
2444 if (GET_CODE (x
) == UNSPEC
&& XVECLEN (x
, 0) == 1)
2446 switch (XINT (x
, 1))
2449 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2450 fputs ("@TPOFF", fp
);
2453 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2454 fputs ("@DTPOFF", fp
);
2459 output_addr_const (fp
, XVECEXP (x
, 0, 0));
2473 xtensa_output_literal (FILE *file
, rtx x
, enum machine_mode mode
, int labelno
)
2480 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2482 switch (GET_MODE_CLASS (mode
))
2485 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
);
2487 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2491 REAL_VALUE_TO_TARGET_SINGLE (r
, value_long
[0]);
2492 if (HOST_BITS_PER_LONG
> 32)
2493 value_long
[0] &= 0xffffffff;
2494 fprintf (file
, "0x%08lx\n", value_long
[0]);
2498 REAL_VALUE_TO_TARGET_DOUBLE (r
, value_long
);
2499 if (HOST_BITS_PER_LONG
> 32)
2501 value_long
[0] &= 0xffffffff;
2502 value_long
[1] &= 0xffffffff;
2504 fprintf (file
, "0x%08lx, 0x%08lx\n",
2505 value_long
[0], value_long
[1]);
2515 case MODE_PARTIAL_INT
:
2516 size
= GET_MODE_SIZE (mode
);
2520 output_addr_const (file
, x
);
2525 split_double (x
, &first
, &second
);
2526 output_addr_const (file
, first
);
2528 output_addr_const (file
, second
);
2543 /* Return the bytes needed to compute the frame pointer from the current
2546 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2547 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2550 compute_frame_size (int size
)
2552 /* Add space for the incoming static chain value. */
2553 if (cfun
->static_chain_decl
!= NULL
)
2554 size
+= (1 * UNITS_PER_WORD
);
2556 xtensa_current_frame_size
=
2557 XTENSA_STACK_ALIGN (size
2558 + crtl
->outgoing_args_size
2559 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2560 return xtensa_current_frame_size
;
2565 xtensa_frame_pointer_required (void)
2567 /* The code to expand builtin_frame_addr and builtin_return_addr
2568 currently uses the hard_frame_pointer instead of frame_pointer.
2569 This seems wrong but maybe it's necessary for other architectures.
2570 This function is derived from the i386 code. */
2572 if (cfun
->machine
->accesses_prev_frame
)
2579 /* minimum frame = reg save area (4 words) plus static chain (1 word)
2580 and the total number of words must be a multiple of 128 bits. */
2581 #define MIN_FRAME_SIZE (8 * UNITS_PER_WORD)
2584 xtensa_expand_prologue (void)
2586 HOST_WIDE_INT total_size
;
2590 total_size
= compute_frame_size (get_frame_size ());
2591 size_rtx
= GEN_INT (total_size
);
2593 if (total_size
< (1 << (12+3)))
2594 insn
= emit_insn (gen_entry (size_rtx
));
2597 /* Use a8 as a temporary since a0-a7 may be live. */
2598 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2599 emit_insn (gen_entry (GEN_INT (MIN_FRAME_SIZE
)));
2600 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2601 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2602 insn
= emit_insn (gen_movsi (stack_pointer_rtx
, tmp_reg
));
2605 if (frame_pointer_needed
)
2607 if (cfun
->machine
->set_frame_ptr_insn
)
2611 push_topmost_sequence ();
2612 first
= get_insns ();
2613 pop_topmost_sequence ();
2615 /* For all instructions prior to set_frame_ptr_insn, replace
2616 hard_frame_pointer references with stack_pointer. */
2618 insn
!= cfun
->machine
->set_frame_ptr_insn
;
2619 insn
= NEXT_INSN (insn
))
2623 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2624 hard_frame_pointer_rtx
,
2626 df_insn_rescan (insn
);
2631 insn
= emit_insn (gen_movsi (hard_frame_pointer_rtx
,
2632 stack_pointer_rtx
));
2635 /* Create a note to describe the CFA. Because this is only used to set
2636 DW_AT_frame_base for debug info, don't bother tracking changes through
2637 each instruction in the prologue. It just takes up space. */
2638 note_rtx
= gen_rtx_SET (VOIDmode
, (frame_pointer_needed
2639 ? hard_frame_pointer_rtx
2640 : stack_pointer_rtx
),
2641 plus_constant (stack_pointer_rtx
, -total_size
));
2642 RTX_FRAME_RELATED_P (insn
) = 1;
2643 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, note_rtx
);
2647 /* Clear variables at function end. */
2650 xtensa_function_epilogue (FILE *file ATTRIBUTE_UNUSED
,
2651 HOST_WIDE_INT size ATTRIBUTE_UNUSED
)
2653 xtensa_current_frame_size
= 0;
2658 xtensa_return_addr (int count
, rtx frame
)
2660 rtx result
, retaddr
, curaddr
, label
;
2663 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
2666 rtx addr
= plus_constant (frame
, -4 * UNITS_PER_WORD
);
2667 addr
= memory_address (Pmode
, addr
);
2668 retaddr
= gen_reg_rtx (Pmode
);
2669 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
2672 /* The 2 most-significant bits of the return address on Xtensa hold
2673 the register window size. To get the real return address, these
2674 bits must be replaced with the high bits from some address in the
2677 /* Get the 2 high bits of a local label in the code. */
2678 curaddr
= gen_reg_rtx (Pmode
);
2679 label
= gen_label_rtx ();
2681 LABEL_PRESERVE_P (label
) = 1;
2682 emit_move_insn (curaddr
, gen_rtx_LABEL_REF (Pmode
, label
));
2683 emit_insn (gen_lshrsi3 (curaddr
, curaddr
, GEN_INT (30)));
2684 emit_insn (gen_ashlsi3 (curaddr
, curaddr
, GEN_INT (30)));
2686 /* Clear the 2 high bits of the return address. */
2687 result
= gen_reg_rtx (Pmode
);
2688 emit_insn (gen_ashlsi3 (result
, retaddr
, GEN_INT (2)));
2689 emit_insn (gen_lshrsi3 (result
, result
, GEN_INT (2)));
2691 /* Combine them to get the result. */
2692 emit_insn (gen_iorsi3 (result
, result
, curaddr
));
2697 /* Create the va_list data type.
2699 This structure is set up by __builtin_saveregs. The __va_reg field
2700 points to a stack-allocated region holding the contents of the
2701 incoming argument registers. The __va_ndx field is an index
2702 initialized to the position of the first unnamed (variable)
2703 argument. This same index is also used to address the arguments
2704 passed in memory. Thus, the __va_stk field is initialized to point
2705 to the position of the first argument in memory offset to account
2706 for the arguments passed in registers and to account for the size
2707 of the argument registers not being 16-byte aligned. E.G., there
2708 are 6 argument registers of 4 bytes each, but we want the __va_ndx
2709 for the first stack argument to have the maximal alignment of 16
2710 bytes, so we offset the __va_stk address by 32 bytes so that
2711 __va_stk[32] references the first argument on the stack. */
2714 xtensa_build_builtin_va_list (void)
2716 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
2718 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2719 type_decl
= build_decl (BUILTINS_LOCATION
,
2720 TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
2722 f_stk
= build_decl (BUILTINS_LOCATION
,
2723 FIELD_DECL
, get_identifier ("__va_stk"),
2725 f_reg
= build_decl (BUILTINS_LOCATION
,
2726 FIELD_DECL
, get_identifier ("__va_reg"),
2728 f_ndx
= build_decl (BUILTINS_LOCATION
,
2729 FIELD_DECL
, get_identifier ("__va_ndx"),
2732 DECL_FIELD_CONTEXT (f_stk
) = record
;
2733 DECL_FIELD_CONTEXT (f_reg
) = record
;
2734 DECL_FIELD_CONTEXT (f_ndx
) = record
;
2736 TYPE_STUB_DECL (record
) = type_decl
;
2737 TYPE_NAME (record
) = type_decl
;
2738 TYPE_FIELDS (record
) = f_stk
;
2739 DECL_CHAIN (f_stk
) = f_reg
;
2740 DECL_CHAIN (f_reg
) = f_ndx
;
2742 layout_type (record
);
2747 /* Save the incoming argument registers on the stack. Returns the
2748 address of the saved registers. */
2751 xtensa_builtin_saveregs (void)
2754 int arg_words
= crtl
->args
.info
.arg_words
;
2755 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
2760 /* Allocate the general-purpose register space. */
2761 gp_regs
= assign_stack_local
2762 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
2763 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
2765 /* Now store the incoming registers. */
2766 cfun
->machine
->need_a7_copy
= true;
2767 cfun
->machine
->vararg_a7
= true;
2768 move_block_from_reg (GP_ARG_FIRST
+ arg_words
,
2769 adjust_address (gp_regs
, BLKmode
,
2770 arg_words
* UNITS_PER_WORD
),
2772 gcc_assert (cfun
->machine
->vararg_a7_copy
!= 0);
2773 emit_insn_before (cfun
->machine
->vararg_a7_copy
, get_insns ());
2775 return XEXP (gp_regs
, 0);
2779 /* Implement `va_start' for varargs and stdarg. We look at the
2780 current function to fill in an initial va_list. */
2783 xtensa_va_start (tree valist
, rtx nextarg ATTRIBUTE_UNUSED
)
2791 arg_words
= crtl
->args
.info
.arg_words
;
2793 f_stk
= TYPE_FIELDS (va_list_type_node
);
2794 f_reg
= DECL_CHAIN (f_stk
);
2795 f_ndx
= DECL_CHAIN (f_reg
);
2797 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
, NULL_TREE
);
2798 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
2800 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
2803 /* Call __builtin_saveregs; save the result in __va_reg */
2804 u
= make_tree (sizetype
, expand_builtin_saveregs ());
2805 u
= fold_convert (ptr_type_node
, u
);
2806 t
= build2 (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
2807 TREE_SIDE_EFFECTS (t
) = 1;
2808 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2810 /* Set the __va_stk member to ($arg_ptr - 32). */
2811 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
2812 u
= fold_build2 (POINTER_PLUS_EXPR
, ptr_type_node
, u
, size_int (-32));
2813 t
= build2 (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
2814 TREE_SIDE_EFFECTS (t
) = 1;
2815 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2817 /* Set the __va_ndx member. If the first variable argument is on
2818 the stack, adjust __va_ndx by 2 words to account for the extra
2819 alignment offset for __va_stk. */
2820 if (arg_words
>= MAX_ARGS_IN_REGISTERS
)
2822 t
= build2 (MODIFY_EXPR
, integer_type_node
, ndx
,
2823 build_int_cst (integer_type_node
, arg_words
* UNITS_PER_WORD
));
2824 TREE_SIDE_EFFECTS (t
) = 1;
2825 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2829 /* Implement `va_arg'. */
2832 xtensa_gimplify_va_arg_expr (tree valist
, tree type
, gimple_seq
*pre_p
,
2833 gimple_seq
*post_p ATTRIBUTE_UNUSED
)
2838 tree type_size
, array
, orig_ndx
, addr
, size
, va_size
, t
;
2839 tree lab_false
, lab_over
, lab_false2
;
2842 indirect
= pass_by_reference (NULL
, TYPE_MODE (type
), type
, false);
2844 type
= build_pointer_type (type
);
2846 /* Handle complex values as separate real and imaginary parts. */
2847 if (TREE_CODE (type
) == COMPLEX_TYPE
)
2849 tree real_part
, imag_part
;
2851 real_part
= xtensa_gimplify_va_arg_expr (valist
, TREE_TYPE (type
),
2853 real_part
= get_initialized_tmp_var (real_part
, pre_p
, NULL
);
2855 imag_part
= xtensa_gimplify_va_arg_expr (unshare_expr (valist
),
2858 imag_part
= get_initialized_tmp_var (imag_part
, pre_p
, NULL
);
2860 return build2 (COMPLEX_EXPR
, type
, real_part
, imag_part
);
2863 f_stk
= TYPE_FIELDS (va_list_type_node
);
2864 f_reg
= DECL_CHAIN (f_stk
);
2865 f_ndx
= DECL_CHAIN (f_reg
);
2867 stk
= build3 (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
,
2869 reg
= build3 (COMPONENT_REF
, TREE_TYPE (f_reg
), unshare_expr (valist
),
2871 ndx
= build3 (COMPONENT_REF
, TREE_TYPE (f_ndx
), unshare_expr (valist
),
2874 type_size
= size_in_bytes (type
);
2875 va_size
= round_up (type_size
, UNITS_PER_WORD
);
2876 gimplify_expr (&va_size
, pre_p
, NULL
, is_gimple_val
, fb_rvalue
);
2879 /* First align __va_ndx if necessary for this arg:
2881 orig_ndx = (AP).__va_ndx;
2882 if (__alignof__ (TYPE) > 4 )
2883 orig_ndx = ((orig_ndx + __alignof__ (TYPE) - 1)
2884 & -__alignof__ (TYPE)); */
2886 orig_ndx
= get_initialized_tmp_var (ndx
, pre_p
, NULL
);
2888 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
2890 int align
= MIN (TYPE_ALIGN (type
), STACK_BOUNDARY
) / BITS_PER_UNIT
;
2892 t
= build2 (PLUS_EXPR
, integer_type_node
, unshare_expr (orig_ndx
),
2893 build_int_cst (integer_type_node
, align
- 1));
2894 t
= build2 (BIT_AND_EXPR
, integer_type_node
, t
,
2895 build_int_cst (integer_type_node
, -align
));
2896 gimplify_assign (unshare_expr (orig_ndx
), t
, pre_p
);
2900 /* Increment __va_ndx to point past the argument:
2902 (AP).__va_ndx = orig_ndx + __va_size (TYPE); */
2904 t
= fold_convert (integer_type_node
, va_size
);
2905 t
= build2 (PLUS_EXPR
, integer_type_node
, orig_ndx
, t
);
2906 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
2909 /* Check if the argument is in registers:
2911 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2912 && !must_pass_in_stack (type))
2913 __array = (AP).__va_reg; */
2915 array
= create_tmp_var (ptr_type_node
, NULL
);
2918 if (!targetm
.calls
.must_pass_in_stack (TYPE_MODE (type
), type
))
2920 lab_false
= create_artificial_label (UNKNOWN_LOCATION
);
2921 lab_over
= create_artificial_label (UNKNOWN_LOCATION
);
2923 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (ndx
),
2924 build_int_cst (integer_type_node
,
2925 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
2926 t
= build3 (COND_EXPR
, void_type_node
, t
,
2927 build1 (GOTO_EXPR
, void_type_node
, lab_false
),
2929 gimplify_and_add (t
, pre_p
);
2931 gimplify_assign (unshare_expr (array
), reg
, pre_p
);
2933 t
= build1 (GOTO_EXPR
, void_type_node
, lab_over
);
2934 gimplify_and_add (t
, pre_p
);
2936 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false
);
2937 gimplify_and_add (t
, pre_p
);
2941 /* ...otherwise, the argument is on the stack (never split between
2942 registers and the stack -- change __va_ndx if necessary):
2946 if (orig_ndx <= __MAX_ARGS_IN_REGISTERS * 4)
2947 (AP).__va_ndx = 32 + __va_size (TYPE);
2948 __array = (AP).__va_stk;
2951 lab_false2
= create_artificial_label (UNKNOWN_LOCATION
);
2953 t
= build2 (GT_EXPR
, boolean_type_node
, unshare_expr (orig_ndx
),
2954 build_int_cst (integer_type_node
,
2955 MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
));
2956 t
= build3 (COND_EXPR
, void_type_node
, t
,
2957 build1 (GOTO_EXPR
, void_type_node
, lab_false2
),
2959 gimplify_and_add (t
, pre_p
);
2961 t
= size_binop (PLUS_EXPR
, unshare_expr (va_size
), size_int (32));
2962 t
= fold_convert (integer_type_node
, t
);
2963 gimplify_assign (unshare_expr (ndx
), t
, pre_p
);
2965 t
= build1 (LABEL_EXPR
, void_type_node
, lab_false2
);
2966 gimplify_and_add (t
, pre_p
);
2968 gimplify_assign (array
, stk
, pre_p
);
2972 t
= build1 (LABEL_EXPR
, void_type_node
, lab_over
);
2973 gimplify_and_add (t
, pre_p
);
2977 /* Given the base array pointer (__array) and index to the subsequent
2978 argument (__va_ndx), find the address:
2980 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2984 The results are endian-dependent because values smaller than one word
2985 are aligned differently. */
2988 if (BYTES_BIG_ENDIAN
&& TREE_CODE (type_size
) == INTEGER_CST
)
2990 t
= fold_build2 (GE_EXPR
, boolean_type_node
, unshare_expr (type_size
),
2991 size_int (PARM_BOUNDARY
/ BITS_PER_UNIT
));
2992 t
= fold_build3 (COND_EXPR
, sizetype
, t
, unshare_expr (va_size
),
2993 unshare_expr (type_size
));
2997 size
= unshare_expr (va_size
);
2999 t
= fold_convert (sizetype
, unshare_expr (ndx
));
3000 t
= build2 (MINUS_EXPR
, sizetype
, t
, size
);
3001 addr
= build2 (POINTER_PLUS_EXPR
, ptr_type_node
, unshare_expr (array
), t
);
3003 addr
= fold_convert (build_pointer_type (type
), addr
);
3005 addr
= build_va_arg_indirect_ref (addr
);
3006 return build_va_arg_indirect_ref (addr
);
3014 XTENSA_BUILTIN_UMULSIDI3
,
3015 XTENSA_BUILTIN_THREAD_POINTER
,
3016 XTENSA_BUILTIN_SET_THREAD_POINTER
,
3022 xtensa_init_builtins (void)
3026 ftype
= build_function_type_list (unsigned_intDI_type_node
,
3027 unsigned_intSI_type_node
,
3028 unsigned_intSI_type_node
, NULL_TREE
);
3030 decl
= add_builtin_function ("__builtin_umulsidi3", ftype
,
3031 XTENSA_BUILTIN_UMULSIDI3
, BUILT_IN_MD
,
3032 "__umulsidi3", NULL_TREE
);
3033 TREE_NOTHROW (decl
) = 1;
3034 TREE_READONLY (decl
) = 1;
3036 if (TARGET_THREADPTR
)
3038 ftype
= build_function_type (ptr_type_node
, void_list_node
);
3039 decl
= add_builtin_function ("__builtin_thread_pointer", ftype
,
3040 XTENSA_BUILTIN_THREAD_POINTER
, BUILT_IN_MD
,
3042 TREE_READONLY (decl
) = 1;
3043 TREE_NOTHROW (decl
) = 1;
3045 ftype
= build_function_type_list (void_type_node
, ptr_type_node
,
3047 decl
= add_builtin_function ("__builtin_set_thread_pointer", ftype
,
3048 XTENSA_BUILTIN_SET_THREAD_POINTER
,
3049 BUILT_IN_MD
, NULL
, NULL_TREE
);
3050 TREE_NOTHROW (decl
) = 1;
3056 xtensa_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*args
,
3057 bool ignore ATTRIBUTE_UNUSED
)
3059 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3064 case XTENSA_BUILTIN_UMULSIDI3
:
3067 if ((TREE_CODE (arg0
) == INTEGER_CST
&& TREE_CODE (arg1
) == INTEGER_CST
)
3068 || TARGET_MUL32_HIGH
)
3069 return fold_build2 (MULT_EXPR
, unsigned_intDI_type_node
,
3070 fold_convert (unsigned_intDI_type_node
, arg0
),
3071 fold_convert (unsigned_intDI_type_node
, arg1
));
3074 case XTENSA_BUILTIN_THREAD_POINTER
:
3075 case XTENSA_BUILTIN_SET_THREAD_POINTER
:
3079 internal_error ("bad builtin code");
3088 xtensa_expand_builtin (tree exp
, rtx target
,
3089 rtx subtarget ATTRIBUTE_UNUSED
,
3090 enum machine_mode mode ATTRIBUTE_UNUSED
,
3093 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
3094 unsigned int fcode
= DECL_FUNCTION_CODE (fndecl
);
3099 case XTENSA_BUILTIN_UMULSIDI3
:
3100 /* The umulsidi3 builtin is just a mechanism to avoid calling the real
3101 __umulsidi3 function when the Xtensa configuration can directly
3102 implement it. If not, just call the function. */
3103 return expand_call (exp
, target
, ignore
);
3105 case XTENSA_BUILTIN_THREAD_POINTER
:
3106 if (!target
|| !register_operand (target
, Pmode
))
3107 target
= gen_reg_rtx (Pmode
);
3108 emit_insn (gen_load_tp (target
));
3111 case XTENSA_BUILTIN_SET_THREAD_POINTER
:
3112 arg
= expand_normal (CALL_EXPR_ARG (exp
, 0));
3113 if (!register_operand (arg
, Pmode
))
3114 arg
= copy_to_mode_reg (Pmode
, arg
);
3115 emit_insn (gen_set_tp (arg
));
3119 internal_error ("bad builtin code");
3126 xtensa_preferred_reload_class (rtx x
, enum reg_class rclass
, int isoutput
)
3128 if (!isoutput
&& CONSTANT_P (x
) && GET_CODE (x
) == CONST_DOUBLE
)
3131 /* Don't use the stack pointer or hard frame pointer for reloads!
3132 The hard frame pointer would normally be OK except that it may
3133 briefly hold an incoming argument in the prologue, and reload
3134 won't know that it is live because the hard frame pointer is
3135 treated specially. */
3137 if (rclass
== AR_REGS
|| rclass
== GR_REGS
)
3145 xtensa_secondary_reload (bool in_p
, rtx x
, reg_class_t rclass
,
3146 enum machine_mode mode
, secondary_reload_info
*sri
)
3150 if (in_p
&& constantpool_mem_p (x
))
3152 if (rclass
== FP_REGS
)
3156 sri
->icode
= CODE_FOR_reloadqi_literal
;
3157 else if (mode
== HImode
)
3158 sri
->icode
= CODE_FOR_reloadhi_literal
;
3161 regno
= xt_true_regnum (x
);
3162 if (ACC_REG_P (regno
))
3163 return ((rclass
== GR_REGS
|| rclass
== RL_REGS
) ? NO_REGS
: RL_REGS
);
3164 if (rclass
== ACC_REG
)
3165 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
3172 order_regs_for_local_alloc (void)
3174 if (!leaf_function_p ())
3176 memcpy (reg_alloc_order
, reg_nonleaf_alloc_order
,
3177 FIRST_PSEUDO_REGISTER
* sizeof (int));
3181 int i
, num_arg_regs
;
3184 /* Use the AR registers in increasing order (skipping a0 and a1)
3185 but save the incoming argument registers for a last resort. */
3186 num_arg_regs
= crtl
->args
.info
.arg_words
;
3187 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
3188 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
3189 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
3190 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
3191 for (i
= 0; i
< num_arg_regs
; i
++)
3192 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
3194 /* List the coprocessor registers in order. */
3195 for (i
= 0; i
< BR_REG_NUM
; i
++)
3196 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
3198 /* List the FP registers in order for now. */
3199 for (i
= 0; i
< 16; i
++)
3200 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
3202 /* GCC requires that we list *all* the registers.... */
3203 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
3204 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
3205 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
3206 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
3208 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
3213 /* Some Xtensa targets support multiple bss sections. If the section
3214 name ends with ".bss", add SECTION_BSS to the flags. */
3217 xtensa_multibss_section_type_flags (tree decl
, const char *name
, int reloc
)
3219 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
3222 suffix
= strrchr (name
, '.');
3223 if (suffix
&& strcmp (suffix
, ".bss") == 0)
3225 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
3226 && DECL_INITIAL (decl
) == NULL_TREE
))
3227 flags
|= SECTION_BSS
; /* @nobits */
3229 warning (0, "only uninitialized variables can be placed in a "
3237 /* The literal pool stays with the function. */
3240 xtensa_select_rtx_section (enum machine_mode mode ATTRIBUTE_UNUSED
,
3241 rtx x ATTRIBUTE_UNUSED
,
3242 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
)
3244 return function_section (current_function_decl
);
3248 /* Compute a (partial) cost for rtx X. Return true if the complete
3249 cost has been computed, and false if subexpressions should be
3250 scanned. In either case, *TOTAL contains the cost result. */
3253 xtensa_rtx_costs (rtx x
, int code
, int outer_code
, int *total
,
3254 bool speed ATTRIBUTE_UNUSED
)
3262 if (xtensa_simm12b (INTVAL (x
)))
3269 if (xtensa_simm8 (INTVAL (x
))
3270 || xtensa_simm8x256 (INTVAL (x
)))
3277 if (xtensa_mask_immediate (INTVAL (x
)))
3284 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
3295 /* No way to tell if X is the 2nd operand so be conservative. */
3298 if (xtensa_simm12b (INTVAL (x
)))
3300 else if (TARGET_CONST16
)
3301 *total
= COSTS_N_INSNS (2);
3310 *total
= COSTS_N_INSNS (2);
3317 *total
= COSTS_N_INSNS (4);
3325 (GET_MODE_SIZE (GET_MODE (x
)) > UNITS_PER_WORD
) ? 2 : 1;
3327 if (memory_address_p (GET_MODE (x
), XEXP ((x
), 0)))
3328 *total
= COSTS_N_INSNS (num_words
);
3330 *total
= COSTS_N_INSNS (2*num_words
);
3336 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
3340 *total
= COSTS_N_INSNS (TARGET_NSA
? 1 : 50);
3344 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 3 : 2);
3350 if (GET_MODE (x
) == DImode
)
3351 *total
= COSTS_N_INSNS (2);
3353 *total
= COSTS_N_INSNS (1);
3359 if (GET_MODE (x
) == DImode
)
3360 *total
= COSTS_N_INSNS (50);
3362 *total
= COSTS_N_INSNS (1);
3367 enum machine_mode xmode
= GET_MODE (x
);
3368 if (xmode
== SFmode
)
3369 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3370 else if (xmode
== DFmode
)
3371 *total
= COSTS_N_INSNS (50);
3373 *total
= COSTS_N_INSNS (4);
3380 enum machine_mode xmode
= GET_MODE (x
);
3381 if (xmode
== SFmode
)
3382 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3383 else if (xmode
== DFmode
|| xmode
== DImode
)
3384 *total
= COSTS_N_INSNS (50);
3386 *total
= COSTS_N_INSNS (1);
3391 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 4 : 2);
3396 enum machine_mode xmode
= GET_MODE (x
);
3397 if (xmode
== SFmode
)
3398 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3399 else if (xmode
== DFmode
)
3400 *total
= COSTS_N_INSNS (50);
3401 else if (xmode
== DImode
)
3402 *total
= COSTS_N_INSNS (TARGET_MUL32_HIGH
? 10 : 50);
3403 else if (TARGET_MUL32
)
3404 *total
= COSTS_N_INSNS (4);
3405 else if (TARGET_MAC16
)
3406 *total
= COSTS_N_INSNS (16);
3407 else if (TARGET_MUL16
)
3408 *total
= COSTS_N_INSNS (12);
3410 *total
= COSTS_N_INSNS (50);
3417 enum machine_mode xmode
= GET_MODE (x
);
3418 if (xmode
== SFmode
)
3420 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3423 else if (xmode
== DFmode
)
3425 *total
= COSTS_N_INSNS (50);
3434 enum machine_mode xmode
= GET_MODE (x
);
3435 if (xmode
== DImode
)
3436 *total
= COSTS_N_INSNS (50);
3437 else if (TARGET_DIV32
)
3438 *total
= COSTS_N_INSNS (32);
3440 *total
= COSTS_N_INSNS (50);
3445 if (GET_MODE (x
) == SFmode
)
3446 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3448 *total
= COSTS_N_INSNS (50);
3455 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3460 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3465 *total
= COSTS_N_INSNS (1);
3473 /* Worker function for TARGET_RETURN_IN_MEMORY. */
3476 xtensa_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
3478 return ((unsigned HOST_WIDE_INT
) int_size_in_bytes (type
)
3479 > 4 * UNITS_PER_WORD
);
3482 /* Worker function for TARGET_FUNCTION_VALUE. */
3485 xtensa_function_value (const_tree valtype
, const_tree func ATTRIBUTE_UNUSED
,
3488 return gen_rtx_REG ((INTEGRAL_TYPE_P (valtype
)
3489 && TYPE_PRECISION (valtype
) < BITS_PER_WORD
)
3490 ? SImode
: TYPE_MODE (valtype
),
3491 outgoing
? GP_OUTGOING_RETURN
: GP_RETURN
);
3494 /* The static chain is passed in memory. Provide rtx giving 'mem'
3495 expressions that denote where they are stored. */
3498 xtensa_static_chain (const_tree
ARG_UNUSED (fndecl
), bool incoming_p
)
3500 rtx base
= incoming_p
? arg_pointer_rtx
: stack_pointer_rtx
;
3501 return gen_frame_mem (Pmode
, plus_constant (base
, -5 * UNITS_PER_WORD
));
3505 /* TRAMPOLINE_TEMPLATE: For Xtensa, the trampoline must perform an ENTRY
3506 instruction with a minimal stack frame in order to get some free
3507 registers. Once the actual call target is known, the proper stack frame
3508 size is extracted from the ENTRY instruction at the target and the
3509 current frame is adjusted to match. The trampoline then transfers
3510 control to the instruction following the ENTRY at the target. Note:
3511 this assumes that the target begins with an ENTRY instruction. */
3514 xtensa_asm_trampoline_template (FILE *stream
)
3516 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3518 fprintf (stream
, "\t.begin no-transform\n");
3519 fprintf (stream
, "\tentry\tsp, %d\n", MIN_FRAME_SIZE
);
3523 /* Save the return address. */
3524 fprintf (stream
, "\tmov\ta10, a0\n");
3526 /* Use a CALL0 instruction to skip past the constants and in the
3527 process get the PC into A0. This allows PC-relative access to
3528 the constants without relying on L32R. */
3529 fprintf (stream
, "\tcall0\t.Lskipconsts\n");
3532 fprintf (stream
, "\tj\t.Lskipconsts\n");
3534 fprintf (stream
, "\t.align\t4\n");
3535 fprintf (stream
, ".Lchainval:%s0\n", integer_asm_op (4, TRUE
));
3536 fprintf (stream
, ".Lfnaddr:%s0\n", integer_asm_op (4, TRUE
));
3537 fprintf (stream
, ".Lskipconsts:\n");
3539 /* Load the static chain and function address from the trampoline. */
3542 fprintf (stream
, "\taddi\ta0, a0, 3\n");
3543 fprintf (stream
, "\tl32i\ta9, a0, 0\n");
3544 fprintf (stream
, "\tl32i\ta8, a0, 4\n");
3548 fprintf (stream
, "\tl32r\ta9, .Lchainval\n");
3549 fprintf (stream
, "\tl32r\ta8, .Lfnaddr\n");
3552 /* Store the static chain. */
3553 fprintf (stream
, "\ts32i\ta9, sp, %d\n", MIN_FRAME_SIZE
- 20);
3555 /* Set the proper stack pointer value. */
3556 fprintf (stream
, "\tl32i\ta9, a8, 0\n");
3557 fprintf (stream
, "\textui\ta9, a9, %d, 12\n",
3558 TARGET_BIG_ENDIAN
? 8 : 12);
3559 fprintf (stream
, "\tslli\ta9, a9, 3\n");
3560 fprintf (stream
, "\taddi\ta9, a9, %d\n", -MIN_FRAME_SIZE
);
3561 fprintf (stream
, "\tsub\ta9, sp, a9\n");
3562 fprintf (stream
, "\tmovsp\tsp, a9\n");
3565 /* Restore the return address. */
3566 fprintf (stream
, "\tmov\ta0, a10\n");
3568 /* Jump to the instruction following the ENTRY. */
3569 fprintf (stream
, "\taddi\ta8, a8, 3\n");
3570 fprintf (stream
, "\tjx\ta8\n");
3572 /* Pad size to a multiple of TRAMPOLINE_ALIGNMENT. */
3574 fprintf (stream
, "\t.byte\t0\n");
3576 fprintf (stream
, "\tnop\n");
3578 fprintf (stream
, "\t.end no-transform\n");
3582 xtensa_trampoline_init (rtx m_tramp
, tree fndecl
, rtx chain
)
3584 rtx func
= XEXP (DECL_RTL (fndecl
), 0);
3585 bool use_call0
= (TARGET_CONST16
|| TARGET_ABSOLUTE_LITERALS
);
3586 int chain_off
= use_call0
? 12 : 8;
3587 int func_off
= use_call0
? 16 : 12;
3589 emit_block_move (m_tramp
, assemble_trampoline_template (),
3590 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3592 emit_move_insn (adjust_address (m_tramp
, SImode
, chain_off
), chain
);
3593 emit_move_insn (adjust_address (m_tramp
, SImode
, func_off
), func
);
3594 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_sync_caches"),
3595 LCT_NORMAL
, VOIDmode
, 1, XEXP (m_tramp
, 0), Pmode
);
3599 #include "gt-xtensa.h"