1 /* Subroutines for insn-output.c for Tensilica's Xtensa architecture.
2 Copyright 2001,2002,2003 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 void xtensa_function_epilogue
PARAMS ((FILE *, HOST_WIDE_INT
));
203 static unsigned int xtensa_multibss_section_type_flags
204 PARAMS ((tree
, const char *, int));
205 static void xtensa_select_rtx_section
206 PARAMS ((enum machine_mode
, rtx
, unsigned HOST_WIDE_INT
));
207 static bool xtensa_rtx_costs
PARAMS ((rtx
, int, int, int *));
209 static int current_function_arg_words
;
210 static const int reg_nonleaf_alloc_order
[FIRST_PSEUDO_REGISTER
] =
214 /* This macro generates the assembly code for function exit,
215 on machines that need it. If FUNCTION_EPILOGUE is not defined
216 then individual return instructions are generated for each
217 return statement. Args are same as for FUNCTION_PROLOGUE. */
219 #undef TARGET_ASM_FUNCTION_EPILOGUE
220 #define TARGET_ASM_FUNCTION_EPILOGUE xtensa_function_epilogue
222 /* These hooks specify assembly directives for creating certain kinds
223 of integer object. */
225 #undef TARGET_ASM_ALIGNED_SI_OP
226 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
228 #undef TARGET_ASM_SELECT_RTX_SECTION
229 #define TARGET_ASM_SELECT_RTX_SECTION xtensa_select_rtx_section
231 #undef TARGET_RTX_COSTS
232 #define TARGET_RTX_COSTS xtensa_rtx_costs
233 #undef TARGET_ADDRESS_COST
234 #define TARGET_ADDRESS_COST hook_int_rtx_0
236 struct gcc_target targetm
= TARGET_INITIALIZER
;
240 * Functions to test Xtensa immediate operand validity.
274 return (v
& 255) == 0 && (v
>= -32768 && v
<= 32512);
281 return (v
== -1 || (v
>= 1 && v
<= 15));
288 return v
>= -32 && v
<= 95;
322 return v
>= -128 && v
<= 127;
329 return (v
>= 7 && v
<= 22);
336 return (v
& 3) == 0 && (v
>= 0 && v
<= 60);
343 return v
>= -2048 && v
<= 2047;
350 return v
>= 0 && v
<= 255;
357 return (v
& 1) == 0 && (v
>= 0 && v
<= 510);
364 return (v
& 3) == 0 && (v
>= 0 && v
<= 1020);
368 /* This is just like the standard true_regnum() function except that it
369 works even when reg_renumber is not initialized. */
375 if (GET_CODE (x
) == REG
)
378 && REGNO (x
) >= FIRST_PSEUDO_REGISTER
379 && reg_renumber
[REGNO (x
)] >= 0)
380 return reg_renumber
[REGNO (x
)];
383 if (GET_CODE (x
) == SUBREG
)
385 int base
= xt_true_regnum (SUBREG_REG (x
));
386 if (base
>= 0 && base
< FIRST_PSEUDO_REGISTER
)
387 return base
+ subreg_regno_offset (REGNO (SUBREG_REG (x
)),
388 GET_MODE (SUBREG_REG (x
)),
389 SUBREG_BYTE (x
), GET_MODE (x
));
396 add_operand (op
, mode
)
398 enum machine_mode mode
;
400 if (GET_CODE (op
) == CONST_INT
)
401 return (xtensa_simm8 (INTVAL (op
)) || xtensa_simm8x256 (INTVAL (op
)));
403 return register_operand (op
, mode
);
408 arith_operand (op
, mode
)
410 enum machine_mode mode
;
412 if (GET_CODE (op
) == CONST_INT
)
413 return xtensa_simm8 (INTVAL (op
));
415 return register_operand (op
, mode
);
420 nonimmed_operand (op
, mode
)
422 enum machine_mode mode
;
424 /* We cannot use the standard nonimmediate_operand() predicate because
425 it includes constant pool memory operands. */
427 if (memory_operand (op
, mode
))
428 return !constantpool_address_p (XEXP (op
, 0));
430 return register_operand (op
, mode
);
435 mem_operand (op
, mode
)
437 enum machine_mode mode
;
439 /* We cannot use the standard memory_operand() predicate because
440 it includes constant pool memory operands. */
442 if (memory_operand (op
, mode
))
443 return !constantpool_address_p (XEXP (op
, 0));
450 xtensa_valid_move (mode
, operands
)
451 enum machine_mode mode
;
454 /* Either the destination or source must be a register, and the
455 MAC16 accumulator doesn't count. */
457 if (register_operand (operands
[0], mode
))
459 int dst_regnum
= xt_true_regnum (operands
[0]);
461 /* The stack pointer can only be assigned with a MOVSP opcode. */
462 if (dst_regnum
== STACK_POINTER_REGNUM
)
463 return (mode
== SImode
464 && register_operand (operands
[1], mode
)
465 && !ACC_REG_P (xt_true_regnum (operands
[1])));
467 if (!ACC_REG_P (dst_regnum
))
470 if (register_operand (operands
[1], mode
))
472 int src_regnum
= xt_true_regnum (operands
[1]);
473 if (!ACC_REG_P (src_regnum
))
481 mask_operand (op
, mode
)
483 enum machine_mode mode
;
485 if (GET_CODE (op
) == CONST_INT
)
486 return xtensa_mask_immediate (INTVAL (op
));
488 return register_operand (op
, mode
);
493 extui_fldsz_operand (op
, mode
)
495 enum machine_mode mode ATTRIBUTE_UNUSED
;
497 return ((GET_CODE (op
) == CONST_INT
)
498 && xtensa_mask_immediate ((1 << INTVAL (op
)) - 1));
503 sext_operand (op
, mode
)
505 enum machine_mode mode
;
508 return nonimmed_operand (op
, mode
);
509 return mem_operand (op
, mode
);
514 sext_fldsz_operand (op
, mode
)
516 enum machine_mode mode ATTRIBUTE_UNUSED
;
518 return ((GET_CODE (op
) == CONST_INT
) && xtensa_tp7 (INTVAL (op
) - 1));
523 lsbitnum_operand (op
, mode
)
525 enum machine_mode mode ATTRIBUTE_UNUSED
;
527 if (GET_CODE (op
) == CONST_INT
)
529 return (BITS_BIG_ENDIAN
530 ? (INTVAL (op
) == BITS_PER_WORD
-1)
531 : (INTVAL (op
) == 0));
543 return xtensa_b4const (v
);
548 branch_operand (op
, mode
)
550 enum machine_mode mode
;
552 if (GET_CODE (op
) == CONST_INT
)
553 return b4const_or_zero (INTVAL (op
));
555 return register_operand (op
, mode
);
560 ubranch_operand (op
, mode
)
562 enum machine_mode mode
;
564 if (GET_CODE (op
) == CONST_INT
)
565 return xtensa_b4constu (INTVAL (op
));
567 return register_operand (op
, mode
);
572 call_insn_operand (op
, mode
)
574 enum machine_mode mode ATTRIBUTE_UNUSED
;
576 if ((GET_CODE (op
) == REG
)
577 && (op
!= arg_pointer_rtx
)
578 && ((REGNO (op
) < FRAME_POINTER_REGNUM
)
579 || (REGNO (op
) > LAST_VIRTUAL_REGISTER
)))
582 if (CONSTANT_ADDRESS_P (op
))
584 /* Direct calls only allowed to static functions with PIC. */
586 || (GET_CODE (op
) == SYMBOL_REF
&& SYMBOL_REF_LOCAL_P (op
)));
594 move_operand (op
, mode
)
596 enum machine_mode mode
;
598 if (register_operand (op
, mode
)
599 || memory_operand (op
, mode
))
606 return TARGET_CONST16
&& CONSTANT_P (op
);
611 return CONSTANT_P (op
);
616 /* Accept CONSTANT_P_RTX, since it will be gone by CSE1 and
618 if (GET_CODE (op
) == CONSTANT_P_RTX
)
621 if (GET_CODE (op
) == CONST_INT
&& xtensa_simm12b (INTVAL (op
)))
634 smalloffset_mem_p (op
)
637 if (GET_CODE (op
) == MEM
)
639 rtx addr
= XEXP (op
, 0);
640 if (GET_CODE (addr
) == REG
)
641 return REG_OK_FOR_BASE_P (addr
);
642 if (GET_CODE (addr
) == PLUS
)
644 rtx offset
= XEXP (addr
, 0);
645 if (GET_CODE (offset
) != CONST_INT
)
646 offset
= XEXP (addr
, 1);
647 if (GET_CODE (offset
) != CONST_INT
)
649 return xtensa_lsi4x4 (INTVAL (offset
));
657 constantpool_address_p (addr
)
662 if (GET_CODE (addr
) == CONST
)
666 /* only handle (PLUS (SYM, OFFSET)) form */
667 addr
= XEXP (addr
, 0);
668 if (GET_CODE (addr
) != PLUS
)
671 /* make sure the address is word aligned */
672 offset
= XEXP (addr
, 1);
673 if ((GET_CODE (offset
) != CONST_INT
)
674 || ((INTVAL (offset
) & 3) != 0))
677 sym
= XEXP (addr
, 0);
680 if ((GET_CODE (sym
) == SYMBOL_REF
)
681 && CONSTANT_POOL_ADDRESS_P (sym
))
688 constantpool_mem_p (op
)
691 if (GET_CODE (op
) == MEM
)
692 return constantpool_address_p (XEXP (op
, 0));
697 /* Accept the floating point constant 1 in the appropriate mode. */
700 const_float_1_operand (op
, mode
)
702 enum machine_mode mode
;
705 static REAL_VALUE_TYPE onedf
;
706 static REAL_VALUE_TYPE onesf
;
707 static int one_initialized
;
709 if ((GET_CODE (op
) != CONST_DOUBLE
)
710 || (mode
!= GET_MODE (op
))
711 || (mode
!= DFmode
&& mode
!= SFmode
))
714 REAL_VALUE_FROM_CONST_DOUBLE (d
, op
);
716 if (! one_initialized
)
718 onedf
= REAL_VALUE_ATOF ("1.0", DFmode
);
719 onesf
= REAL_VALUE_ATOF ("1.0", SFmode
);
720 one_initialized
= TRUE
;
724 return REAL_VALUES_EQUAL (d
, onedf
);
726 return REAL_VALUES_EQUAL (d
, onesf
);
731 fpmem_offset_operand (op
, mode
)
733 enum machine_mode mode ATTRIBUTE_UNUSED
;
735 if (GET_CODE (op
) == CONST_INT
)
736 return xtensa_mem_offset (INTVAL (op
), SFmode
);
742 xtensa_extend_reg (dst
, src
)
746 rtx temp
= gen_reg_rtx (SImode
);
747 rtx shift
= GEN_INT (BITS_PER_WORD
- GET_MODE_BITSIZE (GET_MODE (src
)));
749 /* generate paradoxical subregs as needed so that the modes match */
750 src
= simplify_gen_subreg (SImode
, src
, GET_MODE (src
), 0);
751 dst
= simplify_gen_subreg (SImode
, dst
, GET_MODE (dst
), 0);
753 emit_insn (gen_ashlsi3 (temp
, src
, shift
));
754 emit_insn (gen_ashrsi3 (dst
, temp
, shift
));
759 branch_operator (x
, mode
)
761 enum machine_mode mode
;
763 if (GET_MODE (x
) != mode
)
766 switch (GET_CODE (x
))
781 ubranch_operator (x
, mode
)
783 enum machine_mode mode
;
785 if (GET_MODE (x
) != mode
)
788 switch (GET_CODE (x
))
801 boolean_operator (x
, mode
)
803 enum machine_mode mode
;
805 if (GET_MODE (x
) != mode
)
808 switch (GET_CODE (x
))
821 xtensa_mask_immediate (v
)
824 #define MAX_MASK_SIZE 16
827 for (mask_size
= 1; mask_size
<= MAX_MASK_SIZE
; mask_size
++)
841 xtensa_mem_offset (v
, mode
)
843 enum machine_mode mode
;
848 /* Handle the worst case for block moves. See xtensa_expand_block_move
849 where we emit an optimized block move operation if the block can be
850 moved in < "move_ratio" pieces. The worst case is when the block is
851 aligned but has a size of (3 mod 4) (does this happen?) so that the
852 last piece requires a byte load/store. */
853 return (xtensa_uimm8 (v
)
854 && xtensa_uimm8 (v
+ MOVE_MAX
* LARGEST_MOVE_RATIO
));
857 return xtensa_uimm8 (v
);
860 return xtensa_uimm8x2 (v
);
863 return (xtensa_uimm8x4 (v
) && xtensa_uimm8x4 (v
+ 4));
869 return xtensa_uimm8x4 (v
);
873 /* Make normal rtx_code into something we can index from an array */
875 static enum internal_test
876 map_test_to_internal_test (test_code
)
877 enum rtx_code test_code
;
879 enum internal_test test
= ITEST_MAX
;
884 case EQ
: test
= ITEST_EQ
; break;
885 case NE
: test
= ITEST_NE
; break;
886 case GT
: test
= ITEST_GT
; break;
887 case GE
: test
= ITEST_GE
; break;
888 case LT
: test
= ITEST_LT
; break;
889 case LE
: test
= ITEST_LE
; break;
890 case GTU
: test
= ITEST_GTU
; break;
891 case GEU
: test
= ITEST_GEU
; break;
892 case LTU
: test
= ITEST_LTU
; break;
893 case LEU
: test
= ITEST_LEU
; break;
900 /* Generate the code to compare two integer values. The return value is
901 the comparison expression. */
904 gen_int_relational (test_code
, cmp0
, cmp1
, p_invert
)
905 enum rtx_code test_code
; /* relational test (EQ, etc) */
906 rtx cmp0
; /* first operand to compare */
907 rtx cmp1
; /* second operand to compare */
908 int *p_invert
; /* whether branch needs to reverse its test */
911 enum rtx_code test_code
; /* test code to use in insn */
912 int (*const_range_p
) PARAMS ((int)); /* predicate function to check range */
913 int const_add
; /* constant to add (convert LE -> LT) */
914 int reverse_regs
; /* reverse registers in test */
915 int invert_const
; /* != 0 if invert value if cmp1 is constant */
916 int invert_reg
; /* != 0 if invert value if cmp1 is register */
917 int unsignedp
; /* != 0 for unsigned comparisons. */
920 static struct cmp_info info
[ (int)ITEST_MAX
] = {
922 { EQ
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* EQ */
923 { NE
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* NE */
925 { LT
, b4const_or_zero
, 1, 1, 1, 0, 0 }, /* GT */
926 { GE
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* GE */
927 { LT
, b4const_or_zero
, 0, 0, 0, 0, 0 }, /* LT */
928 { GE
, b4const_or_zero
, 1, 1, 1, 0, 0 }, /* LE */
930 { LTU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* GTU */
931 { GEU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* GEU */
932 { LTU
, xtensa_b4constu
, 0, 0, 0, 0, 1 }, /* LTU */
933 { GEU
, xtensa_b4constu
, 1, 1, 1, 0, 1 }, /* LEU */
936 enum internal_test test
;
937 enum machine_mode mode
;
938 struct cmp_info
*p_info
;
940 test
= map_test_to_internal_test (test_code
);
941 if (test
== ITEST_MAX
)
944 p_info
= &info
[ (int)test
];
946 mode
= GET_MODE (cmp0
);
947 if (mode
== VOIDmode
)
948 mode
= GET_MODE (cmp1
);
950 /* Make sure we can handle any constants given to us. */
951 if (GET_CODE (cmp1
) == CONST_INT
)
953 HOST_WIDE_INT value
= INTVAL (cmp1
);
954 unsigned HOST_WIDE_INT uvalue
= (unsigned HOST_WIDE_INT
)value
;
956 /* if the immediate overflows or does not fit in the immediate field,
957 spill it to a register */
959 if ((p_info
->unsignedp
?
960 (uvalue
+ p_info
->const_add
> uvalue
) :
961 (value
+ p_info
->const_add
> value
)) != (p_info
->const_add
> 0))
963 cmp1
= force_reg (mode
, cmp1
);
965 else if (!(p_info
->const_range_p
) (value
+ p_info
->const_add
))
967 cmp1
= force_reg (mode
, cmp1
);
970 else if ((GET_CODE (cmp1
) != REG
) && (GET_CODE (cmp1
) != SUBREG
))
972 cmp1
= force_reg (mode
, cmp1
);
975 /* See if we need to invert the result. */
976 *p_invert
= ((GET_CODE (cmp1
) == CONST_INT
)
977 ? p_info
->invert_const
978 : p_info
->invert_reg
);
980 /* Comparison to constants, may involve adding 1 to change a LT into LE.
981 Comparison between two registers, may involve switching operands. */
982 if (GET_CODE (cmp1
) == CONST_INT
)
984 if (p_info
->const_add
!= 0)
985 cmp1
= GEN_INT (INTVAL (cmp1
) + p_info
->const_add
);
988 else if (p_info
->reverse_regs
)
995 return gen_rtx (p_info
->test_code
, VOIDmode
, cmp0
, cmp1
);
999 /* Generate the code to compare two float values. The return value is
1000 the comparison expression. */
1003 gen_float_relational (test_code
, cmp0
, cmp1
)
1004 enum rtx_code test_code
; /* relational test (EQ, etc) */
1005 rtx cmp0
; /* first operand to compare */
1006 rtx cmp1
; /* second operand to compare */
1008 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
));
1010 int reverse_regs
, invert
;
1014 case EQ
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_seq_sf
; break;
1015 case NE
: reverse_regs
= 0; invert
= 1; gen_fn
= gen_seq_sf
; break;
1016 case LE
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_sle_sf
; break;
1017 case GT
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_slt_sf
; break;
1018 case LT
: reverse_regs
= 0; invert
= 0; gen_fn
= gen_slt_sf
; break;
1019 case GE
: reverse_regs
= 1; invert
= 0; gen_fn
= gen_sle_sf
; break;
1021 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1022 reverse_regs
= 0; invert
= 0; gen_fn
= 0; /* avoid compiler warnings */
1032 brtmp
= gen_rtx_REG (CCmode
, FPCC_REGNUM
);
1033 emit_insn (gen_fn (brtmp
, cmp0
, cmp1
));
1035 return gen_rtx (invert
? EQ
: NE
, VOIDmode
, brtmp
, const0_rtx
);
1040 xtensa_expand_conditional_branch (operands
, test_code
)
1042 enum rtx_code test_code
;
1044 enum cmp_type type
= branch_type
;
1045 rtx cmp0
= branch_cmp
[0];
1046 rtx cmp1
= branch_cmp
[1];
1055 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1059 cmp
= gen_int_relational (test_code
, cmp0
, cmp1
, &invert
);
1063 if (!TARGET_HARD_FLOAT
)
1064 fatal_insn ("bad test", gen_rtx (test_code
, VOIDmode
, cmp0
, cmp1
));
1066 cmp
= gen_float_relational (test_code
, cmp0
, cmp1
);
1070 /* Generate the branch. */
1072 label1
= gen_rtx_LABEL_REF (VOIDmode
, operands
[0]);
1081 emit_jump_insn (gen_rtx_SET (VOIDmode
, pc_rtx
,
1082 gen_rtx_IF_THEN_ELSE (VOIDmode
, cmp
,
1089 gen_conditional_move (cmp
)
1092 enum rtx_code code
= GET_CODE (cmp
);
1093 rtx op0
= branch_cmp
[0];
1094 rtx op1
= branch_cmp
[1];
1096 if (branch_type
== CMP_SI
)
1098 /* Jump optimization calls get_condition() which canonicalizes
1099 comparisons like (GE x <const>) to (GT x <const-1>).
1100 Transform those comparisons back to GE, since that is the
1101 comparison supported in Xtensa. We shouldn't have to
1102 transform <LE x const> comparisons, because neither
1103 xtensa_expand_conditional_branch() nor get_condition() will
1106 if ((code
== GT
) && (op1
== constm1_rtx
))
1111 cmp
= gen_rtx (code
, VOIDmode
, cc0_rtx
, const0_rtx
);
1113 if (boolean_operator (cmp
, VOIDmode
))
1115 /* swap the operands to make const0 second */
1116 if (op0
== const0_rtx
)
1122 /* if not comparing against zero, emit a comparison (subtract) */
1123 if (op1
!= const0_rtx
)
1125 op0
= expand_binop (SImode
, sub_optab
, op0
, op1
,
1126 0, 0, OPTAB_LIB_WIDEN
);
1130 else if (branch_operator (cmp
, VOIDmode
))
1132 /* swap the operands to make const0 second */
1133 if (op0
== const0_rtx
)
1140 case LT
: code
= GE
; break;
1141 case GE
: code
= LT
; break;
1146 if (op1
!= const0_rtx
)
1152 return gen_rtx (code
, VOIDmode
, op0
, op1
);
1155 if (TARGET_HARD_FLOAT
&& (branch_type
== CMP_SF
))
1156 return gen_float_relational (code
, op0
, op1
);
1163 xtensa_expand_conditional_move (operands
, isflt
)
1168 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
, rtx
, rtx
));
1170 if (!(cmp
= gen_conditional_move (operands
[1])))
1174 gen_fn
= (branch_type
== CMP_SI
1175 ? gen_movsfcc_internal0
1176 : gen_movsfcc_internal1
);
1178 gen_fn
= (branch_type
== CMP_SI
1179 ? gen_movsicc_internal0
1180 : gen_movsicc_internal1
);
1182 emit_insn (gen_fn (operands
[0], XEXP (cmp
, 0),
1183 operands
[2], operands
[3], cmp
));
1189 xtensa_expand_scc (operands
)
1192 rtx dest
= operands
[0];
1193 rtx cmp
= operands
[1];
1194 rtx one_tmp
, zero_tmp
;
1195 rtx (*gen_fn
) PARAMS ((rtx
, rtx
, rtx
, rtx
, rtx
));
1197 if (!(cmp
= gen_conditional_move (cmp
)))
1200 one_tmp
= gen_reg_rtx (SImode
);
1201 zero_tmp
= gen_reg_rtx (SImode
);
1202 emit_insn (gen_movsi (one_tmp
, const_true_rtx
));
1203 emit_insn (gen_movsi (zero_tmp
, const0_rtx
));
1205 gen_fn
= (branch_type
== CMP_SI
1206 ? gen_movsicc_internal0
1207 : gen_movsicc_internal1
);
1208 emit_insn (gen_fn (dest
, XEXP (cmp
, 0), one_tmp
, zero_tmp
, cmp
));
1213 /* Split OP[1] into OP[2,3] and likewise for OP[0] into OP[0,1]. MODE is
1214 for the output, i.e., the input operands are twice as big as MODE. */
1217 xtensa_split_operand_pair (operands
, mode
)
1219 enum machine_mode mode
;
1221 switch (GET_CODE (operands
[1]))
1224 operands
[3] = gen_rtx_REG (mode
, REGNO (operands
[1]) + 1);
1225 operands
[2] = gen_rtx_REG (mode
, REGNO (operands
[1]));
1229 operands
[3] = adjust_address (operands
[1], mode
, GET_MODE_SIZE (mode
));
1230 operands
[2] = adjust_address (operands
[1], mode
, 0);
1235 split_double (operands
[1], &operands
[2], &operands
[3]);
1242 switch (GET_CODE (operands
[0]))
1245 operands
[1] = gen_rtx_REG (mode
, REGNO (operands
[0]) + 1);
1246 operands
[0] = gen_rtx_REG (mode
, REGNO (operands
[0]));
1250 operands
[1] = adjust_address (operands
[0], mode
, GET_MODE_SIZE (mode
));
1251 operands
[0] = adjust_address (operands
[0], mode
, 0);
1260 /* 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 if (!TARGET_CONST16
)
1276 operands
[1] = force_const_mem (SImode
, operands
[1]);
1278 /* PC-relative loads are always SImode, and CONST16 is only
1279 supported in the movsi pattern, so add a SUBREG for any other
1284 if (register_operand (operands
[0], mode
))
1286 operands
[0] = simplify_gen_subreg (SImode
, operands
[0], mode
, 0);
1287 emit_move_insn (operands
[0], operands
[1]);
1292 operands
[1] = force_reg (SImode
, operands
[1]);
1293 operands
[1] = gen_lowpart_SUBREG (mode
, operands
[1]);
1298 if (!(reload_in_progress
| reload_completed
))
1300 if (!xtensa_valid_move (mode
, operands
))
1301 operands
[1] = force_reg (mode
, operands
[1]);
1303 if (xtensa_copy_incoming_a7 (operands
, mode
))
1307 /* During reload we don't want to emit (subreg:X (mem:Y)) since that
1308 instruction won't be recognized after reload, so we remove the
1309 subreg and adjust mem accordingly. */
1310 if (reload_in_progress
)
1312 operands
[0] = fixup_subreg_mem (operands
[0]);
1313 operands
[1] = fixup_subreg_mem (operands
[1]);
1320 fixup_subreg_mem (x
)
1323 if (GET_CODE (x
) == SUBREG
1324 && GET_CODE (SUBREG_REG (x
)) == REG
1325 && REGNO (SUBREG_REG (x
)) >= FIRST_PSEUDO_REGISTER
)
1328 gen_rtx_SUBREG (GET_MODE (x
),
1329 reg_equiv_mem
[REGNO (SUBREG_REG (x
))],
1331 x
= alter_subreg (&temp
);
1337 /* Check if this move is copying an incoming argument in a7. If so,
1338 emit the move, followed by the special "set_frame_ptr"
1339 unspec_volatile insn, at the very beginning of the function. This
1340 is necessary because the register allocator will ignore conflicts
1341 with a7 and may assign some other pseudo to a7. If that pseudo was
1342 assigned prior to this move, it would clobber the incoming argument
1343 in a7. By copying the argument out of a7 as the very first thing,
1344 and then immediately following that with an unspec_volatile to keep
1345 the scheduler away, we should avoid any problems. */
1348 xtensa_copy_incoming_a7 (operands
, mode
)
1350 enum machine_mode mode
;
1352 if (a7_overlap_mentioned_p (operands
[1])
1353 && !cfun
->machine
->incoming_a7_copied
)
1359 mov
= gen_movdf_internal (operands
[0], operands
[1]);
1362 mov
= gen_movsf_internal (operands
[0], operands
[1]);
1365 mov
= gen_movdi_internal (operands
[0], operands
[1]);
1368 mov
= gen_movsi_internal (operands
[0], operands
[1]);
1371 mov
= gen_movhi_internal (operands
[0], operands
[1]);
1374 mov
= gen_movqi_internal (operands
[0], operands
[1]);
1380 /* Insert the instructions before any other argument copies.
1381 (The set_frame_ptr insn comes _after_ the move, so push it
1383 push_topmost_sequence ();
1384 emit_insn_after (gen_set_frame_ptr (), get_insns ());
1385 emit_insn_after (mov
, get_insns ());
1386 pop_topmost_sequence ();
1388 /* Ideally the incoming argument in a7 would only be copied
1389 once, since propagating a7 into the body of a function
1390 will almost certainly lead to errors. However, there is
1391 at least one harmless case (in GCSE) where the original
1392 copy from a7 is changed to copy into a new pseudo. Thus,
1393 we use a flag to only do this special treatment for the
1394 first copy of a7. */
1396 cfun
->machine
->incoming_a7_copied
= true;
1405 /* Try to expand a block move operation to an RTL block move instruction.
1406 If not optimizing or if the block size is not a constant or if the
1407 block is small, the expansion fails and GCC falls back to calling
1410 operands[0] is the destination
1411 operands[1] is the source
1412 operands[2] is the length
1413 operands[3] is the alignment */
1416 xtensa_expand_block_move (operands
)
1419 rtx dest
= operands
[0];
1420 rtx src
= operands
[1];
1421 int bytes
= INTVAL (operands
[2]);
1422 int align
= XINT (operands
[3], 0);
1423 int num_pieces
, move_ratio
;
1425 /* If this is not a fixed size move, just call memcpy */
1426 if (!optimize
|| (GET_CODE (operands
[2]) != CONST_INT
))
1429 /* Anything to move? */
1433 if (align
> MOVE_MAX
)
1436 /* decide whether to expand inline based on the optimization level */
1439 move_ratio
= LARGEST_MOVE_RATIO
;
1440 num_pieces
= (bytes
/ align
) + (bytes
% align
); /* close enough anyway */
1441 if (num_pieces
>= move_ratio
)
1444 /* make sure the memory addresses are valid */
1445 operands
[0] = validize_mem (dest
);
1446 operands
[1] = validize_mem (src
);
1448 emit_insn (gen_movstrsi_internal (operands
[0], operands
[1],
1449 operands
[2], operands
[3]));
1454 /* Emit a sequence of instructions to implement a block move, trying
1455 to hide load delay slots as much as possible. Load N values into
1456 temporary registers, store those N values, and repeat until the
1457 complete block has been moved. N=delay_slots+1 */
1465 xtensa_emit_block_move (operands
, tmpregs
, delay_slots
)
1470 rtx dest
= operands
[0];
1471 rtx src
= operands
[1];
1472 int bytes
= INTVAL (operands
[2]);
1473 int align
= XINT (operands
[3], 0);
1474 rtx from_addr
= XEXP (src
, 0);
1475 rtx to_addr
= XEXP (dest
, 0);
1476 int from_struct
= MEM_IN_STRUCT_P (src
);
1477 int to_struct
= MEM_IN_STRUCT_P (dest
);
1479 int chunk_size
, item_size
;
1480 struct meminsnbuf
*ldinsns
, *stinsns
;
1481 const char *ldname
, *stname
;
1482 enum machine_mode mode
;
1484 if (align
> MOVE_MAX
)
1487 chunk_size
= delay_slots
+ 1;
1489 ldinsns
= (struct meminsnbuf
*)
1490 alloca (chunk_size
* sizeof (struct meminsnbuf
));
1491 stinsns
= (struct meminsnbuf
*)
1492 alloca (chunk_size
* sizeof (struct meminsnbuf
));
1494 mode
= xtensa_find_mode_for_size (item_size
);
1495 item_size
= GET_MODE_SIZE (mode
);
1496 ldname
= xtensa_ld_opcodes
[(int) mode
];
1497 stname
= xtensa_st_opcodes
[(int) mode
];
1503 for (n
= 0; n
< chunk_size
; n
++)
1513 if (bytes
< item_size
)
1515 /* find a smaller item_size which we can load & store */
1517 mode
= xtensa_find_mode_for_size (item_size
);
1518 item_size
= GET_MODE_SIZE (mode
);
1519 ldname
= xtensa_ld_opcodes
[(int) mode
];
1520 stname
= xtensa_st_opcodes
[(int) mode
];
1523 /* record the load instruction opcode and operands */
1524 addr
= plus_constant (from_addr
, offset
);
1525 mem
= gen_rtx_MEM (mode
, addr
);
1526 if (! memory_address_p (mode
, addr
))
1528 MEM_IN_STRUCT_P (mem
) = from_struct
;
1529 ldinsns
[n
].operands
[0] = tmpregs
[n
];
1530 ldinsns
[n
].operands
[1] = mem
;
1531 sprintf (ldinsns
[n
].template, "%s\t%%0, %%1", ldname
);
1533 /* record the store instruction opcode and operands */
1534 addr
= plus_constant (to_addr
, offset
);
1535 mem
= gen_rtx_MEM (mode
, addr
);
1536 if (! memory_address_p (mode
, addr
))
1538 MEM_IN_STRUCT_P (mem
) = to_struct
;
1539 stinsns
[n
].operands
[0] = tmpregs
[n
];
1540 stinsns
[n
].operands
[1] = mem
;
1541 sprintf (stinsns
[n
].template, "%s\t%%0, %%1", stname
);
1543 offset
+= item_size
;
1547 /* now output the loads followed by the stores */
1548 for (n
= 0; n
< chunk_size
; n
++)
1549 output_asm_insn (ldinsns
[n
].template, ldinsns
[n
].operands
);
1550 for (n
= 0; n
< chunk_size
; n
++)
1551 output_asm_insn (stinsns
[n
].template, stinsns
[n
].operands
);
1556 static enum machine_mode
1557 xtensa_find_mode_for_size (item_size
)
1560 enum machine_mode mode
, tmode
;
1566 /* find mode closest to but not bigger than item_size */
1567 for (tmode
= GET_CLASS_NARROWEST_MODE (MODE_INT
);
1568 tmode
!= VOIDmode
; tmode
= GET_MODE_WIDER_MODE (tmode
))
1569 if (GET_MODE_SIZE (tmode
) <= item_size
)
1571 if (mode
== VOIDmode
)
1574 item_size
= GET_MODE_SIZE (mode
);
1576 if (xtensa_ld_opcodes
[(int) mode
]
1577 && xtensa_st_opcodes
[(int) mode
])
1580 /* cannot load & store this mode; try something smaller */
1589 xtensa_expand_nonlocal_goto (operands
)
1592 rtx goto_handler
= operands
[1];
1593 rtx containing_fp
= operands
[3];
1595 /* generate a call to "__xtensa_nonlocal_goto" (in libgcc); the code
1596 is too big to generate in-line */
1598 if (GET_CODE (containing_fp
) != REG
)
1599 containing_fp
= force_reg (Pmode
, containing_fp
);
1601 goto_handler
= replace_rtx (copy_rtx (goto_handler
),
1602 virtual_stack_vars_rtx
,
1605 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_nonlocal_goto"),
1607 containing_fp
, Pmode
,
1608 goto_handler
, Pmode
);
1612 static struct machine_function
*
1613 xtensa_init_machine_status ()
1615 return ggc_alloc_cleared (sizeof (struct machine_function
));
1620 xtensa_setup_frame_addresses ()
1622 /* Set flag to cause FRAME_POINTER_REQUIRED to be set. */
1623 cfun
->machine
->accesses_prev_frame
= 1;
1626 (gen_rtx_SYMBOL_REF (Pmode
, "__xtensa_libgcc_window_spill"),
1631 /* Emit the assembly for the end of a zero-cost loop. Normally we just emit
1632 a comment showing where the end of the loop is. However, if there is a
1633 label or a branch at the end of the loop then we need to place a nop
1634 there. If the loop ends with a label we need the nop so that branches
1635 targetting that label will target the nop (and thus remain in the loop),
1636 instead of targetting the instruction after the loop (and thus exiting
1637 the loop). If the loop ends with a branch, we need the nop in case the
1638 branch is targetting a location inside the loop. When the branch
1639 executes it will cause the loop count to be decremented even if it is
1640 taken (because it is the last instruction in the loop), so we need to
1641 nop after the branch to prevent the loop count from being decremented
1642 when the branch is taken. */
1645 xtensa_emit_loop_end (insn
, operands
)
1651 for (insn
= PREV_INSN (insn
); insn
&& !done
; insn
= PREV_INSN (insn
))
1653 switch (GET_CODE (insn
))
1660 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1666 rtx body
= PATTERN (insn
);
1668 if (GET_CODE (body
) == JUMP_INSN
)
1670 output_asm_insn (TARGET_DENSITY
? "nop.n" : "nop", operands
);
1673 else if ((GET_CODE (body
) != USE
)
1674 && (GET_CODE (body
) != CLOBBER
))
1681 output_asm_insn ("# loop end for %0", operands
);
1686 xtensa_emit_call (callop
, operands
)
1690 static char result
[64];
1691 rtx tgt
= operands
[callop
];
1693 if (GET_CODE (tgt
) == CONST_INT
)
1694 sprintf (result
, "call8\t0x%lx", INTVAL (tgt
));
1695 else if (register_operand (tgt
, VOIDmode
))
1696 sprintf (result
, "callx8\t%%%d", callop
);
1698 sprintf (result
, "call8\t%%%d", callop
);
1704 /* Return the stabs register number to use for 'regno'. */
1707 xtensa_dbx_register_number (regno
)
1712 if (GP_REG_P (regno
))
1714 regno
-= GP_REG_FIRST
;
1717 else if (BR_REG_P (regno
))
1719 regno
-= BR_REG_FIRST
;
1722 else if (FP_REG_P (regno
))
1724 regno
-= FP_REG_FIRST
;
1725 /* The current numbering convention is that TIE registers are
1726 numbered in libcc order beginning with 256. We can't guarantee
1727 that the FP registers will come first, so the following is just
1728 a guess. It seems like we should make a special case for FP
1729 registers and give them fixed numbers < 256. */
1732 else if (ACC_REG_P (regno
))
1738 /* When optimizing, we sometimes get asked about pseudo-registers
1739 that don't represent hard registers. Return 0 for these. */
1743 return first
+ regno
;
1747 /* Argument support functions. */
1749 /* Initialize CUMULATIVE_ARGS for a function. */
1752 init_cumulative_args (cum
, fntype
, libname
)
1753 CUMULATIVE_ARGS
*cum
; /* argument info to initialize */
1754 tree fntype ATTRIBUTE_UNUSED
; /* tree ptr for function decl */
1755 rtx libname ATTRIBUTE_UNUSED
; /* SYMBOL_REF of library name or 0 */
1760 /* Advance the argument to the next argument position. */
1763 function_arg_advance (cum
, mode
, type
)
1764 CUMULATIVE_ARGS
*cum
; /* current arg information */
1765 enum machine_mode mode
; /* current arg mode */
1766 tree type
; /* type of the argument or 0 if lib support */
1771 arg_words
= &cum
->arg_words
;
1772 max
= MAX_ARGS_IN_REGISTERS
;
1774 words
= (((mode
!= BLKmode
)
1775 ? (int) GET_MODE_SIZE (mode
)
1776 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1778 if ((*arg_words
+ words
> max
) && (*arg_words
< max
))
1781 *arg_words
+= words
;
1785 /* Return an RTL expression containing the register for the given mode,
1786 or 0 if the argument is to be passed on the stack. */
1789 function_arg (cum
, mode
, type
, incoming_p
)
1790 CUMULATIVE_ARGS
*cum
; /* current arg information */
1791 enum machine_mode mode
; /* current arg mode */
1792 tree type
; /* type of the argument or 0 if lib support */
1793 int incoming_p
; /* computing the incoming registers? */
1795 int regbase
, words
, max
;
1798 enum machine_mode result_mode
;
1800 arg_words
= &cum
->arg_words
;
1801 regbase
= (incoming_p
? GP_ARG_FIRST
: GP_OUTGOING_ARG_FIRST
);
1802 max
= MAX_ARGS_IN_REGISTERS
;
1804 words
= (((mode
!= BLKmode
)
1805 ? (int) GET_MODE_SIZE (mode
)
1806 : int_size_in_bytes (type
)) + UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
1808 if (type
&& (TYPE_ALIGN (type
) > BITS_PER_WORD
))
1809 *arg_words
+= (*arg_words
& 1);
1811 if (*arg_words
+ words
> max
)
1814 regno
= regbase
+ *arg_words
;
1815 result_mode
= (mode
== BLKmode
? TYPE_MODE (type
) : mode
);
1817 /* We need to make sure that references to a7 are represented with
1818 rtx that is not equal to hard_frame_pointer_rtx. For BLKmode and
1819 modes bigger than 2 words (because we only have patterns for
1820 modes of 2 words or smaller), we can't control the expansion
1821 unless we explicitly list the individual registers in a PARALLEL. */
1823 if ((mode
== BLKmode
|| words
> 2)
1825 && regno
+ words
> A7_REG
)
1830 result
= gen_rtx_PARALLEL (result_mode
, rtvec_alloc (words
));
1831 for (n
= 0; n
< words
; n
++)
1833 XVECEXP (result
, 0, n
) =
1834 gen_rtx_EXPR_LIST (VOIDmode
,
1835 gen_raw_REG (SImode
, regno
+ n
),
1836 GEN_INT (n
* UNITS_PER_WORD
));
1841 return gen_raw_REG (result_mode
, regno
);
1849 enum machine_mode mode
;
1851 if (!TARGET_BOOLEANS
&& TARGET_HARD_FLOAT
)
1852 error ("boolean registers required for the floating-point option");
1854 /* set up the tables of ld/st opcode names for block moves */
1855 xtensa_ld_opcodes
[(int) SImode
] = "l32i";
1856 xtensa_ld_opcodes
[(int) HImode
] = "l16ui";
1857 xtensa_ld_opcodes
[(int) QImode
] = "l8ui";
1858 xtensa_st_opcodes
[(int) SImode
] = "s32i";
1859 xtensa_st_opcodes
[(int) HImode
] = "s16i";
1860 xtensa_st_opcodes
[(int) QImode
] = "s8i";
1862 xtensa_char_to_class
['q'] = SP_REG
;
1863 xtensa_char_to_class
['a'] = GR_REGS
;
1864 xtensa_char_to_class
['b'] = ((TARGET_BOOLEANS
) ? BR_REGS
: NO_REGS
);
1865 xtensa_char_to_class
['f'] = ((TARGET_HARD_FLOAT
) ? FP_REGS
: NO_REGS
);
1866 xtensa_char_to_class
['A'] = ((TARGET_MAC16
) ? ACC_REG
: NO_REGS
);
1867 xtensa_char_to_class
['B'] = ((TARGET_SEXT
) ? GR_REGS
: NO_REGS
);
1868 xtensa_char_to_class
['C'] = ((TARGET_MUL16
) ? GR_REGS
: NO_REGS
);
1869 xtensa_char_to_class
['D'] = ((TARGET_DENSITY
) ? GR_REGS
: NO_REGS
);
1870 xtensa_char_to_class
['d'] = ((TARGET_DENSITY
) ? AR_REGS
: NO_REGS
);
1871 xtensa_char_to_class
['W'] = ((TARGET_CONST16
) ? GR_REGS
: NO_REGS
);
1873 /* Set up array giving whether a given register can hold a given mode. */
1874 for (mode
= VOIDmode
;
1875 mode
!= MAX_MACHINE_MODE
;
1876 mode
= (enum machine_mode
) ((int) mode
+ 1))
1878 int size
= GET_MODE_SIZE (mode
);
1879 enum mode_class
class = GET_MODE_CLASS (mode
);
1881 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1885 if (ACC_REG_P (regno
))
1886 temp
= (TARGET_MAC16
1887 && (class == MODE_INT
) && (size
<= UNITS_PER_WORD
));
1888 else if (GP_REG_P (regno
))
1889 temp
= ((regno
& 1) == 0 || (size
<= UNITS_PER_WORD
));
1890 else if (FP_REG_P (regno
))
1891 temp
= (TARGET_HARD_FLOAT
&& (mode
== SFmode
));
1892 else if (BR_REG_P (regno
))
1893 temp
= (TARGET_BOOLEANS
&& (mode
== CCmode
));
1897 xtensa_hard_regno_mode_ok
[(int) mode
][regno
] = temp
;
1901 init_machine_status
= xtensa_init_machine_status
;
1903 /* Check PIC settings. PIC is only supported when using L32R
1904 instructions, and some targets need to always use PIC. */
1905 if (flag_pic
&& TARGET_CONST16
)
1906 error ("-f%s is not supported with CONST16 instructions",
1907 (flag_pic
> 1 ? "PIC" : "pic"));
1908 else if (XTENSA_ALWAYS_PIC
)
1911 error ("PIC is required but not supported with CONST16 instructions");
1914 /* There's no need for -fPIC (as opposed to -fpic) on Xtensa. */
1920 /* A C compound statement to output to stdio stream STREAM the
1921 assembler syntax for an instruction operand X. X is an RTL
1924 CODE is a value that can be used to specify one of several ways
1925 of printing the operand. It is used when identical operands
1926 must be printed differently depending on the context. CODE
1927 comes from the '%' specification that was used to request
1928 printing of the operand. If the specification was just '%DIGIT'
1929 then CODE is 0; if the specification was '%LTR DIGIT' then CODE
1930 is the ASCII code for LTR.
1932 If X is a register, this macro should print the register's name.
1933 The names can be found in an array 'reg_names' whose type is
1934 'char *[]'. 'reg_names' is initialized from 'REGISTER_NAMES'.
1936 When the machine description has a specification '%PUNCT' (a '%'
1937 followed by a punctuation character), this macro is called with
1938 a null pointer for X and the punctuation character for CODE.
1940 'a', 'c', 'l', and 'n' are reserved.
1942 The Xtensa specific codes are:
1944 'd' CONST_INT, print as signed decimal
1945 'x' CONST_INT, print as signed hexadecimal
1946 'K' CONST_INT, print number of bits in mask for EXTUI
1947 'R' CONST_INT, print (X & 0x1f)
1948 'L' CONST_INT, print ((32 - X) & 0x1f)
1949 'D' REG, print second register of double-word register operand
1950 'N' MEM, print address of next word following a memory operand
1951 'v' MEM, if memory reference is volatile, output a MEMW before it
1952 't' any constant, add "@h" suffix for top 16 bits
1953 'b' any constant, add "@l" suffix for bottom 16 bits
1961 /* print a hexadecimal value in a nice way */
1962 if ((val
> -0xa) && (val
< 0xa))
1963 fprintf (file
, "%d", val
);
1965 fprintf (file
, "-0x%x", -val
);
1967 fprintf (file
, "0x%x", val
);
1972 print_operand (file
, x
, letter
)
1973 FILE *file
; /* file to write to */
1974 rtx x
; /* operand to print */
1975 int letter
; /* %<letter> or 0 */
1978 error ("PRINT_OPERAND null pointer");
1983 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
1984 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
) + 1]);
1986 output_operand_lossage ("invalid %%D value");
1990 if (GET_CODE (x
) == MEM
)
1992 /* For a volatile memory reference, emit a MEMW before the
1994 if (MEM_VOLATILE_P (x
))
1995 fprintf (file
, "memw\n\t");
1998 output_operand_lossage ("invalid %%v value");
2002 if (GET_CODE (x
) == MEM
2003 && (GET_MODE (x
) == DFmode
|| GET_MODE (x
) == DImode
))
2005 x
= adjust_address (x
, GET_MODE (x
) == DFmode
? SFmode
: SImode
, 4);
2006 output_address (XEXP (x
, 0));
2009 output_operand_lossage ("invalid %%N value");
2013 if (GET_CODE (x
) == CONST_INT
)
2016 unsigned val
= INTVAL (x
);
2022 if ((val
!= 0) || (num_bits
== 0) || (num_bits
> 16))
2023 fatal_insn ("invalid mask", x
);
2025 fprintf (file
, "%d", num_bits
);
2028 output_operand_lossage ("invalid %%K value");
2032 if (GET_CODE (x
) == CONST_INT
)
2033 fprintf (file
, "%ld", (32 - INTVAL (x
)) & 0x1f);
2035 output_operand_lossage ("invalid %%L value");
2039 if (GET_CODE (x
) == CONST_INT
)
2040 fprintf (file
, "%ld", INTVAL (x
) & 0x1f);
2042 output_operand_lossage ("invalid %%R value");
2046 if (GET_CODE (x
) == CONST_INT
)
2047 printx (file
, INTVAL (x
));
2049 output_operand_lossage ("invalid %%x value");
2053 if (GET_CODE (x
) == CONST_INT
)
2054 fprintf (file
, "%ld", INTVAL (x
));
2056 output_operand_lossage ("invalid %%d value");
2061 if (GET_CODE (x
) == CONST_INT
)
2063 printx (file
, INTVAL (x
));
2064 fputs (letter
== 't' ? "@h" : "@l", file
);
2066 else if (GET_CODE (x
) == CONST_DOUBLE
)
2069 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2070 if (GET_MODE (x
) == SFmode
)
2073 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
2074 fprintf (file
, "0x%08lx@%c", l
, letter
== 't' ? 'h' : 'l');
2077 output_operand_lossage ("invalid %%t/%%b value");
2079 else if (GET_CODE (x
) == CONST
)
2081 /* X must be a symbolic constant on ELF. Write an expression
2082 suitable for 'const16' that sets the high or low 16 bits. */
2083 if (GET_CODE (XEXP (x
, 0)) != PLUS
2084 || (GET_CODE (XEXP (XEXP (x
, 0), 0)) != SYMBOL_REF
2085 && GET_CODE (XEXP (XEXP (x
, 0), 0)) != LABEL_REF
)
2086 || GET_CODE (XEXP (XEXP (x
, 0), 1)) != CONST_INT
)
2087 output_operand_lossage ("invalid %%t/%%b value");
2088 print_operand (file
, XEXP (XEXP (x
, 0), 0), 0);
2089 fputs (letter
== 't' ? "@h" : "@l", file
);
2090 /* There must be a non-alphanumeric character between 'h' or 'l'
2091 and the number. The '-' is added by print_operand() already. */
2092 if (INTVAL (XEXP (XEXP (x
, 0), 1)) >= 0)
2094 print_operand (file
, XEXP (XEXP (x
, 0), 1), 0);
2098 output_addr_const (file
, x
);
2099 fputs (letter
== 't' ? "@h" : "@l", file
);
2104 if (GET_CODE (x
) == REG
|| GET_CODE (x
) == SUBREG
)
2105 fprintf (file
, "%s", reg_names
[xt_true_regnum (x
)]);
2106 else if (GET_CODE (x
) == MEM
)
2107 output_address (XEXP (x
, 0));
2108 else if (GET_CODE (x
) == CONST_INT
)
2109 fprintf (file
, "%ld", INTVAL (x
));
2111 output_addr_const (file
, x
);
2116 /* A C compound statement to output to stdio stream STREAM the
2117 assembler syntax for an instruction operand that is a memory
2118 reference whose address is ADDR. ADDR is an RTL expression. */
2121 print_operand_address (file
, addr
)
2126 error ("PRINT_OPERAND_ADDRESS, null pointer");
2128 switch (GET_CODE (addr
))
2131 fatal_insn ("invalid address", addr
);
2135 fprintf (file
, "%s, 0", reg_names
[REGNO (addr
)]);
2141 rtx offset
= (rtx
)0;
2142 rtx arg0
= XEXP (addr
, 0);
2143 rtx arg1
= XEXP (addr
, 1);
2145 if (GET_CODE (arg0
) == REG
)
2150 else if (GET_CODE (arg1
) == REG
)
2156 fatal_insn ("no register in address", addr
);
2158 if (CONSTANT_P (offset
))
2160 fprintf (file
, "%s, ", reg_names
[REGNO (reg
)]);
2161 output_addr_const (file
, offset
);
2164 fatal_insn ("address offset not a constant", addr
);
2172 output_addr_const (file
, addr
);
2179 xtensa_output_literal (file
, x
, mode
, labelno
)
2182 enum machine_mode mode
;
2189 fprintf (file
, "\t.literal .LC%u, ", (unsigned) labelno
);
2191 switch (GET_MODE_CLASS (mode
))
2194 if (GET_CODE (x
) != CONST_DOUBLE
)
2197 REAL_VALUE_FROM_CONST_DOUBLE (r
, x
);
2201 REAL_VALUE_TO_TARGET_SINGLE (r
, value_long
[0]);
2202 fprintf (file
, "0x%08lx\n", value_long
[0]);
2206 REAL_VALUE_TO_TARGET_DOUBLE (r
, value_long
);
2207 fprintf (file
, "0x%08lx, 0x%08lx\n",
2208 value_long
[0], value_long
[1]);
2218 case MODE_PARTIAL_INT
:
2219 size
= GET_MODE_SIZE (mode
);
2222 output_addr_const (file
, x
);
2227 output_addr_const (file
, operand_subword (x
, 0, 0, DImode
));
2229 output_addr_const (file
, operand_subword (x
, 1, 0, DImode
));
2242 /* Return the bytes needed to compute the frame pointer from the current
2245 #define STACK_BYTES (STACK_BOUNDARY / BITS_PER_UNIT)
2246 #define XTENSA_STACK_ALIGN(LOC) (((LOC) + STACK_BYTES-1) & ~(STACK_BYTES-1))
2249 compute_frame_size (size
)
2250 int size
; /* # of var. bytes allocated */
2252 /* add space for the incoming static chain value */
2253 if (current_function_needs_context
)
2254 size
+= (1 * UNITS_PER_WORD
);
2256 xtensa_current_frame_size
=
2257 XTENSA_STACK_ALIGN (size
2258 + current_function_outgoing_args_size
2259 + (WINDOW_SIZE
* UNITS_PER_WORD
));
2260 return xtensa_current_frame_size
;
2265 xtensa_frame_pointer_required ()
2267 /* The code to expand builtin_frame_addr and builtin_return_addr
2268 currently uses the hard_frame_pointer instead of frame_pointer.
2269 This seems wrong but maybe it's necessary for other architectures.
2270 This function is derived from the i386 code. */
2272 if (cfun
->machine
->accesses_prev_frame
)
2280 xtensa_expand_prologue ()
2282 HOST_WIDE_INT total_size
;
2285 total_size
= compute_frame_size (get_frame_size ());
2286 size_rtx
= GEN_INT (total_size
);
2288 if (total_size
< (1 << (12+3)))
2289 emit_insn (gen_entry (size_rtx
, size_rtx
));
2292 /* Use a8 as a temporary since a0-a7 may be live. */
2293 rtx tmp_reg
= gen_rtx_REG (Pmode
, A8_REG
);
2294 emit_insn (gen_entry (size_rtx
, GEN_INT (MIN_FRAME_SIZE
)));
2295 emit_move_insn (tmp_reg
, GEN_INT (total_size
- MIN_FRAME_SIZE
));
2296 emit_insn (gen_subsi3 (tmp_reg
, stack_pointer_rtx
, tmp_reg
));
2297 emit_move_insn (stack_pointer_rtx
, tmp_reg
);
2300 if (frame_pointer_needed
)
2302 rtx first
, insn
, set_frame_ptr_insn
= 0;
2304 push_topmost_sequence ();
2305 first
= get_insns ();
2306 pop_topmost_sequence ();
2308 /* Search all instructions, looking for the insn that sets up the
2309 frame pointer. This search will fail if the function does not
2310 have an incoming argument in $a7, but in that case, we can just
2311 set up the frame pointer at the very beginning of the
2314 for (insn
= first
; insn
; insn
= NEXT_INSN (insn
))
2321 pat
= PATTERN (insn
);
2322 if (GET_CODE (pat
) == SET
2323 && GET_CODE (SET_SRC (pat
)) == UNSPEC_VOLATILE
2324 && (XINT (SET_SRC (pat
), 1) == UNSPECV_SET_FP
))
2326 set_frame_ptr_insn
= insn
;
2331 if (set_frame_ptr_insn
)
2333 /* For all instructions prior to set_frame_ptr_insn, replace
2334 hard_frame_pointer references with stack_pointer. */
2336 insn
!= set_frame_ptr_insn
;
2337 insn
= NEXT_INSN (insn
))
2340 PATTERN (insn
) = replace_rtx (copy_rtx (PATTERN (insn
)),
2341 hard_frame_pointer_rtx
,
2346 emit_move_insn (hard_frame_pointer_rtx
, stack_pointer_rtx
);
2351 /* Clear variables at function end. */
2354 xtensa_function_epilogue (file
, size
)
2355 FILE *file ATTRIBUTE_UNUSED
;
2356 HOST_WIDE_INT size ATTRIBUTE_UNUSED
;
2358 xtensa_current_frame_size
= 0;
2363 xtensa_return_addr (count
, frame
)
2367 rtx result
, retaddr
;
2370 retaddr
= gen_rtx_REG (Pmode
, A0_REG
);
2373 rtx addr
= plus_constant (frame
, -4 * UNITS_PER_WORD
);
2374 addr
= memory_address (Pmode
, addr
);
2375 retaddr
= gen_reg_rtx (Pmode
);
2376 emit_move_insn (retaddr
, gen_rtx_MEM (Pmode
, addr
));
2379 /* The 2 most-significant bits of the return address on Xtensa hold
2380 the register window size. To get the real return address, these
2381 bits must be replaced with the high bits from the current PC. */
2383 result
= gen_reg_rtx (Pmode
);
2384 emit_insn (gen_fix_return_addr (result
, retaddr
));
2389 /* Create the va_list data type.
2390 This structure is set up by __builtin_saveregs. The __va_reg
2391 field points to a stack-allocated region holding the contents of the
2392 incoming argument registers. The __va_ndx field is an index initialized
2393 to the position of the first unnamed (variable) argument. This same index
2394 is also used to address the arguments passed in memory. Thus, the
2395 __va_stk field is initialized to point to the position of the first
2396 argument in memory offset to account for the arguments passed in
2397 registers. E.G., if there are 6 argument registers, and each register is
2398 4 bytes, then __va_stk is set to $sp - (6 * 4); then __va_reg[N*4]
2399 references argument word N for 0 <= N < 6, and __va_stk[N*4] references
2400 argument word N for N >= 6. */
2403 xtensa_build_va_list ()
2405 tree f_stk
, f_reg
, f_ndx
, record
, type_decl
;
2407 record
= (*lang_hooks
.types
.make_type
) (RECORD_TYPE
);
2408 type_decl
= build_decl (TYPE_DECL
, get_identifier ("__va_list_tag"), record
);
2410 f_stk
= build_decl (FIELD_DECL
, get_identifier ("__va_stk"),
2412 f_reg
= build_decl (FIELD_DECL
, get_identifier ("__va_reg"),
2414 f_ndx
= build_decl (FIELD_DECL
, get_identifier ("__va_ndx"),
2417 DECL_FIELD_CONTEXT (f_stk
) = record
;
2418 DECL_FIELD_CONTEXT (f_reg
) = record
;
2419 DECL_FIELD_CONTEXT (f_ndx
) = record
;
2421 TREE_CHAIN (record
) = type_decl
;
2422 TYPE_NAME (record
) = type_decl
;
2423 TYPE_FIELDS (record
) = f_stk
;
2424 TREE_CHAIN (f_stk
) = f_reg
;
2425 TREE_CHAIN (f_reg
) = f_ndx
;
2427 layout_type (record
);
2432 /* Save the incoming argument registers on the stack. Returns the
2433 address of the saved registers. */
2436 xtensa_builtin_saveregs ()
2439 int arg_words
= current_function_arg_words
;
2440 int gp_left
= MAX_ARGS_IN_REGISTERS
- arg_words
;
2446 /* allocate the general-purpose register space */
2447 gp_regs
= assign_stack_local
2448 (BLKmode
, MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1);
2449 set_mem_alias_set (gp_regs
, get_varargs_alias_set ());
2451 /* Now store the incoming registers. */
2452 dest
= change_address (gp_regs
, SImode
,
2453 plus_constant (XEXP (gp_regs
, 0),
2454 arg_words
* UNITS_PER_WORD
));
2456 /* Note: Don't use move_block_from_reg() here because the incoming
2457 argument in a7 cannot be represented by hard_frame_pointer_rtx.
2458 Instead, call gen_raw_REG() directly so that we get a distinct
2459 instance of (REG:SI 7). */
2460 for (i
= 0; i
< gp_left
; i
++)
2462 emit_move_insn (operand_subword (dest
, i
, 1, BLKmode
),
2463 gen_raw_REG (SImode
, GP_ARG_FIRST
+ arg_words
+ i
));
2466 return XEXP (gp_regs
, 0);
2470 /* Implement `va_start' for varargs and stdarg. We look at the
2471 current function to fill in an initial va_list. */
2474 xtensa_va_start (valist
, nextarg
)
2476 rtx nextarg ATTRIBUTE_UNUSED
;
2484 arg_words
= current_function_args_info
.arg_words
;
2486 f_stk
= TYPE_FIELDS (va_list_type_node
);
2487 f_reg
= TREE_CHAIN (f_stk
);
2488 f_ndx
= TREE_CHAIN (f_reg
);
2490 stk
= build (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
);
2491 reg
= build (COMPONENT_REF
, TREE_TYPE (f_reg
), valist
, f_reg
);
2492 ndx
= build (COMPONENT_REF
, TREE_TYPE (f_ndx
), valist
, f_ndx
);
2494 /* Call __builtin_saveregs; save the result in __va_reg */
2495 current_function_arg_words
= arg_words
;
2496 u
= make_tree (ptr_type_node
, expand_builtin_saveregs ());
2497 t
= build (MODIFY_EXPR
, ptr_type_node
, reg
, u
);
2498 TREE_SIDE_EFFECTS (t
) = 1;
2499 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2501 /* Set the __va_stk member to $arg_ptr - (size of __va_reg area) */
2502 u
= make_tree (ptr_type_node
, virtual_incoming_args_rtx
);
2503 u
= fold (build (PLUS_EXPR
, ptr_type_node
, u
,
2504 build_int_2 (-MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, -1)));
2505 t
= build (MODIFY_EXPR
, ptr_type_node
, stk
, u
);
2506 TREE_SIDE_EFFECTS (t
) = 1;
2507 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2509 /* Set the __va_ndx member. */
2510 u
= build_int_2 (arg_words
* UNITS_PER_WORD
, 0);
2511 t
= build (MODIFY_EXPR
, integer_type_node
, ndx
, u
);
2512 TREE_SIDE_EFFECTS (t
) = 1;
2513 expand_expr (t
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2517 /* Implement `va_arg'. */
2520 xtensa_va_arg (valist
, type
)
2526 tree tmp
, addr_tree
, type_size
;
2527 rtx array
, orig_ndx
, r
, addr
, size
, va_size
;
2528 rtx lab_false
, lab_over
, lab_false2
;
2530 f_stk
= TYPE_FIELDS (va_list_type_node
);
2531 f_reg
= TREE_CHAIN (f_stk
);
2532 f_ndx
= TREE_CHAIN (f_reg
);
2534 stk
= build (COMPONENT_REF
, TREE_TYPE (f_stk
), valist
, f_stk
);
2535 reg
= build (COMPONENT_REF
, TREE_TYPE (f_reg
), valist
, f_reg
);
2536 ndx
= build (COMPONENT_REF
, TREE_TYPE (f_ndx
), valist
, f_ndx
);
2538 type_size
= TYPE_SIZE_UNIT (TYPE_MAIN_VARIANT (type
));
2540 va_size
= gen_reg_rtx (SImode
);
2541 tmp
= fold (build (MULT_EXPR
, sizetype
,
2542 fold (build (TRUNC_DIV_EXPR
, sizetype
,
2543 fold (build (PLUS_EXPR
, sizetype
,
2545 size_int (UNITS_PER_WORD
- 1))),
2546 size_int (UNITS_PER_WORD
))),
2547 size_int (UNITS_PER_WORD
)));
2548 r
= expand_expr (tmp
, va_size
, SImode
, EXPAND_NORMAL
);
2550 emit_move_insn (va_size
, r
);
2553 /* First align __va_ndx to a double word boundary if necessary for this arg:
2555 if (__alignof__ (TYPE) > 4)
2556 (AP).__va_ndx = (((AP).__va_ndx + 7) & -8)
2559 if (TYPE_ALIGN (type
) > BITS_PER_WORD
)
2561 tmp
= build (PLUS_EXPR
, integer_type_node
, ndx
,
2562 build_int_2 ((2 * UNITS_PER_WORD
) - 1, 0));
2563 tmp
= build (BIT_AND_EXPR
, integer_type_node
, tmp
,
2564 build_int_2 (-2 * UNITS_PER_WORD
, -1));
2565 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2566 TREE_SIDE_EFFECTS (tmp
) = 1;
2567 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2571 /* Increment __va_ndx to point past the argument:
2573 orig_ndx = (AP).__va_ndx;
2574 (AP).__va_ndx += __va_size (TYPE);
2577 orig_ndx
= gen_reg_rtx (SImode
);
2578 r
= expand_expr (ndx
, orig_ndx
, SImode
, EXPAND_NORMAL
);
2580 emit_move_insn (orig_ndx
, r
);
2582 tmp
= build (PLUS_EXPR
, integer_type_node
, ndx
,
2583 make_tree (intSI_type_node
, va_size
));
2584 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2585 TREE_SIDE_EFFECTS (tmp
) = 1;
2586 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2589 /* Check if the argument is in registers:
2591 if ((AP).__va_ndx <= __MAX_ARGS_IN_REGISTERS * 4
2592 && !MUST_PASS_IN_STACK (type))
2593 __array = (AP).__va_reg;
2596 array
= gen_reg_rtx (Pmode
);
2598 lab_over
= NULL_RTX
;
2599 if (!MUST_PASS_IN_STACK (VOIDmode
, type
))
2601 lab_false
= gen_label_rtx ();
2602 lab_over
= gen_label_rtx ();
2604 emit_cmp_and_jump_insns (expand_expr (ndx
, NULL_RTX
, SImode
,
2606 GEN_INT (MAX_ARGS_IN_REGISTERS
2608 GT
, const1_rtx
, SImode
, 0, lab_false
);
2610 r
= expand_expr (reg
, array
, Pmode
, EXPAND_NORMAL
);
2612 emit_move_insn (array
, r
);
2614 emit_jump_insn (gen_jump (lab_over
));
2616 emit_label (lab_false
);
2619 /* ...otherwise, the argument is on the stack (never split between
2620 registers and the stack -- change __va_ndx if necessary):
2624 if (orig_ndx < __MAX_ARGS_IN_REGISTERS * 4)
2625 (AP).__va_ndx = __MAX_ARGS_IN_REGISTERS * 4 + __va_size (TYPE);
2626 __array = (AP).__va_stk;
2630 lab_false2
= gen_label_rtx ();
2631 emit_cmp_and_jump_insns (orig_ndx
,
2632 GEN_INT (MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
),
2633 GE
, const1_rtx
, SImode
, 0, lab_false2
);
2635 tmp
= build (PLUS_EXPR
, sizetype
, make_tree (intSI_type_node
, va_size
),
2636 build_int_2 (MAX_ARGS_IN_REGISTERS
* UNITS_PER_WORD
, 0));
2637 tmp
= build (MODIFY_EXPR
, integer_type_node
, ndx
, tmp
);
2638 TREE_SIDE_EFFECTS (tmp
) = 1;
2639 expand_expr (tmp
, const0_rtx
, VOIDmode
, EXPAND_NORMAL
);
2641 emit_label (lab_false2
);
2643 r
= expand_expr (stk
, array
, Pmode
, EXPAND_NORMAL
);
2645 emit_move_insn (array
, r
);
2647 if (lab_over
!= NULL_RTX
)
2648 emit_label (lab_over
);
2651 /* Given the base array pointer (__array) and index to the subsequent
2652 argument (__va_ndx), find the address:
2654 __array + (AP).__va_ndx - (BYTES_BIG_ENDIAN && sizeof (TYPE) < 4
2658 The results are endian-dependent because values smaller than one word
2659 are aligned differently.
2662 size
= gen_reg_rtx (SImode
);
2663 emit_move_insn (size
, va_size
);
2665 if (BYTES_BIG_ENDIAN
)
2667 rtx lab_use_va_size
= gen_label_rtx ();
2669 emit_cmp_and_jump_insns (expand_expr (type_size
, NULL_RTX
, SImode
,
2671 GEN_INT (PARM_BOUNDARY
/ BITS_PER_UNIT
),
2672 GE
, const1_rtx
, SImode
, 0, lab_use_va_size
);
2674 r
= expand_expr (type_size
, size
, SImode
, EXPAND_NORMAL
);
2676 emit_move_insn (size
, r
);
2678 emit_label (lab_use_va_size
);
2681 addr_tree
= build (PLUS_EXPR
, ptr_type_node
,
2682 make_tree (ptr_type_node
, array
),
2684 addr_tree
= build (MINUS_EXPR
, ptr_type_node
, addr_tree
,
2685 make_tree (intSI_type_node
, size
));
2686 addr
= expand_expr (addr_tree
, NULL_RTX
, Pmode
, EXPAND_NORMAL
);
2687 addr
= copy_to_reg (addr
);
2693 xtensa_preferred_reload_class (x
, class, isoutput
)
2695 enum reg_class
class;
2698 if (!isoutput
&& CONSTANT_P (x
) && GET_CODE (x
) == CONST_DOUBLE
)
2701 /* Don't use the stack pointer or hard frame pointer for reloads!
2702 The hard frame pointer would normally be OK except that it may
2703 briefly hold an incoming argument in the prologue, and reload
2704 won't know that it is live because the hard frame pointer is
2705 treated specially. */
2707 if (class == AR_REGS
|| class == GR_REGS
)
2715 xtensa_secondary_reload_class (class, mode
, x
, isoutput
)
2716 enum reg_class
class;
2717 enum machine_mode mode ATTRIBUTE_UNUSED
;
2723 if (GET_CODE (x
) == SIGN_EXTEND
)
2725 regno
= xt_true_regnum (x
);
2729 if (class == FP_REGS
&& constantpool_mem_p (x
))
2733 if (ACC_REG_P (regno
))
2734 return ((class == GR_REGS
|| class == RL_REGS
) ? NO_REGS
: RL_REGS
);
2735 if (class == ACC_REG
)
2736 return (GP_REG_P (regno
) ? NO_REGS
: RL_REGS
);
2743 order_regs_for_local_alloc ()
2745 if (!leaf_function_p ())
2747 memcpy (reg_alloc_order
, reg_nonleaf_alloc_order
,
2748 FIRST_PSEUDO_REGISTER
* sizeof (int));
2752 int i
, num_arg_regs
;
2755 /* use the AR registers in increasing order (skipping a0 and a1)
2756 but save the incoming argument registers for a last resort */
2757 num_arg_regs
= current_function_args_info
.arg_words
;
2758 if (num_arg_regs
> MAX_ARGS_IN_REGISTERS
)
2759 num_arg_regs
= MAX_ARGS_IN_REGISTERS
;
2760 for (i
= GP_ARG_FIRST
; i
< 16 - num_arg_regs
; i
++)
2761 reg_alloc_order
[nxt
++] = i
+ num_arg_regs
;
2762 for (i
= 0; i
< num_arg_regs
; i
++)
2763 reg_alloc_order
[nxt
++] = GP_ARG_FIRST
+ i
;
2765 /* list the coprocessor registers in order */
2766 for (i
= 0; i
< BR_REG_NUM
; i
++)
2767 reg_alloc_order
[nxt
++] = BR_REG_FIRST
+ i
;
2769 /* list the FP registers in order for now */
2770 for (i
= 0; i
< 16; i
++)
2771 reg_alloc_order
[nxt
++] = FP_REG_FIRST
+ i
;
2773 /* GCC requires that we list *all* the registers.... */
2774 reg_alloc_order
[nxt
++] = 0; /* a0 = return address */
2775 reg_alloc_order
[nxt
++] = 1; /* a1 = stack pointer */
2776 reg_alloc_order
[nxt
++] = 16; /* pseudo frame pointer */
2777 reg_alloc_order
[nxt
++] = 17; /* pseudo arg pointer */
2779 reg_alloc_order
[nxt
++] = ACC_REG_FIRST
; /* MAC16 accumulator */
2784 /* A customized version of reg_overlap_mentioned_p that only looks for
2785 references to a7 (as opposed to hard_frame_pointer_rtx). */
2788 a7_overlap_mentioned_p (x
)
2792 unsigned int x_regno
;
2795 if (GET_CODE (x
) == REG
)
2797 x_regno
= REGNO (x
);
2798 return (x
!= hard_frame_pointer_rtx
2799 && x_regno
< A7_REG
+ 1
2800 && x_regno
+ HARD_REGNO_NREGS (A7_REG
, GET_MODE (x
)) > A7_REG
);
2803 if (GET_CODE (x
) == SUBREG
2804 && GET_CODE (SUBREG_REG (x
)) == REG
2805 && REGNO (SUBREG_REG (x
)) < FIRST_PSEUDO_REGISTER
)
2807 x_regno
= subreg_regno (x
);
2808 return (SUBREG_REG (x
) != hard_frame_pointer_rtx
2809 && x_regno
< A7_REG
+ 1
2810 && x_regno
+ HARD_REGNO_NREGS (A7_REG
, GET_MODE (x
)) > A7_REG
);
2813 /* X does not match, so try its subexpressions. */
2814 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
2815 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
2819 if (a7_overlap_mentioned_p (XEXP (x
, i
)))
2822 else if (fmt
[i
] == 'E')
2824 for (j
= XVECLEN (x
, i
) - 1; j
>=0; j
--)
2825 if (a7_overlap_mentioned_p (XVECEXP (x
, i
, j
)))
2834 /* Some Xtensa targets support multiple bss sections. If the section
2835 name ends with ".bss", add SECTION_BSS to the flags. */
2838 xtensa_multibss_section_type_flags (decl
, name
, reloc
)
2843 unsigned int flags
= default_section_type_flags (decl
, name
, reloc
);
2846 suffix
= strrchr (name
, '.');
2847 if (suffix
&& strcmp (suffix
, ".bss") == 0)
2849 if (!decl
|| (TREE_CODE (decl
) == VAR_DECL
2850 && DECL_INITIAL (decl
) == NULL_TREE
))
2851 flags
|= SECTION_BSS
; /* @nobits */
2853 warning ("only uninitialized variables can be placed in a "
2861 /* The literal pool stays with the function. */
2864 xtensa_select_rtx_section (mode
, x
, align
)
2865 enum machine_mode mode ATTRIBUTE_UNUSED
;
2866 rtx x ATTRIBUTE_UNUSED
;
2867 unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED
;
2869 function_section (current_function_decl
);
2872 /* Compute a (partial) cost for rtx X. Return true if the complete
2873 cost has been computed, and false if subexpressions should be
2874 scanned. In either case, *TOTAL contains the cost result. */
2877 xtensa_rtx_costs (x
, code
, outer_code
, total
)
2879 int code
, outer_code
;
2888 if (xtensa_simm12b (INTVAL (x
)))
2895 if (xtensa_simm8 (INTVAL (x
))
2896 || xtensa_simm8x256 (INTVAL (x
)))
2903 if (xtensa_mask_immediate (INTVAL (x
)))
2910 if ((INTVAL (x
) == 0) || xtensa_b4const (INTVAL (x
)))
2921 /* no way to tell if X is the 2nd operand so be conservative */
2924 if (xtensa_simm12b (INTVAL (x
)))
2926 else if (TARGET_CONST16
)
2927 *total
= COSTS_N_INSNS (2);
2936 *total
= COSTS_N_INSNS (2);
2943 *total
= COSTS_N_INSNS (4);
2951 (GET_MODE_SIZE (GET_MODE (x
)) > UNITS_PER_WORD
) ? 2 : 1;
2953 if (memory_address_p (GET_MODE (x
), XEXP ((x
), 0)))
2954 *total
= COSTS_N_INSNS (num_words
);
2956 *total
= COSTS_N_INSNS (2*num_words
);
2961 *total
= COSTS_N_INSNS (TARGET_NSA
? 5 : 50);
2965 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 3 : 2);
2971 if (GET_MODE (x
) == DImode
)
2972 *total
= COSTS_N_INSNS (2);
2974 *total
= COSTS_N_INSNS (1);
2980 if (GET_MODE (x
) == DImode
)
2981 *total
= COSTS_N_INSNS (50);
2983 *total
= COSTS_N_INSNS (1);
2988 enum machine_mode xmode
= GET_MODE (x
);
2989 if (xmode
== SFmode
)
2990 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
2991 else if (xmode
== DFmode
)
2992 *total
= COSTS_N_INSNS (50);
2994 *total
= COSTS_N_INSNS (4);
3001 enum machine_mode xmode
= GET_MODE (x
);
3002 if (xmode
== SFmode
)
3003 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 1 : 50);
3004 else if (xmode
== DFmode
|| xmode
== DImode
)
3005 *total
= COSTS_N_INSNS (50);
3007 *total
= COSTS_N_INSNS (1);
3012 *total
= COSTS_N_INSNS ((GET_MODE (x
) == DImode
) ? 4 : 2);
3017 enum machine_mode xmode
= GET_MODE (x
);
3018 if (xmode
== SFmode
)
3019 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT
? 4 : 50);
3020 else if (xmode
== DFmode
|| xmode
== DImode
)
3021 *total
= COSTS_N_INSNS (50);
3022 else if (TARGET_MUL32
)
3023 *total
= COSTS_N_INSNS (4);
3024 else if (TARGET_MAC16
)
3025 *total
= COSTS_N_INSNS (16);
3026 else if (TARGET_MUL16
)
3027 *total
= COSTS_N_INSNS (12);
3029 *total
= COSTS_N_INSNS (50);
3036 enum machine_mode xmode
= GET_MODE (x
);
3037 if (xmode
== SFmode
)
3039 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_DIV
? 8 : 50);
3042 else if (xmode
== DFmode
)
3044 *total
= COSTS_N_INSNS (50);
3053 enum machine_mode xmode
= GET_MODE (x
);
3054 if (xmode
== DImode
)
3055 *total
= COSTS_N_INSNS (50);
3056 else if (TARGET_DIV32
)
3057 *total
= COSTS_N_INSNS (32);
3059 *total
= COSTS_N_INSNS (50);
3064 if (GET_MODE (x
) == SFmode
)
3065 *total
= COSTS_N_INSNS (TARGET_HARD_FLOAT_SQRT
? 8 : 50);
3067 *total
= COSTS_N_INSNS (50);
3074 *total
= COSTS_N_INSNS (TARGET_MINMAX
? 1 : 50);
3079 *total
= COSTS_N_INSNS (TARGET_SEXT
? 1 : 2);
3084 *total
= COSTS_N_INSNS (1);
3092 #include "gt-xtensa.h"