1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001,2002 Free Software Foundation, Inc.
3 Contributed by Bob Wilson (bwilson@tensilica.com) at Tensilica.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING. If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
24 #include "coretypes.h"
28 #include "hard-reg-set.h"
29 #include "basic-block.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "insn-flags.h"
34 #include "insn-attr.h"
35 #include "insn-codes.h"
50 #include "target-def.h"
51 #include "langhooks.h"
53 /* Enumeration for all of the relational tests, so that we can build
54 arrays indexed by the test type, and not worry about the order
71 /* Cached operands, and operator to compare for use in set/branch on
75 /* what type of branch to use */
76 enum cmp_type branch_type
;
78 /* Array giving truth value on whether or not a given hard register
79 can support a given mode. */
80 char xtensa_hard_regno_mode_ok
[(int) MAX_MACHINE_MODE
][FIRST_PSEUDO_REGISTER
];
82 /* Current frame size calculated by compute_frame_size. */
83 unsigned xtensa_current_frame_size
;
85 /* Tables of ld/st opcode names for block moves */
86 const char *xtensa_ld_opcodes
[(int) MAX_MACHINE_MODE
];
87 const char *xtensa_st_opcodes
[(int) MAX_MACHINE_MODE
];
88 #define LARGEST_MOVE_RATIO 15
90 /* Define the structure for the machine field in struct function. */
91 struct machine_function
GTY(())
93 int accesses_prev_frame
;
94 bool incoming_a7_copied
;
97 /* Vector, indexed by hard register number, which contains 1 for a
98 register that is allowable in a candidate for leaf function
101 const char xtensa_leaf_regs
[FIRST_PSEUDO_REGISTER
] =
103 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
105 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
109 /* Map hard register number to register class */
110 const enum reg_class xtensa_regno_to_class
[FIRST_PSEUDO_REGISTER
] =
112 RL_REGS
, SP_REG
, RL_REGS
, RL_REGS
,
113 RL_REGS
, RL_REGS
, RL_REGS
, GR_REGS
,
114 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
115 RL_REGS
, RL_REGS
, RL_REGS
, RL_REGS
,
116 AR_REGS
, AR_REGS
, BR_REGS
,
117 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
118 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
119 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
120 FP_REGS
, FP_REGS
, FP_REGS
, FP_REGS
,
124 /* Map register constraint character to register class. */
125 enum reg_class xtensa_char_to_class
[256] =
127 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
128 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
129 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
130 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
131 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
132 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
133 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
134 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
135 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
136 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
137 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
138 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
139 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
140 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
141 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
142 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
143 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
144 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
145 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
146 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
147 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
148 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
149 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
150 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
151 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
152 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
153 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
154 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
155 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
156 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
157 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
158 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
159 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
160 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
161 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
162 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
163 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
164 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
165 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
166 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
167 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
168 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
169 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
170 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
171 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
172 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
173 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
174 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
175 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
176 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
177 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
178 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
179 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
180 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
181 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
182 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
183 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
184 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
185 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
186 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
187 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
188 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
189 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
190 NO_REGS
, NO_REGS
, NO_REGS
, NO_REGS
,
193 static int b4const_or_zero
PARAMS ((int));
194 static enum internal_test map_test_to_internal_test
PARAMS ((enum rtx_code
));
195 static rtx gen_int_relational
PARAMS ((enum rtx_code
, rtx
, rtx
, int *));
196 static rtx gen_float_relational
PARAMS ((enum rtx_code
, rtx
, rtx
));
197 static rtx gen_conditional_move
PARAMS ((rtx
));
198 static rtx fixup_subreg_mem
PARAMS ((rtx x
));
199 static enum machine_mode xtensa_find_mode_for_size
PARAMS ((unsigned));
200 static struct machine_function
* xtensa_init_machine_status
PARAMS ((void));
201 static void printx
PARAMS ((FILE *, signed int));
202 static unsigned int xtensa_multibss_section_type_flags
203 PARAMS ((tree
, const char *, int));
204 static void xtensa_select_rtx_section
205 PARAMS ((enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
));
206 static void xtensa_encode_section_info
PARAMS ((tree
, int));
207 static bool xtensa_rtx_costs
PARAMS ((rtx
, int, int, int *));
209 static rtx frame_size_const
;
210 static int current_function_arg_words
;
211 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
214 /* This macro generates the assembly code for function entry.
215 FILE is a stdio stream to output the code to.
216 SIZE is an int: how many units of temporary storage to allocate.
217 Refer to the array 'regs_ever_live' to determine which registers
218 to save; 'regs_ever_live[I]' is nonzero if register number I
219 is ever used in the function. This macro is responsible for
220 knowing which registers should not be saved even if used. */
222 #undef TARGET_ASM_FUNCTION_PROLOGUE
223 #define TARGET_ASM_FUNCTION_PROLOGUE xtensa_function_prologue
225 /* This macro generates the assembly code for function exit,
226 on machines that need it. If FUNCTION_EPILOGUE is not defined
227 then individual return instructions are generated for each
228 return statement. Args are same as for FUNCTION_PROLOGUE. */
230 #undef TARGET_ASM_FUNCTION_EPILOGUE
231 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
233 /* These hooks specify assembly directives for creating certain kinds
234 of integer object. */
236 #undef TARGET_ASM_ALIGNED_SI_OP
237 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
239 #undef TARGET_ASM_SELECT_RTX_SECTION
240 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
241 #undef TARGET_ENCODE_SECTION_INFO
242 #define TARGET_ENCODE_SECTION_INFO xtensa_encode_section_info
244 #undef TARGET_RTX_COSTS
245 #define TARGET_RTX_COSTS xtensa_rtx_costs
247 struct gcc_target targetm
= TARGET_INITIALIZER
;
251 * Functions to test Xtensa immediate operand validity.
285 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
292 return (v
== -1 || (v
>= 1 && v
<= 15));
299 return v
>= -32 && v
<= 95;
333 return v
>= -128 && v
<= 127;
340 return (v
>= 7 && v
<= 22);
347 return (v
& 3) == 0 && (v
>= 0 && v
<= 60);
354 return v
>= -2048 && v
<= 2047;
361 return v
>= 0 && v
<= 255;
368 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
375 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
379 /* This is just like the standard true_regnum() function except that it
380 works even when reg_renumber is not initialized. */
386 if (GET_CODE (x
) == REG
)
389 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
390 && reg_renumber
[REGNO (x
)] >= 0)
391 return reg_renumber
[REGNO (x
)];
394 if (GET_CODE (x
) == SUBREG
)
396 int base
= xt_true_regnum (SUBREG_REG (x
));
397 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
398 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
399 GET_MODE (SUBREG_REG (x
)),
400 SUBREG_BYTE (x
), GET_MODE (x
));
407 add_operand (op
, mode
)
409 enum machine_mode mode
;
411 if (GET_CODE (op
) == CONST_INT
)
412 return (xtensa_simm8 (INTVAL (op
)) ||
413 xtensa_simm8x256 (INTVAL (op
)));
415 return register_operand (op
, mode
);
420 arith_operand (op
, mode
)
422 enum machine_mode mode
;
424 if (GET_CODE (op
) == CONST_INT
)
425 return xtensa_simm8 (INTVAL (op
));
427 return register_operand (op
, mode
);
432 nonimmed_operand (op
, mode
)
434 enum machine_mode mode
;
436 /* We cannot use the standard nonimmediate_operand() predicate because
437 it includes constant pool memory operands. */
439 if (memory_operand (op
, mode
))
440 return !constantpool_address_p (XEXP (op
, 0));
442 return register_operand (op
, mode
);
447 mem_operand (op
, mode
)
449 enum machine_mode mode
;
451 /* We cannot use the standard memory_operand() predicate because
452 it includes constant pool memory operands. */
454 if (memory_operand (op
, mode
))
455 return !constantpool_address_p (XEXP (op
, 0));
462 xtensa_valid_move (mode
, operands
)
463 enum machine_mode mode
;
466 /* Either the destination or source must be a register, and the
467 MAC16 accumulator doesn't count. */
469 if (register_operand (operands
[0], mode
))
471 int dst_regnum
= xt_true_regnum (operands
[0]);
473 /* The stack pointer can only be assigned with a MOVSP opcode. */
474 if (dst_regnum
== STACK_POINTER_REGNUM
)
475 return (mode
== SImode
476 && register_operand (operands
[1], mode
)
477 && !ACC_REG_P (xt_true_regnum (operands
[1])));
479 if (!ACC_REG_P (dst_regnum
))
482 if (register_operand (operands
[1], mode
))
484 int src_regnum
= xt_true_regnum (operands
[1]);
485 if (!ACC_REG_P (src_regnum
))
493 mask_operand (op
, mode
)
495 enum machine_mode mode
;
497 if (GET_CODE (op
) == CONST_INT
)
498 return xtensa_mask_immediate (INTVAL (op
));
500 return register_operand (op
, mode
);
505 extui_fldsz_operand (op
, mode
)
507 enum machine_mode mode ATTRIBUTE_UNUSED
;
509 return ((GET_CODE (op
) == CONST_INT
)
510 && xtensa_mask_immediate ((1 << INTVAL (op
)) - 1));
515 sext_operand (op
, mode
)
517 enum machine_mode mode
;
520 return nonimmed_operand (op
, mode
);
521 return mem_operand (op
, mode
);
526 sext_fldsz_operand (op
, mode
)
528 enum machine_mode mode ATTRIBUTE_UNUSED
;
530 return ((GET_CODE (op
) == CONST_INT
) && xtensa_tp7 (INTVAL (op
) - 1));
535 lsbitnum_operand (op
, mode
)
537 enum machine_mode mode ATTRIBUTE_UNUSED
;
539 if (GET_CODE (op
) == CONST_INT
)
541 return (BITS_BIG_ENDIAN
542 ? (INTVAL (op
) == BITS_PER_WORD
-1)
543 : (INTVAL (op
) == 0));
555 return xtensa_b4const (v
);
560 branch_operand (op
, mode
)
562 enum machine_mode mode
;
564 if (GET_CODE (op
) == CONST_INT
)
565 return b4const_or_zero (INTVAL (op
));
567 return register_operand (op
, mode
);
572 ubranch_operand (op
, mode
)
574 enum machine_mode mode
;
576 if (GET_CODE (op
) == CONST_INT
)
577 return xtensa_b4constu (INTVAL (op
));
579 return register_operand (op
, mode
);
584 call_insn_operand (op
, mode
)
586 enum machine_mode mode ATTRIBUTE_UNUSED
;
588 if ((GET_CODE (op
) == REG
)
589 && (op
!= arg_pointer_rtx
)
590 && ((REGNO (op
) < FRAME_POINTER_REGNUM
)
591 || (REGNO (op
) > LAST_VIRTUAL_REGISTER
)))
594 if (CONSTANT_ADDRESS_P (op
))
596 /* Direct calls only allowed to static functions with PIC. */
597 return (!flag_pic
|| (GET_CODE (op
) == SYMBOL_REF
598 && SYMBOL_REF_FLAG (op
)));
606 move_operand (op
, mode
)
608 enum machine_mode mode
;
610 if (register_operand (op
, mode
))
613 /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
615 if (GET_CODE (op
) == CONSTANT_P_RTX
)
618 if (GET_CODE (op
) == CONST_INT
)
619 return xtensa_simm12b (INTVAL (op
));
621 if (GET_CODE (op
) == MEM
)
622 return memory_address_p (mode
, XEXP (op
, 0));
629 smalloffset_mem_p (op
)
632 if (GET_CODE (op
) == MEM
)
634 rtx addr
= XEXP (op
, 0);
635 if (GET_CODE (addr
) == REG
)
636 return REG_OK_FOR_BASE_P (addr
);
637 if (GET_CODE (addr
) == PLUS
)
639 rtx offset
= XEXP (addr
, 0);
640 if (GET_CODE (offset
) != CONST_INT
)
641 offset
= XEXP (addr
, 1);
642 if (GET_CODE (offset
) != CONST_INT
)
644 return xtensa_lsi4x4 (INTVAL (offset
));
652 smalloffset_double_mem_p (op
)
655 if (!smalloffset_mem_p (op
))
657 return smalloffset_mem_p (adjust_address (op
, GET_MODE (op
), 4));
662 constantpool_address_p (addr
)
667 if (GET_CODE (addr
) == CONST
)
671 /* only handle (PLUS (SYM, OFFSET)) form */
672 addr
= XEXP (addr
, 0);
673 if (GET_CODE (addr
) != PLUS
)
676 /* make sure the address is word aligned */
677 offset
= XEXP (addr
, 1);
678 if ((GET_CODE (offset
) != CONST_INT
)
679 || ((INTVAL (offset
) & 3) != 0))
682 sym
= XEXP (addr
, 0);
685 if ((GET_CODE (sym
) == SYMBOL_REF
)
686 && CONSTANT_POOL_ADDRESS_P (sym
))
693 constantpool_mem_p (op
)
696 if (GET_CODE (op
) == MEM
)
697 return constantpool_address_p (XEXP (op
, 0));
703 non_const_move_operand (op
, mode
)
705 enum machine_mode mode
;
707 if (register_operand (op
, mode
))
709 if (GET_CODE (op
) == SUBREG
)
710 op
= SUBREG_REG (op
);
711 if (GET_CODE (op
) == MEM
)
712 return memory_address_p (mode
, XEXP (op
, 0));
717 /* Accept the floating point constant 1 in the appropriate mode. */
720 const_float_1_operand (op
, mode
)
722 enum machine_mode mode
;
725 static REAL_VALUE_TYPE onedf
;
726 static REAL_VALUE_TYPE onesf
;
727 static int one_initialized
;
729 if ((GET_CODE (op
) != CONST_DOUBLE
)
730 || (mode
!= GET_MODE (op
))
731 || (mode
!= DFmode
&& mode
!= SFmode
))
734 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
736 if (! one_initialized
)
738 onedf
= REAL_VALUE_ATOF ("1.0", DFmode
);
739 onesf
= REAL_VALUE_ATOF ("1.0", SFmode
);
740 one_initialized
= TRUE
;
744 return REAL_VALUES_EQUAL (d
, onedf
);
746 return REAL_VALUES_EQUAL (d
, onesf
);
751 fpmem_offset_operand (op
, mode
)
753 enum machine_mode mode ATTRIBUTE_UNUSED
;
755 if (GET_CODE (op
) == CONST_INT
)
756 return xtensa_mem_offset (INTVAL (op
), SFmode
);
762 xtensa_extend_reg (dst
, src
)
766 rtx temp
= gen_reg_rtx (SImode
);
767 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
769 /* generate paradoxical subregs as needed so that the modes match */
770 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
771 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
773 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
774 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
779 xtensa_load_constant (dst
, src
)
783 enum machine_mode mode
= GET_MODE (dst
);
784 src
= force_const_mem (SImode
, src
);
786 /* PC-relative loads are always SImode so we have to add a SUBREG if that
787 is not the desired mode */
791 if (register_operand (dst
, mode
))
792 dst
= simplify_gen_subreg (SImode
, dst
, mode
, 0);
795 src
= force_reg (SImode
, src
);
796 src
= gen_lowpart_SUBREG (mode
, src
);
800 emit_move_insn (dst
, src
);
805 branch_operator (x
, mode
)
807 enum machine_mode mode
;
809 if (GET_MODE (x
) != mode
)
812 switch (GET_CODE (x
))
827 ubranch_operator (x
, mode
)
829 enum machine_mode mode
;
831 if (GET_MODE (x
) != mode
)
834 switch (GET_CODE (x
))
847 boolean_operator (x
, mode
)
849 enum machine_mode mode
;
851 if (GET_MODE (x
) != mode
)
854 switch (GET_CODE (x
))
867 xtensa_mask_immediate (v
)
870 #define MAX_MASK_SIZE 16
873 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
887 xtensa_mem_offset (v
, mode
)
889 enum machine_mode mode
;
894 /* Handle the worst case for block moves. See xtensa_expand_block_move
895 where we emit an optimized block move operation if the block can be
896 moved in < "move_ratio" pieces. The worst case is when the block is
897 aligned but has a size of (3 mod 4) (does this happen?) so that the
898 last piece requires a byte load/store. */
899 return (xtensa_uimm8 (v
) &&
900 xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
903 return xtensa_uimm8 (v
);
906 return xtensa_uimm8x2 (v
);
909 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
915 return xtensa_uimm8x4 (v
);
919 /* Make normal rtx_code into something we can index from an array */
921 static enum internal_test
922 map_test_to_internal_test (test_code
)
923 enum rtx_code test_code
;
925 enum internal_test test
= ITEST_MAX
;
930 case EQ
: test
= ITEST_EQ
; break;
931 case NE
: test
= ITEST_NE
; break;
932 case GT
: test
= ITEST_GT
; break;
933 case GE
: test
= ITEST_GE
; break;
934 case LT
: test
= ITEST_LT
; break;
935 case LE
: test
= ITEST_LE
; break;
936 case GTU
: test
= ITEST_GTU
; break;
937 case GEU
: test
= ITEST_GEU
; break;
938 case LTU
: test
= ITEST_LTU
; break;
939 case LEU
: test
= ITEST_LEU
; break;
946 /* Generate the code to compare two integer values. The return value is
947 the comparison expression. */
950 gen_int_relational (test_code
, cmp0
, cmp1
, p_invert
)
951 enum rtx_code test_code
; /* relational test (EQ, etc) */
952 rtx cmp0
; /* first operand to compare */
953 rtx cmp1
; /* second operand to compare */
954 int *p_invert
; /* whether branch needs to reverse its test */
957 enum rtx_code test_code
; /* test code to use in insn */
958 int (*const_range_p
) PARAMS ((int)); /* predicate function to check range */
959 int const_add
; /* constant to add (convert LE -> LT) */
960 int reverse_regs
; /* reverse registers in test */
961 int invert_const
; /* != 0 if invert value if cmp1 is constant */
962 int invert_reg
; /* != 0 if invert value if cmp1 is register */
963 int unsignedp
; /* != 0 for unsigned comparisons. */
966 static struct cmp_info info
[ (int)ITEST_MAX
] = {
968 { EQ
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
969 { NE
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
971 { LT
, b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
972 { GE
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
973 { LT
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
974 { GE
, b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
976 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
977 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
978 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
979 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
982 enum internal_test test
;
983 enum machine_mode mode
;
984 struct cmp_info
*p_info
;
986 test
= map_test_to_internal_test (test_code
);
987 if (test
== ITEST_MAX
)
990 p_info
= &info
[ (int)test
];
992 mode
= GET_MODE (cmp0
);
993 if (mode
== VOIDmode
)
994 mode
= GET_MODE (cmp1
);
996 /* Make sure we can handle any constants given to us. */
997 if (GET_CODE (cmp1
) == CONST_INT
)
999 HOST_WIDE_INT value
= INTVAL (cmp1
);
1000 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
1002 /* if the immediate overflows or does not fit in the immediate field,
1003 spill it to a register */
1005 if ((p_info
->unsignedp
?
1006 (uvalue
+ p_info
->const_add
> uvalue
) :
1007 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
1009 cmp1
= force_reg (mode
, cmp1
);
1011 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
1013 cmp1
= force_reg (mode
, cmp1
);
1016 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
1018 cmp1
= force_reg (mode
, cmp1
);
1021 /* See if we need to invert the result. */
1022 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
1023 ? p_info
->invert_const
1024 : p_info
->invert_reg
);
1026 /* Comparison to constants, may involve adding 1 to change a LT into LE.
1027 Comparison between two registers, may involve switching operands. */
1028 if (GET_CODE (cmp1
) == CONST_INT
)
1030 if (p_info
->const_add
!= 0)
1031 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
1034 else if (p_info
->reverse_regs
)
1041 return gen_rtx (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
1045 /* Generate the code to compare two float values. The return value is
1046 the comparison expression. */
1049 gen_float_relational (test_code
, cmp0
, cmp1
)
1050 enum rtx_code test_code
; /* relational test (EQ, etc) */
1051 rtx cmp0
; /* first operand to compare */
1052 rtx cmp1
; /* second operand to compare */
1054 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
));
1056 int reverse_regs
, invert
;
1060 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
1061 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
1062 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
1063 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
1064 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
1065 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
1067 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1068 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
1078 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
1079 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
1081 return gen_rtx (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
1086 xtensa_expand_conditional_branch (operands
, test_code
)
1088 enum rtx_code test_code
;
1090 enum cmp_type type
= branch_type
;
1091 rtx cmp0
= branch_cmp
[0];
1092 rtx cmp1
= branch_cmp
[1];
1101 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1105 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
1109 if (!TARGET_HARD_FLOAT
)
1110 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1112 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
1116 /* Generate the branch. */
1118 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[0]);
1127 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1128 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
1135 gen_conditional_move (cmp
)
1138 enum rtx_code code
= GET_CODE (cmp
);
1139 rtx op0
= branch_cmp
[0];
1140 rtx op1
= branch_cmp
[1];
1142 if (branch_type
== CMP_SI
)
1144 /* Jump optimization calls get_condition() which canonicalizes
1145 comparisons like (GE x <const>) to (GT x <const-1>).
1146 Transform those comparisons back to GE, since that is the
1147 comparison supported in Xtensa. We shouldn't have to
1148 transform <LE x const> comparisons, because neither
1149 xtensa_expand_conditional_branch() nor get_condition() will
1152 if ((code
== GT
) && (op1
== constm1_rtx
))
1157 cmp
= gen_rtx (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
1159 if (boolean_operator (cmp
, VOIDmode
))
1161 /* swap the operands to make const0 second */
1162 if (op0
== const0_rtx
)
1168 /* if not comparing against zero, emit a comparison (subtract) */
1169 if (op1
!= const0_rtx
)
1171 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
1172 0, 0, OPTAB_LIB_WIDEN
);
1176 else if (branch_operator (cmp
, VOIDmode
))
1178 /* swap the operands to make const0 second */
1179 if (op0
== const0_rtx
)
1186 case LT
: code
= GE
; break;
1187 case GE
: code
= LT
; break;
1192 if (op1
!= const0_rtx
)
1198 return gen_rtx (code
, VOIDmode
, op0
, op1
);
1201 if (TARGET_HARD_FLOAT
&& (branch_type
== CMP_SF
))
1202 return gen_float_relational (code
, op0
, op1
);
1209 xtensa_expand_conditional_move (operands
, isflt
)
1214 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
, rtx
, rtx
));
1216 if (!(cmp
= gen_conditional_move (operands
[1])))
1220 gen_fn
= (branch_type
== CMP_SI
1221 ? gen_movsfcc_internal0
1222 : gen_movsfcc_internal1
);
1224 gen_fn
= (branch_type
== CMP_SI
1225 ? gen_movsicc_internal0
1226 : gen_movsicc_internal1
);
1228 emit_insn (gen_fn (operands
[0], XEXP (cmp
, 0),
1229 operands
[2], operands
[3], cmp
));
1235 xtensa_expand_scc (operands
)
1238 rtx dest
= operands
[0];
1239 rtx cmp
= operands
[1];
1240 rtx one_tmp
, zero_tmp
;
1241 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
, rtx
, rtx
));
1243 if (!(cmp
= gen_conditional_move (cmp
)))
1246 one_tmp
= gen_reg_rtx (SImode
);
1247 zero_tmp
= gen_reg_rtx (SImode
);
1248 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
1249 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
1251 gen_fn
= (branch_type
== CMP_SI
1252 ? gen_movsicc_internal0
1253 : gen_movsicc_internal1
);
1254 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
1259 /* Emit insns to move operands[1] into operands[0].
1261 Return 1 if we have written out everything that needs to be done to
1262 do the move. Otherwise, return 0 and the caller will emit the move
1266 xtensa_emit_move_sequence (operands
, mode
)
1268 enum machine_mode mode
;
1270 if (CONSTANT_P (operands
[1])
1271 && GET_CODE (operands
[1]) != CONSTANT_P_RTX
1272 && (GET_CODE (operands
[1]) != CONST_INT
1273 || !xtensa_simm12b (INTVAL (operands
[1]))))
1275 xtensa_load_constant (operands
[0], operands
[1]);
1279 if (!(reload_in_progress
| reload_completed
))
1281 if (!xtensa_valid_move (mode
, operands
))
1282 operands
[1] = force_reg (mode
, operands
[1]);
1284 if (xtensa_copy_incoming_a7 (operands
, mode
))
1288 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1289 instruction won't be recognized after reload. So we remove the
1290 subreg and adjust mem accordingly. */
1291 if (reload_in_progress
)
1293 operands
[0] = fixup_subreg_mem (operands
[0]);
1294 operands
[1] = fixup_subreg_mem (operands
[1]);
1300 fixup_subreg_mem (x
)
1303 if (GET_CODE (x
) == SUBREG
1304 && GET_CODE (SUBREG_REG (x
)) == REG
1305 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1308 gen_rtx_SUBREG (GET_MODE (x
),
1309 reg_equiv_mem
[REGNO (SUBREG_REG (x
))],
1311 x
= alter_subreg (&temp
);
1317 /* Check if this move is copying an incoming argument in a7. If so,
1318 emit the move, followed by the special "set_frame_ptr"
1319 unspec_volatile insn, at the very beginning of the function. This
1320 is necessary because the register allocator will ignore conflicts
1321 with a7 and may assign some other pseudo to a7. If that pseudo was
1322 assigned prior to this move, it would clobber the incoming argument
1323 in a7. By copying the argument out of a7 as the very first thing,
1324 and then immediately following that with an unspec_volatile to keep
1325 the scheduler away, we should avoid any problems. */
1328 xtensa_copy_incoming_a7 (operands
, mode
)
1330 enum machine_mode mode
;
1332 if (a7_overlap_mentioned_p (operands
[1])
1333 && !cfun
->machine
->incoming_a7_copied
)
1339 mov
= gen_movdf_internal (operands
[0], operands
[1]);
1342 mov
= gen_movsf_internal (operands
[0], operands
[1]);
1345 mov
= gen_movdi_internal (operands
[0], operands
[1]);
1348 mov
= gen_movsi_internal (operands
[0], operands
[1]);
1351 mov
= gen_movhi_internal (operands
[0], operands
[1]);
1354 mov
= gen_movqi_internal (operands
[0], operands
[1]);
1360 /* Insert the instructions before any other argument copies.
1361 (The set_frame_ptr insn comes _after_ the move, so push it
1363 push_topmost_sequence ();
1364 emit_insn_after (gen_set_frame_ptr (), get_insns ());
1365 emit_insn_after (mov
, get_insns ());
1366 pop_topmost_sequence ();
1368 /* Ideally the incoming argument in a7 would only be copied
1369 once, since propagating a7 into the body of a function
1370 will almost certainly lead to errors. However, there is
1371 at least one harmless case (in GCSE) where the original
1372 copy from a7 is changed to copy into a new pseudo. Thus,
1373 we use a flag to only do this special treatment for the
1374 first copy of a7. */
1376 cfun
->machine
->incoming_a7_copied
= true;
1385 /* Try to expand a block move operation to an RTL block move instruction.
1386 If not optimizing or if the block size is not a constant or if the
1387 block is small, the expansion fails and GCC falls back to calling
1390 operands[0] is the destination
1391 operands[1] is the source
1392 operands[2] is the length
1393 operands[3] is the alignment */
1396 xtensa_expand_block_move (operands
)
1399 rtx dest
= operands
[0];
1400 rtx src
= operands
[1];
1401 int bytes
= INTVAL (operands
[2]);
1402 int align
= XINT (operands
[3], 0);
1403 int num_pieces
, move_ratio
;
1405 /* If this is not a fixed size move, just call memcpy */
1406 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1409 /* Anything to move? */
1413 if (align
> MOVE_MAX
)
1416 /* decide whether to expand inline based on the optimization level */
1419 move_ratio
= LARGEST_MOVE_RATIO
;
1420 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* close enough anyway */
1421 if (num_pieces
>= move_ratio
)
1424 /* make sure the memory addresses are valid */
1425 operands
[0] = validize_mem (dest
);
1426 operands
[1] = validize_mem (src
);
1428 emit_insn (gen_movstrsi_internal (operands
[0], operands
[1],
1429 operands
[2], operands
[3]));
1434 /* Emit a sequence of instructions to implement a block move, trying
1435 to hide load delay slots as much as possible. Load N values into
1436 temporary registers, store those N values, and repeat until the
1437 complete block has been moved. N=delay_slots+1 */
1445 xtensa_emit_block_move (operands
, tmpregs
, delay_slots
)
1450 rtx dest
= operands
[0];
1451 rtx src
= operands
[1];
1452 int bytes
= INTVAL (operands
[2]);
1453 int align
= XINT (operands
[3], 0);
1454 rtx from_addr
= XEXP (src
, 0);
1455 rtx to_addr
= XEXP (dest
, 0);
1456 int from_struct
= MEM_IN_STRUCT_P (src
);
1457 int to_struct
= MEM_IN_STRUCT_P (dest
);
1459 int chunk_size
, item_size
;
1460 struct meminsnbuf
*ldinsns
, *stinsns
;
1461 const char *ldname
, *stname
;
1462 enum machine_mode mode
;
1464 if (align
> MOVE_MAX
)
1467 chunk_size
= delay_slots
+ 1;
1469 ldinsns
= (struct meminsnbuf
*)
1470 alloca (chunk_size
* sizeof (struct meminsnbuf
));
1471 stinsns
= (struct meminsnbuf
*)
1472 alloca (chunk_size
* sizeof (struct meminsnbuf
));
1474 mode
= xtensa_find_mode_for_size (item_size
);
1475 item_size
= GET_MODE_SIZE (mode
);
1476 ldname
= xtensa_ld_opcodes
[(int) mode
];
1477 stname
= xtensa_st_opcodes
[(int) mode
];
1483 for (n
= 0; n
< chunk_size
; n
++)
1493 if (bytes
< item_size
)
1495 /* find a smaller item_size which we can load & store */
1497 mode
= xtensa_find_mode_for_size (item_size
);
1498 item_size
= GET_MODE_SIZE (mode
);
1499 ldname
= xtensa_ld_opcodes
[(int) mode
];
1500 stname
= xtensa_st_opcodes
[(int) mode
];
1503 /* record the load instruction opcode and operands */
1504 addr
= plus_constant (from_addr
, offset
);
1505 mem
= gen_rtx_MEM (mode
, addr
);
1506 if (! memory_address_p (mode
, addr
))
1508 MEM_IN_STRUCT_P (mem
) = from_struct
;
1509 ldinsns
[n
].operands
[0] = tmpregs
[n
];
1510 ldinsns
[n
].operands
[1] = mem
;
1511 sprintf (ldinsns
[n
].template, "%s\t%%0, %%1", ldname
);
1513 /* record the store instruction opcode and operands */
1514 addr
= plus_constant (to_addr
, offset
);
1515 mem
= gen_rtx_MEM (mode
, addr
);
1516 if (! memory_address_p (mode
, addr
))
1518 MEM_IN_STRUCT_P (mem
) = to_struct
;
1519 stinsns
[n
].operands
[0] = tmpregs
[n
];
1520 stinsns
[n
].operands
[1] = mem
;
1521 sprintf (stinsns
[n
].template, "%s\t%%0, %%1", stname
);
1523 offset
+= item_size
;
1527 /* now output the loads followed by the stores */
1528 for (n
= 0; n
< chunk_size
; n
++)
1529 output_asm_insn (ldinsns
[n
].template, ldinsns
[n
].operands
);
1530 for (n
= 0; n
< chunk_size
; n
++)
1531 output_asm_insn (stinsns
[n
].template, stinsns
[n
].operands
);
1536 static enum machine_mode
1537 xtensa_find_mode_for_size (item_size
)
1540 enum machine_mode mode
, tmode
;
1546 /* find mode closest to but not bigger than item_size */
1547 for (tmode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
1548 tmode
!= VOIDmode
; tmode
= GET_MODE_WIDER_MODE (tmode
))
1549 if (GET_MODE_SIZE (tmode
) <= item_size
)
1551 if (mode
== VOIDmode
)
1554 item_size
= GET_MODE_SIZE (mode
);
1556 if (xtensa_ld_opcodes
[(int) mode
]
1557 && xtensa_st_opcodes
[(int) mode
])
1560 /* cannot load & store this mode; try something smaller */
1569 xtensa_expand_nonlocal_goto (operands
)
1572 rtx goto_handler
= operands
[1];
1573 rtx containing_fp
= operands
[3];
1575 /* generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1576 is too big to generate in-line */
1578 if (GET_CODE (containing_fp
) != REG
)
1579 containing_fp
= force_reg (Pmode
, containing_fp
);
1581 goto_handler
= replace_rtx (copy_rtx (goto_handler
),
1582 virtual_stack_vars_rtx
,
1585 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1587 containing_fp
, Pmode
,
1588 goto_handler
, Pmode
);
1592 static struct machine_function
*
1593 xtensa_init_machine_status ()
1595 return ggc_alloc_cleared (sizeof (struct machine_function
));
1600 xtensa_setup_frame_addresses ()
1602 /* Set flag to cause FRAME_POINTER_REQUIRED to be set. */
1603 cfun
->machine
->accesses_prev_frame
= 1;
1606 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1611 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1612 a comment showing where the end of the loop is. However, if there is a
1613 label or a branch at the end of the loop then we need to place a nop
1614 there. If the loop ends with a label we need the nop so that branches
1615 targetting that label will target the nop (and thus remain in the loop),
1616 instead of targetting the instruction after the loop (and thus exiting
1617 the loop). If the loop ends with a branch, we need the nop in case the
1618 branch is targetting a location inside the loop. When the branch
1619 executes it will cause the loop count to be decremented even if it is
1620 taken (because it is the last instruction in the loop), so we need to
1621 nop after the branch to prevent the loop count from being decremented
1622 when the branch is taken. */
1625 xtensa_emit_loop_end (insn
, operands
)
1631 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1633 switch (GET_CODE (insn
))
1640 output_asm_insn ("nop.n", operands
);
1646 rtx body
= PATTERN (insn
);
1648 if (GET_CODE (body
) == JUMP_INSN
)
1650 output_asm_insn ("nop.n", operands
);
1653 else if ((GET_CODE (body
) != USE
)
1654 && (GET_CODE (body
) != CLOBBER
))
1661 output_asm_insn ("# loop end for %0", operands
);
1666 xtensa_emit_call (callop
, operands
)
1670 static char result
[64];
1671 rtx tgt
= operands
[callop
];
1673 if (GET_CODE (tgt
) == CONST_INT
)
1674 sprintf (result
, "call8\t0x%lx", INTVAL (tgt
));
1675 else if (register_operand (tgt
, VOIDmode
))
1676 sprintf (result
, "callx8\t%%%d", callop
);
1678 sprintf (result
, "call8\t%%%d", callop
);
1684 /* Return the stabs register number to use for 'regno'. */
1687 xtensa_dbx_register_number (regno
)
1692 if (GP_REG_P (regno
)) {
1693 regno
-= GP_REG_FIRST
;
1696 else if (BR_REG_P (regno
)) {
1697 regno
-= BR_REG_FIRST
;
1700 else if (FP_REG_P (regno
)) {
1701 regno
-= FP_REG_FIRST
;
1702 /* The current numbering convention is that TIE registers are
1703 numbered in libcc order beginning with 256. We can't guarantee
1704 that the FP registers will come first, so the following is just
1705 a guess. It seems like we should make a special case for FP
1706 registers and give them fixed numbers < 256. */
1709 else if (ACC_REG_P (regno
))
1715 /* When optimizing, we sometimes get asked about pseudo-registers
1716 that don't represent hard registers. Return 0 for these. */
1720 return first
+ regno
;
1724 /* Argument support functions. */
1726 /* Initialize CUMULATIVE_ARGS for a function. */
1729 init_cumulative_args (cum
, fntype
, libname
)
1730 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
1731 tree fntype ATTRIBUTE_UNUSED
; /* tree ptr for function decl */
1732 rtx libname ATTRIBUTE_UNUSED
; /* SYMBOL_REF of library name or 0 */
1737 /* Advance the argument to the next argument position. */
1740 function_arg_advance (cum
, mode
, type
)
1741 CUMULATIVE_ARGS
*cum
; /* current arg information */
1742 enum machine_mode mode
; /* current arg mode */
1743 tree type
; /* type of the argument or 0 if lib support */
1748 arg_words
= &cum
->arg_words
;
1749 max
= MAX_ARGS_IN_REGISTERS
;
1751 words
= (((mode
!= BLKmode
)
1752 ? (int) GET_MODE_SIZE (mode
)
1753 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1755 if ((*arg_words
+ words
> max
) && (*arg_words
< max
))
1758 *arg_words
+= words
;
1762 /* Return an RTL expression containing the register for the given mode,
1763 or 0 if the argument is to be passed on the stack. */
1766 function_arg (cum
, mode
, type
, incoming_p
)
1767 CUMULATIVE_ARGS
*cum
; /* current arg information */
1768 enum machine_mode mode
; /* current arg mode */
1769 tree type
; /* type of the argument or 0 if lib support */
1770 int incoming_p
; /* computing the incoming registers? */
1772 int regbase
, words
, max
;
1775 enum machine_mode result_mode
;
1777 arg_words
= &cum
->arg_words
;
1778 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
1779 max
= MAX_ARGS_IN_REGISTERS
;
1781 words
= (((mode
!= BLKmode
)
1782 ? (int) GET_MODE_SIZE (mode
)
1783 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1785 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
1786 *arg_words
+= (*arg_words
& 1);
1788 if (*arg_words
+ words
> max
)
1791 regno
= regbase
+ *arg_words
;
1792 result_mode
= (mode
== BLKmode
? TYPE_MODE (type
) : mode
);
1794 /* We need to make sure that references to a7 are represented with
1795 rtx that is not equal to hard_frame_pointer_rtx. For BLKmode and
1796 modes bigger than 2 words (because we only have patterns for
1797 modes of 2 words or smaller), we can't control the expansion
1798 unless we explicitly list the individual registers in a PARALLEL. */
1800 if ((mode
== BLKmode
|| words
> 2)
1802 && regno
+ words
> A7_REG
)
1807 result
= gen_rtx_PARALLEL (result_mode
, rtvec_alloc (words
));
1808 for (n
= 0; n
< words
; n
++)
1810 XVECEXP (result
, 0, n
) =
1811 gen_rtx_EXPR_LIST (VOIDmode
,
1812 gen_raw_REG (SImode
, regno
+ n
),
1813 GEN_INT (n
* UNITS_PER_WORD
));
1818 return gen_raw_REG (result_mode
, regno
);
1826 enum machine_mode mode
;
1828 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
1829 error ("boolean registers required for the floating-point option");
1831 /* set up the tables of ld/st opcode names for block moves */
1832 xtensa_ld_opcodes
[(int) SImode
] = "l32i";
1833 xtensa_ld_opcodes
[(int) HImode
] = "l16ui";
1834 xtensa_ld_opcodes
[(int) QImode
] = "l8ui";
1835 xtensa_st_opcodes
[(int) SImode
] = "s32i";
1836 xtensa_st_opcodes
[(int) HImode
] = "s16i";
1837 xtensa_st_opcodes
[(int) QImode
] = "s8i";
1839 xtensa_char_to_class
['q'] = SP_REG
;
1840 xtensa_char_to_class
['a'] = GR_REGS
;
1841 xtensa_char_to_class
['b'] = ((TARGET_BOOLEANS
) ? BR_REGS
: NO_REGS
);
1842 xtensa_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
1843 xtensa_char_to_class
['A'] = ((TARGET_MAC16
) ? ACC_REG
: NO_REGS
);
1844 xtensa_char_to_class
['B'] = ((TARGET_SEXT
) ? GR_REGS
: NO_REGS
);
1845 xtensa_char_to_class
['C'] = ((TARGET_MUL16
) ? GR_REGS
: NO_REGS
);
1846 xtensa_char_to_class
['D'] = ((TARGET_DENSITY
) ? GR_REGS
: NO_REGS
);
1847 xtensa_char_to_class
['d'] = ((TARGET_DENSITY
) ? AR_REGS
: NO_REGS
);
1849 /* Set up array giving whether a given register can hold a given mode. */
1850 for (mode
= VOIDmode
;
1851 mode
!= MAX_MACHINE_MODE
;
1852 mode
= (enum machine_mode
) ((int) mode
+ 1))
1854 int size
= GET_MODE_SIZE (mode
);
1855 enum mode_class
class = GET_MODE_CLASS (mode
);
1857 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1861 if (ACC_REG_P (regno
))
1862 temp
= (TARGET_MAC16
&&
1863 (class == MODE_INT
) && (size
<= UNITS_PER_WORD
));
1864 else if (GP_REG_P (regno
))
1865 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
1866 else if (FP_REG_P (regno
))
1867 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
1868 else if (BR_REG_P (regno
))
1869 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
1873 xtensa_hard_regno_mode_ok
[(int) mode
][regno
] = temp
;
1877 init_machine_status
= xtensa_init_machine_status
;
1879 /* Check PIC settings. There's no need for -fPIC on Xtensa and
1880 some targets need to always use PIC. */
1881 if (flag_pic
> 1 || (XTENSA_ALWAYS_PIC
))
1886 /* A C compound statement to output to stdio stream STREAM the
1887 assembler syntax for an instruction operand X. X is an RTL
1890 CODE is a value that can be used to specify one of several ways
1891 of printing the operand. It is used when identical operands
1892 must be printed differently depending on the context. CODE
1893 comes from the '%' specification that was used to request
1894 printing of the operand. If the specification was just '%DIGIT'
1895 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
1896 is the ASCII code for LTR.
1898 If X is a register, this macro should print the register's name.
1899 The names can be found in an array 'reg_names' whose type is
1900 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
1902 When the machine description has a specification '%PUNCT' (a '%'
1903 followed by a punctuation character), this macro is called with
1904 a null pointer for X and the punctuation character for CODE.
1906 'a', 'c', 'l', and 'n' are reserved.
1908 The Xtensa specific codes are:
1910 'd' CONST_INT, print as signed decimal
1911 'x' CONST_INT, print as signed hexadecimal
1912 'K' CONST_INT, print number of bits in mask for EXTUI
1913 'R' CONST_INT, print (X & 0x1f)
1914 'L' CONST_INT, print ((32 - X) & 0x1f)
1915 'D' REG, print second register of double-word register operand
1916 'N' MEM, print address of next word following a memory operand
1917 'v' MEM, if memory reference is volatile, output a MEMW before it
1925 /* print a hexadecimal value in a nice way */
1926 if ((val
> -0xa) && (val
< 0xa))
1927 fprintf (file
, "%d", val
);
1929 fprintf (file
, "-0x%x", -val
);
1931 fprintf (file
, "0x%x", val
);
1936 print_operand (file
, op
, letter
)
1937 FILE *file
; /* file to write to */
1938 rtx op
; /* operand to print */
1939 int letter
; /* %<letter> or 0 */
1944 error ("PRINT_OPERAND null pointer");
1946 code
= GET_CODE (op
);
1952 int regnum
= xt_true_regnum (op
);
1955 fprintf (file
, "%s", reg_names
[regnum
]);
1960 /* For a volatile memory reference, emit a MEMW before the
1964 if (MEM_VOLATILE_P (op
) && TARGET_SERIALIZE_VOLATILE
)
1965 fprintf (file
, "memw\n\t");
1968 else if (letter
== 'N')
1970 enum machine_mode mode
;
1971 switch (GET_MODE (op
))
1973 case DFmode
: mode
= SFmode
; break;
1974 case DImode
: mode
= SImode
; break;
1977 op
= adjust_address (op
, mode
, 4);
1980 output_address (XEXP (op
, 0));
1989 unsigned val
= INTVAL (op
);
1995 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
1996 fatal_insn ("invalid mask", op
);
1998 fprintf (file
, "%d", num_bits
);
2003 fprintf (file
, "%ld", (32 - INTVAL (op
)) & 0x1f);
2007 fprintf (file
, "%ld", INTVAL (op
) & 0x1f);
2011 printx (file
, INTVAL (op
));
2016 fprintf (file
, "%ld", INTVAL (op
));
2023 output_addr_const (file
, op
);
2028 /* A C compound statement to output to stdio stream STREAM the
2029 assembler syntax for an instruction operand that is a memory
2030 reference whose address is ADDR. ADDR is an RTL expression. */
2033 print_operand_address (file
, addr
)
2038 error ("PRINT_OPERAND_ADDRESS, null pointer");
2040 switch (GET_CODE (addr
))
2043 fatal_insn ("invalid address", addr
);
2047 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2053 rtx offset
= (rtx
)0;
2054 rtx arg0
= XEXP (addr
, 0);
2055 rtx arg1
= XEXP (addr
, 1);
2057 if (GET_CODE (arg0
) == REG
)
2062 else if (GET_CODE (arg1
) == REG
)
2068 fatal_insn ("no register in address", addr
);
2070 if (CONSTANT_P (offset
))
2072 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2073 output_addr_const (file
, offset
);
2076 fatal_insn ("address offset not a constant", addr
);
2084 output_addr_const (file
, addr
);
2090 /* Emit either a label, .comm, or .lcomm directive. */
2093 xtensa_declare_object (file
, name
, init_string
, final_string
, size
)
2100 fputs (init_string
, file
); /* "", "\t.comm\t", or "\t.lcomm\t" */
2101 assemble_name (file
, name
);
2102 fprintf (file
, final_string
, size
); /* ":\n", ",%u\n", ",%u\n" */
2107 xtensa_output_literal (file
, x
, mode
, labelno
)
2110 enum machine_mode mode
;
2117 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2119 switch (GET_MODE_CLASS (mode
))
2122 if (GET_CODE (x
) != CONST_DOUBLE
)
2125 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2129 REAL_VALUE_TO_TARGET_SINGLE (r
, value_long
[0]);
2130 fprintf (file
, "0x%08lx\n", value_long
[0]);
2134 REAL_VALUE_TO_TARGET_DOUBLE (r
, value_long
);
2135 fprintf (file
, "0x%08lx, 0x%08lx\n",
2136 value_long
[0], value_long
[1]);
2146 case MODE_PARTIAL_INT
:
2147 size
= GET_MODE_SIZE (mode
);
2150 output_addr_const (file
, x
);
2155 output_addr_const (file
, operand_subword (x
, 0, 0, DImode
));
2157 output_addr_const (file
, operand_subword (x
, 1, 0, DImode
));
2170 /* Return the bytes needed to compute the frame pointer from the current
2173 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2174 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2177 compute_frame_size (size
)
2178 int size
; /* # of var. bytes allocated */
2180 /* add space for the incoming static chain value */
2181 if (current_function_needs_context
)
2182 size
+= (1 * UNITS_PER_WORD
);
2184 xtensa_current_frame_size
=
2185 XTENSA_STACK_ALIGN (size
2186 + current_function_outgoing_args_size
2187 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2188 return xtensa_current_frame_size
;
2193 xtensa_frame_pointer_required ()
2195 /* The code to expand builtin_frame_addr and builtin_return_addr
2196 currently uses the hard_frame_pointer instead of frame_pointer.
2197 This seems wrong but maybe it's necessary for other architectures.
2198 This function is derived from the i386 code. */
2200 if (cfun
->machine
->accesses_prev_frame
)
2208 xtensa_reorg (first
)
2211 rtx insn
, set_frame_ptr_insn
= 0;
2213 unsigned long tsize
= compute_frame_size (get_frame_size ());
2214 if (tsize
< (1 << (12+3)))
2215 frame_size_const
= 0;
2218 frame_size_const
= force_const_mem (SImode
, GEN_INT (tsize
- 16));;
2220 /* make sure the constant is used so it doesn't get eliminated
2221 from the constant pool */
2222 emit_insn_before (gen_rtx_USE (SImode
, frame_size_const
), first
);
2225 if (!frame_pointer_needed
)
2228 /* Search all instructions, looking for the insn that sets up the
2229 frame pointer. This search will fail if the function does not
2230 have an incoming argument in $a7, but in that case, we can just
2231 set up the frame pointer at the very beginning of the
2234 for (insn
= first
; insn
; insn
= NEXT_INSN (insn
))
2241 pat
= PATTERN (insn
);
2242 if (GET_CODE (pat
) == UNSPEC_VOLATILE
2243 && (XINT (pat
, 1) == UNSPECV_SET_FP
))
2245 set_frame_ptr_insn
= insn
;
2250 if (set_frame_ptr_insn
)
2252 /* for all instructions prior to set_frame_ptr_insn, replace
2253 hard_frame_pointer references with stack_pointer */
2254 for (insn
= first
; insn
!= set_frame_ptr_insn
; insn
= NEXT_INSN (insn
))
2257 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2258 hard_frame_pointer_rtx
,
2264 /* emit the frame pointer move immediately after the NOTE that starts
2266 emit_insn_after (gen_movsi (hard_frame_pointer_rtx
,
2267 stack_pointer_rtx
), first
);
2272 /* Set up the stack and frame (if desired) for the function. */
2275 xtensa_function_prologue (file
, size
)
2277 HOST_WIDE_INT size ATTRIBUTE_UNUSED
;
2279 unsigned long tsize
= compute_frame_size (get_frame_size ());
2281 if (frame_pointer_needed
)
2282 fprintf (file
, "\t.frame\ta7, %ld\n", tsize
);
2284 fprintf (file
, "\t.frame\tsp, %ld\n", tsize
);
2287 if (tsize
< (1 << (12+3)))
2289 fprintf (file
, "\tentry\tsp, %ld\n", tsize
);
2293 fprintf (file
, "\tentry\tsp, 16\n");
2295 /* use a8 as a temporary since a0-a7 may be live */
2296 fprintf (file
, "\tl32r\ta8, ");
2297 print_operand (file
, frame_size_const
, 0);
2298 fprintf (file
, "\n\tsub\ta8, sp, a8\n");
2299 fprintf (file
, "\tmovsp\tsp, a8\n");
2304 /* Do any necessary cleanup after a function to restore
2305 stack, frame, and regs. */
2308 xtensa_function_epilogue (file
, size
)
2310 HOST_WIDE_INT size ATTRIBUTE_UNUSED
;
2312 rtx insn
= get_last_insn ();
2313 /* If the last insn was a BARRIER, we don't have to write anything. */
2314 if (GET_CODE (insn
) == NOTE
)
2315 insn
= prev_nonnote_insn (insn
);
2316 if (insn
== 0 || GET_CODE (insn
) != BARRIER
)
2317 fprintf (file
, TARGET_DENSITY
? "\tretw.n\n" : "\tretw\n");
2319 xtensa_current_frame_size
= 0;
2324 xtensa_return_addr (count
, frame
)
2328 rtx result
, retaddr
;
2331 retaddr
= gen_rtx_REG (Pmode
, 0);
2334 rtx addr
= plus_constant (frame
, -4 * UNITS_PER_WORD
);
2335 addr
= memory_address (Pmode
, addr
);
2336 retaddr
= gen_reg_rtx (Pmode
);
2337 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
2340 /* The 2 most-significant bits of the return address on Xtensa hold
2341 the register window size. To get the real return address, these
2342 bits must be replaced with the high bits from the current PC. */
2344 result
= gen_reg_rtx (Pmode
);
2345 emit_insn (gen_fix_return_addr (result
, retaddr
));
2350 /* Create the va_list data type.
2351 This structure is set up by __builtin_saveregs. The __va_reg
2352 field points to a stack-allocated region holding the contents of the
2353 incoming argument registers. The __va_ndx field is an index initialized
2354 to the position of the first unnamed (variable) argument. This same index
2355 is also used to address the arguments passed in memory. Thus, the
2356 __va_stk field is initialized to point to the position of the first
2357 argument in memory offset to account for the arguments passed in
2358 registers. E.G., if there are 6 argument registers, and each register is
2359 4 bytes, then __va_stk is set to $sp - (6 * 4); then __va_reg[N*4]
2360 references argument word N for 0 <= N < 6, and __va_stk[N*4] references
2361 argument word N for N >= 6. */
2364 xtensa_build_va_list ()
2366 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
2368 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2369 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
2371 f_stk
= build_decl (FIELD_DECL
, get_identifier ("__va_stk"),
2373 f_reg
= build_decl (FIELD_DECL
, get_identifier ("__va_reg"),
2375 f_ndx
= build_decl (FIELD_DECL
, get_identifier ("__va_ndx"),
2378 DECL_FIELD_CONTEXT (f_stk
) = record
;
2379 DECL_FIELD_CONTEXT (f_reg
) = record
;
2380 DECL_FIELD_CONTEXT (f_ndx
) = record
;
2382 TREE_CHAIN (record
) = type_decl
;
2383 TYPE_NAME (record
) = type_decl
;
2384 TYPE_FIELDS (record
) = f_stk
;
2385 TREE_CHAIN (f_stk
) = f_reg
;
2386 TREE_CHAIN (f_reg
) = f_ndx
;
2388 layout_type (record
);
2393 /* Save the incoming argument registers on the stack. Returns the
2394 address of the saved registers. */
2397 xtensa_builtin_saveregs ()
2400 int arg_words
= current_function_arg_words
;
2401 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
2407 /* allocate the general-purpose register space */
2408 gp_regs
= assign_stack_local
2409 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
2410 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
2412 /* Now store the incoming registers. */
2413 dest
= change_address (gp_regs
, SImode
,
2414 plus_constant (XEXP (gp_regs
, 0),
2415 arg_words
* UNITS_PER_WORD
));
2417 /* Note: Don't use move_block_from_reg() here because the incoming
2418 argument in a7 cannot be represented by hard_frame_pointer_rtx.
2419 Instead, call gen_raw_REG() directly so that we get a distinct
2420 instance of (REG:SI 7). */
2421 for (i
= 0; i
< gp_left
; i
++)
2423 emit_move_insn (operand_subword (dest
, i
, 1, BLKmode
),
2424 gen_raw_REG (SImode
, GP_ARG_FIRST
+ arg_words
+ i
));
2427 return XEXP (gp_regs
, 0);
2431 /* Implement `va_start' for varargs and stdarg. We look at the
2432 current function to fill in an initial va_list. */
2435 xtensa_va_start (valist
, nextarg
)
2437 rtx nextarg ATTRIBUTE_UNUSED
;
2445 arg_words
= current_function_args_info
.arg_words
;
2447 f_stk
= TYPE_FIELDS (va_list_type_node
);
2448 f_reg
= TREE_CHAIN (f_stk
);
2449 f_ndx
= TREE_CHAIN (f_reg
);
2451 stk
= build (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
);
2452 reg
= build (COMPONENT_REF
, TREE_TYPE (f_reg
), valist
, f_reg
);
2453 ndx
= build (COMPONENT_REF
, TREE_TYPE (f_ndx
), valist
, f_ndx
);
2455 /* Call __builtin_saveregs; save the result in __va_reg */
2456 current_function_arg_words
= arg_words
;
2457 u
= make_tree (ptr_type_node
, expand_builtin_saveregs ());
2458 t
= build (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
2459 TREE_SIDE_EFFECTS (t
) = 1;
2460 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2462 /* Set the __va_stk member to $arg_ptr - (size of __va_reg area) */
2463 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
2464 u
= fold (build (PLUS_EXPR
, ptr_type_node
, u
,
2465 build_int_2 (-MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1)));
2466 t
= build (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
2467 TREE_SIDE_EFFECTS (t
) = 1;
2468 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2470 /* Set the __va_ndx member. */
2471 u
= build_int_2 (arg_words
* UNITS_PER_WORD
, 0);
2472 t
= build (MODIFY_EXPR
, integer_type_node
, ndx
, u
);
2473 TREE_SIDE_EFFECTS (t
) = 1;
2474 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2478 /* Implement `va_arg'. */
2481 xtensa_va_arg (valist
, type
)
2487 tree tmp
, addr_tree
, type_size
;
2488 rtx array
, orig_ndx
, r
, addr
, size
, va_size
;
2489 rtx lab_false
, lab_over
, lab_false2
;
2491 f_stk
= TYPE_FIELDS (va_list_type_node
);
2492 f_reg
= TREE_CHAIN (f_stk
);
2493 f_ndx
= TREE_CHAIN (f_reg
);
2495 stk
= build (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
);
2496 reg
= build (COMPONENT_REF
, TREE_TYPE (f_reg
), valist
, f_reg
);
2497 ndx
= build (COMPONENT_REF
, TREE_TYPE (f_ndx
), valist
, f_ndx
);
2499 type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
));
2501 va_size
= gen_reg_rtx (SImode
);
2502 tmp
= fold (build (MULT_EXPR
, sizetype
,
2503 fold (build (TRUNC_DIV_EXPR
, sizetype
,
2504 fold (build (PLUS_EXPR
, sizetype
,
2506 size_int (UNITS_PER_WORD
- 1))),
2507 size_int (UNITS_PER_WORD
))),
2508 size_int (UNITS_PER_WORD
)));
2509 r
= expand_expr (tmp
, va_size
, SImode
, EXPAND_NORMAL
);
2511 emit_move_insn (va_size
, r
);
2514 /* First align __va_ndx to a double word boundary if necessary for this arg:
2516 if (__alignof__ (TYPE) > 4)
2517 (AP).__va_ndx = (((AP).__va_ndx + 7) & -8)
2520 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
2522 tmp
= build (PLUS_EXPR
, integer_type_node
, ndx
,
2523 build_int_2 ((2 * UNITS_PER_WORD
) - 1, 0));
2524 tmp
= build (BIT_AND_EXPR
, integer_type_node
, tmp
,
2525 build_int_2 (-2 * UNITS_PER_WORD
, -1));
2526 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2527 TREE_SIDE_EFFECTS (tmp
) = 1;
2528 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2532 /* Increment __va_ndx to point past the argument:
2534 orig_ndx = (AP).__va_ndx;
2535 (AP).__va_ndx += __va_size (TYPE);
2538 orig_ndx
= gen_reg_rtx (SImode
);
2539 r
= expand_expr (ndx
, orig_ndx
, SImode
, EXPAND_NORMAL
);
2541 emit_move_insn (orig_ndx
, r
);
2543 tmp
= build (PLUS_EXPR
, integer_type_node
, ndx
,
2544 make_tree (intSI_type_node
, va_size
));
2545 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2546 TREE_SIDE_EFFECTS (tmp
) = 1;
2547 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2550 /* Check if the argument is in registers:
2552 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2553 && !MUST_PASS_IN_STACK (type))
2554 __array = (AP).__va_reg;
2557 array
= gen_reg_rtx (Pmode
);
2559 lab_over
= NULL_RTX
;
2560 if (!MUST_PASS_IN_STACK (VOIDmode
, type
))
2562 lab_false
= gen_label_rtx ();
2563 lab_over
= gen_label_rtx ();
2565 emit_cmp_and_jump_insns (expand_expr (ndx
, NULL_RTX
, SImode
,
2567 GEN_INT (MAX_ARGS_IN_REGISTERS
2569 GT
, const1_rtx
, SImode
, 0, lab_false
);
2571 r
= expand_expr (reg
, array
, Pmode
, EXPAND_NORMAL
);
2573 emit_move_insn (array
, r
);
2575 emit_jump_insn (gen_jump (lab_over
));
2577 emit_label (lab_false
);
2580 /* ...otherwise, the argument is on the stack (never split between
2581 registers and the stack -- change __va_ndx if necessary):
2585 if (orig_ndx < __MAX_ARGS_IN_REGISTERS * 4)
2586 (AP).__va_ndx = __MAX_ARGS_IN_REGISTERS * 4 + __va_size (TYPE);
2587 __array = (AP).__va_stk;
2591 lab_false2
= gen_label_rtx ();
2592 emit_cmp_and_jump_insns (orig_ndx
,
2593 GEN_INT (MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
),
2594 GE
, const1_rtx
, SImode
, 0, lab_false2
);
2596 tmp
= build (PLUS_EXPR
, sizetype
, make_tree (intSI_type_node
, va_size
),
2597 build_int_2 (MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, 0));
2598 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2599 TREE_SIDE_EFFECTS (tmp
) = 1;
2600 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2602 emit_label (lab_false2
);
2604 r
= expand_expr (stk
, array
, Pmode
, EXPAND_NORMAL
);
2606 emit_move_insn (array
, r
);
2608 if (lab_over
!= NULL_RTX
)
2609 emit_label (lab_over
);
2612 /* Given the base array pointer (__array) and index to the subsequent
2613 argument (__va_ndx), find the address:
2615 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2619 The results are endian-dependent because values smaller than one word
2620 are aligned differently.
2623 size
= gen_reg_rtx (SImode
);
2624 emit_move_insn (size
, va_size
);
2626 if (BYTES_BIG_ENDIAN
)
2628 rtx lab_use_va_size
= gen_label_rtx ();
2630 emit_cmp_and_jump_insns (expand_expr (type_size
, NULL_RTX
, SImode
,
2632 GEN_INT (PARM_BOUNDARY
/ BITS_PER_UNIT
),
2633 GE
, const1_rtx
, SImode
, 0, lab_use_va_size
);
2635 r
= expand_expr (type_size
, size
, SImode
, EXPAND_NORMAL
);
2637 emit_move_insn (size
, r
);
2639 emit_label (lab_use_va_size
);
2642 addr_tree
= build (PLUS_EXPR
, ptr_type_node
,
2643 make_tree (ptr_type_node
, array
),
2645 addr_tree
= build (MINUS_EXPR
, ptr_type_node
, addr_tree
,
2646 make_tree (intSI_type_node
, size
));
2647 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
2648 addr
= copy_to_reg (addr
);
2654 xtensa_preferred_reload_class (x
, class, isoutput
)
2656 enum reg_class
class;
2659 if (!isoutput
&& CONSTANT_P (x
) && GET_CODE (x
) == CONST_DOUBLE
)
2662 /* Don't use the stack pointer or hard frame pointer for reloads!
2663 The hard frame pointer would normally be OK except that it may
2664 briefly hold an incoming argument in the prologue, and reload
2665 won't know that it is live because the hard frame pointer is
2666 treated specially. */
2668 if (class == AR_REGS
|| class == GR_REGS
)
2676 xtensa_secondary_reload_class (class, mode
, x
, isoutput
)
2677 enum reg_class
class;
2678 enum machine_mode mode ATTRIBUTE_UNUSED
;
2684 if (GET_CODE (x
) == SIGN_EXTEND
)
2686 regno
= xt_true_regnum (x
);
2690 if (class == FP_REGS
&& constantpool_mem_p (x
))
2694 if (ACC_REG_P (regno
))
2695 return ((class == GR_REGS
|| class == RL_REGS
) ? NO_REGS
: RL_REGS
);
2696 if (class == ACC_REG
)
2697 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
2704 order_regs_for_local_alloc ()
2706 if (!leaf_function_p ())
2708 memcpy (reg_alloc_order
, reg_nonleaf_alloc_order
,
2709 FIRST_PSEUDO_REGISTER
* sizeof (int));
2713 int i
, num_arg_regs
;
2716 /* use the AR registers in increasing order (skipping a0 and a1)
2717 but save the incoming argument registers for a last resort */
2718 num_arg_regs
= current_function_args_info
.arg_words
;
2719 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
2720 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
2721 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
2722 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
2723 for (i
= 0; i
< num_arg_regs
; i
++)
2724 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
2726 /* list the FP registers in order for now */
2727 for (i
= 0; i
< 16; i
++)
2728 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
2730 /* GCC requires that we list *all* the registers.... */
2731 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
2732 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
2733 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
2734 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
2736 /* list the coprocessor registers in order */
2737 for (i
= 0; i
< BR_REG_NUM
; i
++)
2738 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
2740 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
2745 /* A customized version of reg_overlap_mentioned_p that only looks for
2746 references to a7 (as opposed to hard_frame_pointer_rtx). */
2749 a7_overlap_mentioned_p (x
)
2753 unsigned int x_regno
;
2756 if (GET_CODE (x
) == REG
)
2758 x_regno
= REGNO (x
);
2759 return (x
!= hard_frame_pointer_rtx
2760 && x_regno
< A7_REG
+ 1
2761 && x_regno
+ HARD_REGNO_NREGS (A7_REG
, GET_MODE (x
)) > A7_REG
);
2764 if (GET_CODE (x
) == SUBREG
2765 && GET_CODE (SUBREG_REG (x
)) == REG
2766 && REGNO (SUBREG_REG (x
)) < FIRST_PSEUDO_REGISTER
)
2768 x_regno
= subreg_regno (x
);
2769 return (SUBREG_REG (x
) != hard_frame_pointer_rtx
2770 && x_regno
< A7_REG
+ 1
2771 && x_regno
+ HARD_REGNO_NREGS (A7_REG
, GET_MODE (x
)) > A7_REG
);
2774 /* X does not match, so try its subexpressions. */
2775 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
2776 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2780 if (a7_overlap_mentioned_p (XEXP (x
, i
)))
2783 else if (fmt
[i
] == 'E')
2785 for (j
= XVECLEN (x
, i
) - 1; j
>=0; j
--)
2786 if (a7_overlap_mentioned_p (XVECEXP (x
, i
, j
)))
2795 /* Some Xtensa targets support multiple bss sections. If the section
2796 name ends with ".bss", add SECTION_BSS to the flags. */
2799 xtensa_multibss_section_type_flags (decl
, name
, reloc
)
2804 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
2807 suffix
= strrchr (name
, '.');
2808 if (suffix
&& strcmp (suffix
, ".bss") == 0)
2810 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
2811 && DECL_INITIAL (decl
) == NULL_TREE
))
2812 flags
|= SECTION_BSS
; /* @nobits */
2814 warning ("only uninitialized variables can be placed in a "
2822 /* The literal pool stays with the function. */
2825 xtensa_select_rtx_section (mode
, x
, align
)
2826 enum machine_mode mode ATTRIBUTE_UNUSED
;
2827 rtx x ATTRIBUTE_UNUSED
;
2828 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
;
2830 function_section (current_function_decl
);
2833 /* If we are referencing a function that is static, make the SYMBOL_REF
2834 special so that we can generate direct calls to it even with -fpic. */
2837 xtensa_encode_section_info (decl
, first
)
2839 int first ATTRIBUTE_UNUSED
;
2841 if (TREE_CODE (decl
) == FUNCTION_DECL
&& ! TREE_PUBLIC (decl
))
2842 SYMBOL_REF_FLAG (XEXP (DECL_RTL (decl
), 0)) = 1;
2845 /* Compute a (partial) cost for rtx X. Return true if the complete
2846 cost has been computed, and false if subexpressions should be
2847 scanned. In either case, *TOTAL contains the cost result. */
2850 xtensa_rtx_costs (x
, code
, outer_code
, total
)
2852 int code
, outer_code
;
2861 if (xtensa_simm12b (INTVAL (x
)))
2868 if (xtensa_simm8 (INTVAL (x
))
2869 || xtensa_simm8x256 (INTVAL (x
)))
2876 if (xtensa_mask_immediate (INTVAL (x
)))
2883 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
2894 /* no way to tell if X is the 2nd operand so be conservative */
2897 if (xtensa_simm12b (INTVAL (x
)))
2916 (GET_MODE_SIZE (GET_MODE (x
)) > UNITS_PER_WORD
) ? 2 : 1;
2918 if (memory_address_p (GET_MODE (x
), XEXP ((x
), 0)))
2919 *total
= COSTS_N_INSNS (num_words
);
2921 *total
= COSTS_N_INSNS (2*num_words
);
2926 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
2930 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 3 : 2);
2936 if (GET_MODE (x
) == DImode
)
2937 *total
= COSTS_N_INSNS (2);
2939 *total
= COSTS_N_INSNS (1);
2945 if (GET_MODE (x
) == DImode
)
2946 *total
= COSTS_N_INSNS (50);
2948 *total
= COSTS_N_INSNS (1);
2953 enum machine_mode xmode
= GET_MODE (x
);
2954 if (xmode
== SFmode
)
2955 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
2956 else if (xmode
== DFmode
)
2957 *total
= COSTS_N_INSNS (50);
2959 *total
= COSTS_N_INSNS (4);
2966 enum machine_mode xmode
= GET_MODE (x
);
2967 if (xmode
== SFmode
)
2968 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
2969 else if (xmode
== DFmode
|| xmode
== DImode
)
2970 *total
= COSTS_N_INSNS (50);
2972 *total
= COSTS_N_INSNS (1);
2977 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 4 : 2);
2982 enum machine_mode xmode
= GET_MODE (x
);
2983 if (xmode
== SFmode
)
2984 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
2985 else if (xmode
== DFmode
|| xmode
== DImode
)
2986 *total
= COSTS_N_INSNS (50);
2987 else if (TARGET_MUL32
)
2988 *total
= COSTS_N_INSNS (4);
2989 else if (TARGET_MAC16
)
2990 *total
= COSTS_N_INSNS (16);
2991 else if (TARGET_MUL16
)
2992 *total
= COSTS_N_INSNS (12);
2994 *total
= COSTS_N_INSNS (50);
3001 enum machine_mode xmode
= GET_MODE (x
);
3002 if (xmode
== SFmode
)
3004 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3007 else if (xmode
== DFmode
)
3009 *total
= COSTS_N_INSNS (50);
3018 enum machine_mode xmode
= GET_MODE (x
);
3019 if (xmode
== DImode
)
3020 *total
= COSTS_N_INSNS (50);
3021 else if (TARGET_DIV32
)
3022 *total
= COSTS_N_INSNS (32);
3024 *total
= COSTS_N_INSNS (50);
3029 if (GET_MODE (x
) == SFmode
)
3030 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3032 *total
= COSTS_N_INSNS (50);
3039 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3044 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3049 *total
= COSTS_N_INSNS (1);
3057 #include "gt-xtensa.h"